aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-06-25 09:27:27 -0400
committerAnton Altaparmakov <aia21@cantab.net>2005-06-25 09:27:27 -0400
commit38b22b6e9f46ab8f73ef5734f0e0a000766a9258 (patch)
tree2ccc41ef55918d3af43e444bde7648562a031559
parent3357d4c75f1fb67e7304998c4ad4e9a9fed66fa4 (diff)
parentb3e112bcc19abd8e9657dca34a87316786e096f3 (diff)
Automerge with /usr/src/ntfs-2.6.git.
-rw-r--r--Documentation/Changes2
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/kernel-api.tmpl2
-rw-r--r--Documentation/DocBook/stylesheet.xsl1
-rw-r--r--Documentation/IPMI.txt146
-rw-r--r--Documentation/basic_profiling.txt10
-rw-r--r--Documentation/dontdiff1
-rw-r--r--Documentation/dvb/README.dvb-usb (renamed from Documentation/dvb/README.dibusb)195
-rw-r--r--Documentation/feature-removal-schedule.txt18
-rw-r--r--Documentation/filesystems/ext2.txt2
-rw-r--r--Documentation/filesystems/xip.txt67
-rw-r--r--Documentation/keys.txt319
-rw-r--r--Documentation/networking/ip-sysctl.txt56
-rw-r--r--Documentation/networking/tcp.txt69
-rw-r--r--Documentation/sysctl/kernel.txt20
-rw-r--r--Documentation/tty.txt2
-rw-r--r--Documentation/video4linux/CARDLIST.bttv14
-rw-r--r--Documentation/video4linux/CARDLIST.cx8829
-rw-r--r--Documentation/video4linux/CARDLIST.saa713429
-rw-r--r--Documentation/video4linux/CARDLIST.tuner15
-rw-r--r--Documentation/video4linux/hauppauge-wintv-cx88-ir.txt54
-rw-r--r--Documentation/video4linux/lifeview.txt42
-rw-r--r--Documentation/video4linux/not-in-cx2388x-datasheet.txt37
-rw-r--r--MAINTAINERS24
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/Kconfig4
-rw-r--r--arch/alpha/defconfig2
-rw-r--r--arch/alpha/mm/numa.c16
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/boot/install.sh4
-rw-r--r--arch/arm/configs/s3c2410_defconfig27
-rw-r--r--arch/arm/mach-ixp2000/core.c85
-rw-r--r--arch/arm/mach-ixp4xx/common.c8
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c49
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c77
-rw-r--r--arch/arm/mm/proc-v6.S6
-rw-r--r--arch/arm/nwfpe/softfloat-macros22
-rw-r--r--arch/arm/nwfpe/softfloat.c12
-rw-r--r--arch/arm26/Kconfig2
-rw-r--r--arch/arm26/boot/install.sh4
-rw-r--r--arch/cris/Kconfig2
-rw-r--r--arch/frv/Kconfig2
-rw-r--r--arch/h8300/Kconfig.cpu3
-rw-r--r--arch/h8300/platform/h8300h/ptrace_h8300h.c4
-rw-r--r--arch/i386/Kconfig40
-rw-r--r--arch/i386/Makefile7
-rw-r--r--arch/i386/boot/install.sh4
-rw-r--r--arch/i386/kernel/apic.c2
-rw-r--r--arch/i386/kernel/cpu/common.c2
-rw-r--r--arch/i386/kernel/cpu/mtrr/main.c23
-rw-r--r--arch/i386/kernel/cpu/proc.c2
-rw-r--r--arch/i386/kernel/i386_ksyms.c160
-rw-r--r--arch/i386/kernel/i387.c3
-rw-r--r--arch/i386/kernel/io_apic.c13
-rw-r--r--arch/i386/kernel/kprobes.c176
-rw-r--r--arch/i386/kernel/mpparse.c31
-rw-r--r--arch/i386/kernel/nmi.c24
-rw-r--r--arch/i386/kernel/pci-dma.c3
-rw-r--r--arch/i386/kernel/process.c36
-rw-r--r--arch/i386/kernel/ptrace.c2
-rw-r--r--arch/i386/kernel/reboot.c5
-rw-r--r--arch/i386/kernel/setup.c28
-rw-r--r--arch/i386/kernel/signal.c31
-rw-r--r--arch/i386/kernel/smp.c3
-rw-r--r--arch/i386/kernel/smpboot.c14
-rw-r--r--arch/i386/kernel/time.c6
-rw-r--r--arch/i386/kernel/timers/common.c12
-rw-r--r--arch/i386/kernel/timers/timer.c9
-rw-r--r--arch/i386/kernel/timers/timer_hpet.c3
-rw-r--r--arch/i386/kernel/timers/timer_pm.c1
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c8
-rw-r--r--arch/i386/kernel/traps.c21
-rw-r--r--arch/i386/lib/dec_and_lock.c2
-rw-r--r--arch/i386/lib/delay.c6
-rw-r--r--arch/i386/lib/mmx.c5
-rw-r--r--arch/i386/lib/usercopy.c8
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c2
-rw-r--r--arch/i386/mm/Makefile2
-rw-r--r--arch/i386/mm/discontig.c127
-rw-r--r--arch/i386/mm/highmem.c6
-rw-r--r--arch/i386/mm/init.c21
-rw-r--r--arch/i386/mm/ioremap.c5
-rw-r--r--arch/i386/mm/pgtable.c10
-rw-r--r--arch/i386/oprofile/backtrace.c2
-rw-r--r--arch/i386/pci/irq.c22
-rw-r--r--arch/i386/pci/pcbios.c4
-rw-r--r--arch/i386/power/cpu.c14
-rw-r--r--arch/ia64/Kconfig6
-rw-r--r--arch/ia64/Kconfig.debug11
-rw-r--r--arch/ia64/configs/sn2_defconfig2
-rw-r--r--arch/ia64/defconfig2
-rw-r--r--arch/ia64/ia32/ia32priv.h2
-rw-r--r--arch/ia64/kernel/Makefile1
-rw-r--r--arch/ia64/kernel/jprobes.S61
-rw-r--r--arch/ia64/kernel/kprobes.c601
-rw-r--r--arch/ia64/kernel/traps.c33
-rw-r--r--arch/ia64/mm/discontig.c9
-rw-r--r--arch/ia64/mm/fault.c8
-rw-r--r--arch/m32r/Kconfig4
-rw-r--r--arch/m32r/mm/init.c4
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/m68knommu/Kconfig2
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/configs/ip27_defconfig2
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c5
-rw-r--r--arch/parisc/Kconfig4
-rw-r--r--arch/parisc/mm/init.c2
-rw-r--r--arch/ppc/Kconfig2
-rw-r--r--arch/ppc/boot/simple/misc.c2
-rw-r--r--arch/ppc/boot/simple/mpc10x_memory.c2
-rw-r--r--arch/ppc64/Kconfig63
-rw-r--r--arch/ppc64/Makefile2
-rw-r--r--arch/ppc64/boot/install.sh4
-rw-r--r--arch/ppc64/configs/pSeries_defconfig2
-rw-r--r--arch/ppc64/defconfig2
-rw-r--r--arch/ppc64/kernel/Makefile11
-rw-r--r--arch/ppc64/kernel/bpa_iic.c270
-rw-r--r--arch/ppc64/kernel/bpa_iic.h62
-rw-r--r--arch/ppc64/kernel/bpa_iommu.c377
-rw-r--r--arch/ppc64/kernel/bpa_iommu.h65
-rw-r--r--arch/ppc64/kernel/bpa_nvram.c118
-rw-r--r--arch/ppc64/kernel/bpa_setup.c140
-rw-r--r--arch/ppc64/kernel/cpu_setup_power4.S16
-rw-r--r--arch/ppc64/kernel/cputable.c11
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c5
-rw-r--r--arch/ppc64/kernel/irq.c3
-rw-r--r--arch/ppc64/kernel/kprobes.c61
-rw-r--r--arch/ppc64/kernel/maple_setup.c64
-rw-r--r--arch/ppc64/kernel/maple_time.c51
-rw-r--r--arch/ppc64/kernel/mpic.h3
-rw-r--r--arch/ppc64/kernel/pSeries_pci.c497
-rw-r--r--arch/ppc64/kernel/pSeries_setup.c184
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c69
-rw-r--r--arch/ppc64/kernel/pci.c3
-rw-r--r--arch/ppc64/kernel/pci.h6
-rw-r--r--arch/ppc64/kernel/pmac_time.c8
-rw-r--r--arch/ppc64/kernel/proc_ppc64.c2
-rw-r--r--arch/ppc64/kernel/prom_init.c4
-rw-r--r--arch/ppc64/kernel/ptrace.c4
-rw-r--r--arch/ppc64/kernel/rtas-proc.c4
-rw-r--r--arch/ppc64/kernel/rtas.c121
-rw-r--r--arch/ppc64/kernel/rtas_pci.c495
-rw-r--r--arch/ppc64/kernel/rtc.c6
-rw-r--r--arch/ppc64/kernel/setup.c34
-rw-r--r--arch/ppc64/kernel/smp.c4
-rw-r--r--arch/ppc64/kernel/spider-pic.c191
-rw-r--r--arch/ppc64/kernel/time.c63
-rw-r--r--arch/ppc64/kernel/traps.c4
-rw-r--r--arch/ppc64/mm/Makefile2
-rw-r--r--arch/ppc64/mm/init.c22
-rw-r--r--arch/ppc64/mm/numa.c3
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/s390/boot/install.sh4
-rw-r--r--arch/s390/kernel/compat_linux.h2
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sh64/Kconfig2
-rw-r--r--arch/sparc/Kconfig18
-rw-r--r--arch/sparc64/Kconfig2
-rw-r--r--arch/sparc64/kernel/kprobes.c83
-rw-r--r--arch/sparc64/kernel/signal32.c2
-rw-r--r--arch/um/Kconfig1
-rw-r--r--arch/um/kernel/process_kern.c8
-rw-r--r--arch/v850/Kconfig2
-rw-r--r--arch/x86_64/Kconfig25
-rw-r--r--arch/x86_64/boot/install.sh4
-rw-r--r--arch/x86_64/ia32/ia32_signal.c15
-rw-r--r--arch/x86_64/kernel/aperture.c4
-rw-r--r--arch/x86_64/kernel/early_printk.c13
-rw-r--r--arch/x86_64/kernel/head64.c2
-rw-r--r--arch/x86_64/kernel/i8259.c15
-rw-r--r--arch/x86_64/kernel/kprobes.c190
-rw-r--r--arch/x86_64/kernel/mpparse.c25
-rw-r--r--arch/x86_64/kernel/process.c16
-rw-r--r--arch/x86_64/kernel/setup.c33
-rw-r--r--arch/x86_64/kernel/signal.c30
-rw-r--r--arch/x86_64/kernel/time.c42
-rw-r--r--arch/x86_64/kernel/traps.c22
-rw-r--r--arch/x86_64/lib/delay.c7
-rw-r--r--arch/x86_64/mm/Makefile2
-rw-r--r--arch/x86_64/mm/fault.c4
-rw-r--r--arch/x86_64/mm/init.c9
-rw-r--r--arch/x86_64/mm/ioremap.c2
-rw-r--r--arch/x86_64/mm/numa.c8
-rw-r--r--arch/x86_64/pci/k8-bus.c16
-rw-r--r--arch/xtensa/Kconfig258
-rw-r--r--arch/xtensa/Kconfig.debug7
-rw-r--r--arch/xtensa/Makefile102
-rw-r--r--arch/xtensa/boot/Makefile37
-rw-r--r--arch/xtensa/boot/boot-elf/Makefile52
-rw-r--r--arch/xtensa/boot/boot-elf/boot.ld71
-rw-r--r--arch/xtensa/boot/boot-elf/bootstrap.S37
-rw-r--r--arch/xtensa/boot/boot-redboot/Makefile35
-rw-r--r--arch/xtensa/boot/boot-redboot/boot.ld66
-rw-r--r--arch/xtensa/boot/boot-redboot/bootstrap.S246
-rw-r--r--arch/xtensa/boot/include/zlib.h433
-rw-r--r--arch/xtensa/boot/lib/Makefile6
-rw-r--r--arch/xtensa/boot/lib/memcpy.S36
-rw-r--r--arch/xtensa/boot/lib/zlib.c2150
-rw-r--r--arch/xtensa/boot/lib/zmem.c87
-rw-r--r--arch/xtensa/boot/ramdisk/Makefile23
-rw-r--r--arch/xtensa/configs/common_defconfig662
-rw-r--r--arch/xtensa/configs/iss_defconfig531
-rw-r--r--arch/xtensa/kernel/Makefile18
-rw-r--r--arch/xtensa/kernel/align.S459
-rw-r--r--arch/xtensa/kernel/asm-offsets.c94
-rw-r--r--arch/xtensa/kernel/coprocessor.S201
-rw-r--r--arch/xtensa/kernel/entry.S1996
-rw-r--r--arch/xtensa/kernel/head.S237
-rw-r--r--arch/xtensa/kernel/irq.c192
-rw-r--r--arch/xtensa/kernel/module.c78
-rw-r--r--arch/xtensa/kernel/pci-dma.c73
-rw-r--r--arch/xtensa/kernel/pci.c563
-rw-r--r--arch/xtensa/kernel/platform.c49
-rw-r--r--arch/xtensa/kernel/process.c482
-rw-r--r--arch/xtensa/kernel/ptrace.c407
-rw-r--r--arch/xtensa/kernel/semaphore.c226
-rw-r--r--arch/xtensa/kernel/setup.c520
-rw-r--r--arch/xtensa/kernel/signal.c713
-rw-r--r--arch/xtensa/kernel/syscalls.c418
-rw-r--r--arch/xtensa/kernel/syscalls.h248
-rw-r--r--arch/xtensa/kernel/time.c227
-rw-r--r--arch/xtensa/kernel/traps.c498
-rw-r--r--arch/xtensa/kernel/vectors.S464
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S341
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c123
-rw-r--r--arch/xtensa/lib/Makefile7
-rw-r--r--arch/xtensa/lib/checksum.S410
-rw-r--r--arch/xtensa/lib/memcopy.S315
-rw-r--r--arch/xtensa/lib/memset.S160
-rw-r--r--arch/xtensa/lib/pci-auto.c352
-rw-r--r--arch/xtensa/lib/strcasecmp.c32
-rw-r--r--arch/xtensa/lib/strncpy_user.S224
-rw-r--r--arch/xtensa/lib/strnlen_user.S147
-rw-r--r--arch/xtensa/lib/usercopy.S321
-rw-r--r--arch/xtensa/mm/Makefile13
-rw-r--r--arch/xtensa/mm/fault.c241
-rw-r--r--arch/xtensa/mm/init.c551
-rw-r--r--arch/xtensa/mm/misc.S374
-rw-r--r--arch/xtensa/mm/pgtable.c76
-rw-r--r--arch/xtensa/mm/tlb.c545
-rw-r--r--arch/xtensa/platform-iss/Makefile13
-rw-r--r--arch/xtensa/platform-iss/console.c303
-rw-r--r--arch/xtensa/platform-iss/io.c32
-rw-r--r--arch/xtensa/platform-iss/network.c855
-rw-r--r--arch/xtensa/platform-iss/setup.c112
-rw-r--r--drivers/block/as-iosched.c8
-rw-r--r--drivers/block/deadline-iosched.c8
-rw-r--r--drivers/block/genhd.c25
-rw-r--r--drivers/block/ioctl.c74
-rw-r--r--drivers/block/ll_rw_blk.c111
-rw-r--r--drivers/block/loop.c81
-rw-r--r--drivers/block/pktcdvd.c36
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/char/amiserial.c18
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c196
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c46
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c137
-rw-r--r--drivers/char/n_hdlc.c2
-rw-r--r--drivers/char/n_r3964.c2
-rw-r--r--drivers/char/tpm/tpm.c350
-rw-r--r--drivers/char/tpm/tpm.h26
-rw-r--r--drivers/char/tpm/tpm_atmel.c51
-rw-r--r--drivers/char/tpm/tpm_nsc.c120
-rw-r--r--drivers/char/tty_io.c37
-rw-r--r--drivers/char/watchdog/Kconfig10
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/wdrtas.c696
-rw-r--r--drivers/firmware/pcdp.c11
-rw-r--r--drivers/firmware/pcdp.h2
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c3
-rw-r--r--drivers/ide/ide-cd.c89
-rw-r--r--drivers/ide/ide-disk.c3
-rw-r--r--drivers/ide/ide-floppy.c6
-rw-r--r--drivers/ide/ide-probe.c8
-rw-r--r--drivers/input/serio/serport.c2
-rw-r--r--drivers/md/dm-ioctl.c14
-rw-r--r--drivers/media/common/ir-common.c72
-rw-r--r--drivers/media/common/saa7146_fops.c2
-rw-r--r--drivers/media/dvb/Kconfig2
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/Kconfig1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c26
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c11
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h3
-rw-r--r--drivers/media/dvb/dibusb/Kconfig62
-rw-r--r--drivers/media/dvb/dibusb/Makefile11
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-core.c558
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-dvb.c185
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c582
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-firmware.c87
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-remote.c316
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-usb.c303
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb.h327
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c4
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig99
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile30
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c176
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c272
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c316
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c116
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h122
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c282
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.h65
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c (renamed from drivers/media/dvb/dibusb/dvb-fe-dtt200u.c)113
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c171
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.h66
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-common.h44
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c210
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-firmware.c100
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c118
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h83
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c211
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c175
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c211
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h315
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c236
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c162
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045-fe.c196
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c263
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.h78
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c853
-rw-r--r--drivers/media/dvb/frontends/bcm3510.h40
-rw-r--r--drivers/media/dvb/frontends/bcm3510_priv.h460
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.c2
-rw-r--r--drivers/media/dvb/frontends/dib3000.h5
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c20
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c29
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c94
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h9
-rw-r--r--drivers/media/video/Kconfig14
-rw-r--r--drivers/media/video/bt832.c46
-rw-r--r--drivers/media/video/bt832.h36
-rw-r--r--drivers/media/video/bttv-cards.c100
-rw-r--r--drivers/media/video/bttv-driver.c2
-rw-r--r--drivers/media/video/bttv-i2c.c2
-rw-r--r--drivers/media/video/bttv.h3
-rw-r--r--drivers/media/video/bttvp.h8
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c488
-rw-r--r--drivers/media/video/cx88/cx88-cards.c230
-rw-r--r--drivers/media/video/cx88/cx88-core.c28
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c18
-rw-r--r--drivers/media/video/cx88/cx88-input.c11
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c52
-rw-r--r--drivers/media/video/cx88/cx88-reg.h3
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c103
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c6
-rw-r--r--drivers/media/video/cx88/cx88-video.c59
-rw-r--r--drivers/media/video/cx88/cx88.h23
-rw-r--r--drivers/media/video/ir-kbd-gpio.c34
-rw-r--r--drivers/media/video/msp3400.c12
-rw-r--r--drivers/media/video/msp3400.h4
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c20
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c163
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c112
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c16
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c21
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c14
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c92
-rw-r--r--drivers/media/video/saa7134/saa7134.h17
-rw-r--r--drivers/media/video/tda9887.c40
-rw-r--r--drivers/media/video/tuner-core.c194
-rw-r--r--drivers/media/video/tuner-simple.c53
-rw-r--r--drivers/media/video/tvaudio.c23
-rw-r--r--drivers/media/video/tveeprom.c2
-rw-r--r--drivers/media/video/tvmixer.c4
-rw-r--r--drivers/media/video/v4l1-compat.c10
-rw-r--r--drivers/message/i2o/Kconfig46
-rw-r--r--drivers/message/i2o/Makefile3
-rw-r--r--drivers/message/i2o/bus-osm.c164
-rw-r--r--drivers/message/i2o/config-osm.c579
-rw-r--r--drivers/message/i2o/core.h58
-rw-r--r--drivers/message/i2o/debug.c3
-rw-r--r--drivers/message/i2o/device.c40
-rw-r--r--drivers/message/i2o/driver.c130
-rw-r--r--drivers/message/i2o/exec-osm.c131
-rw-r--r--drivers/message/i2o/i2o_block.c453
-rw-r--r--drivers/message/i2o/i2o_block.h34
-rw-r--r--drivers/message/i2o/i2o_config.c124
-rw-r--r--drivers/message/i2o/i2o_proc.c6
-rw-r--r--drivers/message/i2o/i2o_scsi.c505
-rw-r--r--drivers/message/i2o/iop.c566
-rw-r--r--drivers/message/i2o/pci.c246
-rw-r--r--drivers/net/e1000/e1000_main.c1
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/mkiss.c2
-rw-r--r--drivers/net/irda/irtty-sir.c2
-rw-r--r--drivers/net/ppp_async.c2
-rw-r--r--drivers/net/ppp_synctty.c2
-rw-r--r--drivers/net/slip.c16
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/oprofile/buffer_sync.c29
-rw-r--r--drivers/oprofile/event_buffer.h3
-rw-r--r--drivers/parport/parport_pc.c4
-rw-r--r--drivers/parport/parport_serial.c5
-rw-r--r--drivers/parport/probe.c18
-rw-r--r--drivers/pcmcia/cs.c11
-rw-r--r--drivers/pcmcia/ti113x.h167
-rw-r--r--drivers/pcmcia/yenta_socket.c60
-rw-r--r--drivers/pnp/card.c3
-rw-r--r--drivers/pnp/manager.c1
-rw-r--r--drivers/s390/block/dcssblk.c44
-rw-r--r--drivers/scsi/dpt_i2o.c17
-rw-r--r--drivers/scsi/hosts.c2
-rw-r--r--drivers/scsi/scsi.c6
-rw-r--r--drivers/scsi/scsi_debug.c2
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/scsi_priv.h4
-rw-r--r--drivers/scsi/scsi_sysfs.c4
-rw-r--r--drivers/serial/8250.c64
-rw-r--r--drivers/serial/8250.h3
-rw-r--r--drivers/serial/au1x00_uart.c10
-rw-r--r--drivers/serial/m32r_sio.c10
-rw-r--r--drivers/serial/pxa.c10
-rw-r--r--drivers/serial/s3c2410.c4
-rw-r--r--drivers/serial/sn_console.c1
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/hcd.h2
-rw-r--r--drivers/usb/core/inode.c13
-rw-r--r--drivers/usb/media/pwc/pwc-uncompress.c11
-rw-r--r--drivers/usb/mon/Kconfig13
-rw-r--r--drivers/usb/mon/Makefile2
-rw-r--r--drivers/video/pxafb.c3
-rw-r--r--fs/Kconfig19
-rw-r--r--fs/block_dev.c5
-rw-r--r--fs/buffer.c57
-rw-r--r--fs/char_dev.c13
-rw-r--r--fs/debugfs/inode.c12
-rw-r--r--fs/direct-io.c2
-rw-r--r--fs/dquot.c16
-rw-r--r--fs/eventpoll.c195
-rw-r--r--fs/exec.c23
-rw-r--r--fs/ext2/Makefile1
-rw-r--r--fs/ext2/acl.c12
-rw-r--r--fs/ext2/acl.h2
-rw-r--r--fs/ext2/ext2.h2
-rw-r--r--fs/ext2/file.c14
-rw-r--r--fs/ext2/inode.c31
-rw-r--r--fs/ext2/namei.c12
-rw-r--r--fs/ext2/super.c27
-rw-r--r--fs/ext2/xip.c80
-rw-r--r--fs/ext2/xip.h25
-rw-r--r--fs/ext3/acl.c17
-rw-r--r--fs/ext3/acl.h2
-rw-r--r--fs/ext3/inode.c7
-rw-r--r--fs/ext3/namei.c37
-rw-r--r--fs/ext3/super.c55
-rw-r--r--fs/ext3/xattr.c2
-rw-r--r--fs/file_table.c57
-rw-r--r--fs/fs-writeback.c64
-rw-r--r--fs/inode.c16
-rw-r--r--fs/jfs/acl.c11
-rw-r--r--fs/jfs/jfs_acl.h2
-rw-r--r--fs/jfs/super.c1
-rw-r--r--fs/jfs/xattr.c7
-rw-r--r--fs/lockd/svc.c4
-rw-r--r--fs/namei.c20
-rw-r--r--fs/namespace.c2
-rw-r--r--fs/nfs/direct.c5
-rw-r--r--fs/nfsd/Makefile2
-rw-r--r--fs/nfsd/nfs4acl.c4
-rw-r--r--fs/nfsd/nfs4callback.c13
-rw-r--r--fs/nfsd/nfs4idmap.c12
-rw-r--r--fs/nfsd/nfs4proc.c26
-rw-r--r--fs/nfsd/nfs4recover.c431
-rw-r--r--fs/nfsd/nfs4state.c1028
-rw-r--r--fs/nfsd/nfs4xdr.c11
-rw-r--r--fs/nfsd/nfsctl.c28
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--fs/nfsd/vfs.c9
-rw-r--r--fs/open.c45
-rw-r--r--fs/proc/base.c6
-rw-r--r--fs/proc/proc_misc.c2
-rw-r--r--fs/qnx4/dir.c2
-rw-r--r--fs/qnx4/inode.c4
-rw-r--r--fs/quota.c60
-rw-r--r--fs/read_write.c20
-rw-r--r--fs/reiserfs/file.c4
-rw-r--r--fs/reiserfs/inode.c13
-rw-r--r--fs/reiserfs/journal.c2
-rw-r--r--fs/reiserfs/namei.c25
-rw-r--r--fs/reiserfs/stree.c2
-rw-r--r--fs/reiserfs/super.c102
-rw-r--r--fs/reiserfs/xattr_acl.c26
-rw-r--r--fs/super.c83
-rw-r--r--fs/sysfs/dir.c5
-rw-r--r--fs/sysfs/file.c10
-rw-r--r--fs/sysfs/group.c4
-rw-r--r--fs/sysfs/inode.c10
-rw-r--r--fs/sysfs/sysfs.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c3
-rw-r--r--include/asm-alpha/mmzone.h3
-rw-r--r--include/asm-arm/arch-ixp2000/gpio.h31
-rw-r--r--include/asm-arm/arch-ixp2000/io.h76
-rw-r--r--include/asm-arm/arch-ixp2000/platform.h22
-rw-r--r--include/asm-arm/arch-ixp4xx/debug-macro.S1
-rw-r--r--include/asm-arm/arch-ixp4xx/ixp4xx-regs.h10
-rw-r--r--include/asm-arm/io.h2
-rw-r--r--include/asm-arm/thread_info.h2
-rw-r--r--include/asm-arm26/thread_info.h2
-rw-r--r--include/asm-cris/thread_info.h2
-rw-r--r--include/asm-frv/thread_info.h2
-rw-r--r--include/asm-generic/percpu.h2
-rw-r--r--include/asm-generic/topology.h9
-rw-r--r--include/asm-h8300/thread_info.h2
-rw-r--r--include/asm-i386/checksum.h2
-rw-r--r--include/asm-i386/genapic.h1
-rw-r--r--include/asm-i386/kprobes.h3
-rw-r--r--include/asm-i386/mach-bigsmp/mach_apic.h2
-rw-r--r--include/asm-i386/mach-default/mach_apic.h2
-rw-r--r--include/asm-i386/mach-es7000/mach_apic.h2
-rw-r--r--include/asm-i386/mach-generic/mach_apic.h1
-rw-r--r--include/asm-i386/mach-numaq/mach_apic.h2
-rw-r--r--include/asm-i386/mach-summit/mach_apic.h2
-rw-r--r--include/asm-i386/mach-visws/mach_apic.h2
-rw-r--r--include/asm-i386/mmzone.h93
-rw-r--r--include/asm-i386/page.h6
-rw-r--r--include/asm-i386/param.h4
-rw-r--r--include/asm-i386/pgtable.h4
-rw-r--r--include/asm-i386/processor.h14
-rw-r--r--include/asm-i386/ptrace.h3
-rw-r--r--include/asm-i386/sparsemem.h31
-rw-r--r--include/asm-i386/string.h32
-rw-r--r--include/asm-i386/thread_info.h2
-rw-r--r--include/asm-i386/timer.h2
-rw-r--r--include/asm-i386/timex.h5
-rw-r--r--include/asm-i386/topology.h8
-rw-r--r--include/asm-ia64/break.h2
-rw-r--r--include/asm-ia64/compat.h1
-rw-r--r--include/asm-ia64/fcntl.h2
-rw-r--r--include/asm-ia64/kdebug.h61
-rw-r--r--include/asm-ia64/kprobes.h116
-rw-r--r--include/asm-ia64/mmzone.h4
-rw-r--r--include/asm-ia64/param.h2
-rw-r--r--include/asm-ia64/percpu.h2
-rw-r--r--include/asm-ia64/thread_info.h2
-rw-r--r--include/asm-m32r/mmzone.h3
-rw-r--r--include/asm-m32r/thread_info.h2
-rw-r--r--include/asm-m32r/topology.h44
-rw-r--r--include/asm-m68k/thread_info.h2
-rw-r--r--include/asm-m68knommu/thread_info.h2
-rw-r--r--include/asm-mips/compat.h1
-rw-r--r--include/asm-mips/thread_info.h2
-rw-r--r--include/asm-parisc/compat.h2
-rw-r--r--include/asm-parisc/mmzone.h3
-rw-r--r--include/asm-parisc/thread_info.h2
-rw-r--r--include/asm-ppc/thread_info.h3
-rw-r--r--include/asm-ppc64/compat.h1
-rw-r--r--include/asm-ppc64/machdep.h1
-rw-r--r--include/asm-ppc64/mmu.h5
-rw-r--r--include/asm-ppc64/mmzone.h44
-rw-r--r--include/asm-ppc64/nvram.h1
-rw-r--r--include/asm-ppc64/page.h3
-rw-r--r--include/asm-ppc64/ppc32.h2
-rw-r--r--include/asm-ppc64/processor.h15
-rw-r--r--include/asm-ppc64/rtas.h6
-rw-r--r--include/asm-ppc64/smp.h8
-rw-r--r--include/asm-ppc64/sparsemem.h16
-rw-r--r--include/asm-ppc64/thread_info.h2
-rw-r--r--include/asm-ppc64/time.h9
-rw-r--r--include/asm-ppc64/topology.h4
-rw-r--r--include/asm-s390/thread_info.h2
-rw-r--r--include/asm-sh/thread_info.h2
-rw-r--r--include/asm-sh64/thread_info.h2
-rw-r--r--include/asm-sparc/thread_info.h4
-rw-r--r--include/asm-sparc64/compat.h1
-rw-r--r--include/asm-sparc64/thread_info.h2
-rw-r--r--include/asm-um/thread_info.h2
-rw-r--r--include/asm-v850/thread_info.h3
-rw-r--r--include/asm-x86_64/bitops.h2
-rw-r--r--include/asm-x86_64/ia32.h2
-rw-r--r--include/asm-x86_64/io.h5
-rw-r--r--include/asm-x86_64/kprobes.h3
-rw-r--r--include/asm-x86_64/mmzone.h20
-rw-r--r--include/asm-x86_64/msr.h5
-rw-r--r--include/asm-x86_64/page.h4
-rw-r--r--include/asm-x86_64/param.h6
-rw-r--r--include/asm-x86_64/percpu.h2
-rw-r--r--include/asm-x86_64/processor.h8
-rw-r--r--include/asm-x86_64/ptrace.h1
-rw-r--r--include/asm-x86_64/sparsemem.h26
-rw-r--r--include/asm-x86_64/thread_info.h2
-rw-r--r--include/asm-x86_64/timex.h3
-rw-r--r--include/asm-x86_64/topology.h18
-rw-r--r--include/asm-xtensa/a.out.h33
-rw-r--r--include/asm-xtensa/atomic.h272
-rw-r--r--include/asm-xtensa/bitops.h446
-rw-r--r--include/asm-xtensa/bootparam.h61
-rw-r--r--include/asm-xtensa/bug.h41
-rw-r--r--include/asm-xtensa/bugs.h22
-rw-r--r--include/asm-xtensa/byteorder.h82
-rw-r--r--include/asm-xtensa/cache.h32
-rw-r--r--include/asm-xtensa/cacheflush.h122
-rw-r--r--include/asm-xtensa/checksum.h264
-rw-r--r--include/asm-xtensa/coprocessor.h70
-rw-r--r--include/asm-xtensa/cpumask.h16
-rw-r--r--include/asm-xtensa/cputime.h6
-rw-r--r--include/asm-xtensa/current.h38
-rw-r--r--include/asm-xtensa/delay.h50
-rw-r--r--include/asm-xtensa/div64.h19
-rw-r--r--include/asm-xtensa/dma-mapping.h182
-rw-r--r--include/asm-xtensa/dma.h61
-rw-r--r--include/asm-xtensa/elf.h222
-rw-r--r--include/asm-xtensa/errno.h142
-rw-r--r--include/asm-xtensa/fcntl.h101
-rw-r--r--include/asm-xtensa/fixmap.h252
-rw-r--r--include/asm-xtensa/hardirq.h28
-rw-r--r--include/asm-xtensa/hdreg.h17
-rw-r--r--include/asm-xtensa/highmem.h17
-rw-r--r--include/asm-xtensa/hw_irq.h18
-rw-r--r--include/asm-xtensa/ide.h36
-rw-r--r--include/asm-xtensa/io.h197
-rw-r--r--include/asm-xtensa/ioctl.h83
-rw-r--r--include/asm-xtensa/ioctls.h112
-rw-r--r--include/asm-xtensa/ipc.h34
-rw-r--r--include/asm-xtensa/ipcbuf.h37
-rw-r--r--include/asm-xtensa/irq.h37
-rw-r--r--include/asm-xtensa/kmap_types.h31
-rw-r--r--include/asm-xtensa/linkage.h16
-rw-r--r--include/asm-xtensa/local.h16
-rw-r--r--include/asm-xtensa/mman.h80
-rw-r--r--include/asm-xtensa/mmu.h17
-rw-r--r--include/asm-xtensa/mmu_context.h330
-rw-r--r--include/asm-xtensa/module.h25
-rw-r--r--include/asm-xtensa/msgbuf.h48
-rw-r--r--include/asm-xtensa/namei.h26
-rw-r--r--include/asm-xtensa/page.h133
-rw-r--r--include/asm-xtensa/page.h.n135
-rw-r--r--include/asm-xtensa/param.h34
-rw-r--r--include/asm-xtensa/pci-bridge.h88
-rw-r--r--include/asm-xtensa/pci.h89
-rw-r--r--include/asm-xtensa/percpu.h16
-rw-r--r--include/asm-xtensa/pgalloc.h116
-rw-r--r--include/asm-xtensa/pgtable.h468
-rw-r--r--include/asm-xtensa/platform-iss/hardware.h29
-rw-r--r--include/asm-xtensa/platform.h92
-rw-r--r--include/asm-xtensa/poll.h37
-rw-r--r--include/asm-xtensa/posix_types.h123
-rw-r--r--include/asm-xtensa/processor.h205
-rw-r--r--include/asm-xtensa/ptrace.h135
-rw-r--r--include/asm-xtensa/resource.h16
-rw-r--r--include/asm-xtensa/rmap.h16
-rw-r--r--include/asm-xtensa/rwsem.h175
-rw-r--r--include/asm-xtensa/scatterlist.h34
-rw-r--r--include/asm-xtensa/sections.h16
-rw-r--r--include/asm-xtensa/segment.h16
-rw-r--r--include/asm-xtensa/semaphore.h129
-rw-r--r--include/asm-xtensa/sembuf.h44
-rw-r--r--include/asm-xtensa/serial.h18
-rw-r--r--include/asm-xtensa/setup.h16
-rw-r--r--include/asm-xtensa/shmbuf.h50
-rw-r--r--include/asm-xtensa/shmparam.h23
-rw-r--r--include/asm-xtensa/sigcontext.h44
-rw-r--r--include/asm-xtensa/siginfo.h16
-rw-r--r--include/asm-xtensa/signal.h187
-rw-r--r--include/asm-xtensa/smp.h27
-rw-r--r--include/asm-xtensa/socket.h61
-rw-r--r--include/asm-xtensa/sockios.h30
-rw-r--r--include/asm-xtensa/spinlock.h16
-rw-r--r--include/asm-xtensa/stat.h105
-rw-r--r--include/asm-xtensa/statfs.h17
-rw-r--r--include/asm-xtensa/string.h124
-rw-r--r--include/asm-xtensa/system.h252
-rw-r--r--include/asm-xtensa/termbits.h194
-rw-r--r--include/asm-xtensa/termios.h122
-rw-r--r--include/asm-xtensa/thread_info.h146
-rw-r--r--include/asm-xtensa/timex.h94
-rw-r--r--include/asm-xtensa/tlb.h25
-rw-r--r--include/asm-xtensa/tlbflush.h200
-rw-r--r--include/asm-xtensa/topology.h16
-rw-r--r--include/asm-xtensa/types.h66
-rw-r--r--include/asm-xtensa/uaccess.h532
-rw-r--r--include/asm-xtensa/ucontext.h22
-rw-r--r--include/asm-xtensa/unaligned.h28
-rw-r--r--include/asm-xtensa/unistd.h537
-rw-r--r--include/asm-xtensa/user.h20
-rw-r--r--include/asm-xtensa/vga.h19
-rw-r--r--include/asm-xtensa/xor.h16
-rw-r--r--include/asm-xtensa/xtensa/cacheasm.h708
-rw-r--r--include/asm-xtensa/xtensa/cacheattrasm.h432
-rw-r--r--include/asm-xtensa/xtensa/config-linux_be/core.h1270
-rw-r--r--include/asm-xtensa/xtensa/config-linux_be/defs.h270
-rw-r--r--include/asm-xtensa/xtensa/config-linux_be/specreg.h99
-rw-r--r--include/asm-xtensa/xtensa/config-linux_be/system.h198
-rw-r--r--include/asm-xtensa/xtensa/config-linux_be/tie.h275
-rw-r--r--include/asm-xtensa/xtensa/coreasm.h526
-rw-r--r--include/asm-xtensa/xtensa/corebits.h77
-rw-r--r--include/asm-xtensa/xtensa/hal.h822
-rw-r--r--include/asm-xtensa/xtensa/simcall.h130
-rw-r--r--include/asm-xtensa/xtensa/xt2000-uart.h155
-rw-r--r--include/asm-xtensa/xtensa/xt2000.h408
-rw-r--r--include/asm-xtensa/xtensa/xtboard.h120
-rw-r--r--include/linux/binfmts.h5
-rw-r--r--include/linux/blkdev.h10
-rw-r--r--include/linux/bootmem.h9
-rw-r--r--include/linux/dqblk_v1.h6
-rw-r--r--include/linux/dqblk_v2.h6
-rw-r--r--include/linux/ext2_fs.h25
-rw-r--r--include/linux/ext3_fs.h1
-rw-r--r--include/linux/ext3_jbd.h19
-rw-r--r--include/linux/fcntl.h4
-rw-r--r--include/linux/fs.h27
-rw-r--r--include/linux/genhd.h3
-rw-r--r--include/linux/i2o-dev.h43
-rw-r--r--include/linux/i2o.h497
-rw-r--r--include/linux/ide.h2
-rw-r--r--include/linux/ipmi.h5
-rw-r--r--include/linux/irq.h1
-rw-r--r--include/linux/key-ui.h47
-rw-r--r--include/linux/key.h44
-rw-r--r--include/linux/keyctl.h11
-rw-r--r--include/linux/kmod.h13
-rw-r--r--include/linux/kprobes.h100
-rw-r--r--include/linux/loop.h2
-rw-r--r--include/linux/mempool.h11
-rw-r--r--include/linux/mm.h119
-rw-r--r--include/linux/mmzone.h171
-rw-r--r--include/linux/module.h5
-rw-r--r--include/linux/namespace.h1
-rw-r--r--include/linux/netdevice.h15
-rw-r--r--include/linux/nfs4.h2
-rw-r--r--include/linux/nfsd/nfsd.h8
-rw-r--r--include/linux/nfsd/state.h47
-rw-r--r--include/linux/nfsd/xdr4.h1
-rw-r--r--include/linux/nfsd_idmap.h5
-rw-r--r--include/linux/numa.h2
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/pkt_cls.h1
-rw-r--r--include/linux/pktcdvd.h2
-rw-r--r--include/linux/posix_acl_xattr.h11
-rw-r--r--include/linux/qnx4_fs.h18
-rw-r--r--include/linux/qnxtypes.h16
-rw-r--r--include/linux/quota.h7
-rw-r--r--include/linux/quotaops.h3
-rw-r--r--include/linux/reiserfs_acl.h1
-rw-r--r--include/linux/reiserfs_fs.h15
-rw-r--r--include/linux/reiserfs_fs_sb.h2
-rw-r--r--include/linux/rmap.h6
-rw-r--r--include/linux/rtnetlink.h7
-rw-r--r--include/linux/sched.h10
-rw-r--r--include/linux/skbuff.h23
-rw-r--r--include/linux/string.h2
-rw-r--r--include/linux/sysctl.h11
-rw-r--r--include/linux/tc_ematch/tc_em_text.h19
-rw-r--r--include/linux/tcp.h50
-rw-r--r--include/linux/tcp_diag.h4
-rw-r--r--include/linux/textsearch.h180
-rw-r--r--include/linux/textsearch_fsm.h48
-rw-r--r--include/linux/timer.h34
-rw-r--r--include/linux/tty.h1
-rw-r--r--include/linux/usb.h2
-rw-r--r--include/linux/wait.h16
-rw-r--r--include/media/audiochip.h4
-rw-r--r--include/media/id.h4
-rw-r--r--include/media/ir-common.h3
-rw-r--r--include/media/tuner.h29
-rw-r--r--include/media/tveeprom.h4
-rw-r--r--include/net/sctp/sm.h6
-rw-r--r--include/net/tcp.h239
-rw-r--r--include/pcmcia/ss.h8
-rw-r--r--include/scsi/sg_request.h26
-rw-r--r--include/sound/core.h3
-rw-r--r--init/calibrate.c94
-rw-r--r--ipc/sem.c9
-rw-r--r--kernel/Kconfig.hz46
-rw-r--r--kernel/cpuset.c8
-rw-r--r--kernel/exit.c16
-rw-r--r--kernel/irq/spurious.c2
-rw-r--r--kernel/kmod.c17
-rw-r--r--kernel/kprobes.c288
-rw-r--r--kernel/module.c97
-rw-r--r--kernel/posix-timers.c34
-rw-r--r--kernel/power/swsusp.c2
-rw-r--r--kernel/printk.c12
-rw-r--r--kernel/sched.c4
-rw-r--r--kernel/signal.c1
-rw-r--r--kernel/sys.c110
-rw-r--r--kernel/sysctl.c9
-rw-r--r--kernel/timer.c351
-rw-r--r--lib/Kconfig29
-rw-r--r--lib/Makefile4
-rw-r--r--lib/textsearch.c317
-rw-r--r--lib/ts_fsm.c338
-rw-r--r--lib/ts_kmp.c145
-rw-r--r--mm/Kconfig91
-rw-r--r--mm/Makefile2
-rw-r--r--mm/bootmem.c9
-rw-r--r--mm/fadvise.c4
-rw-r--r--mm/filemap.c80
-rw-r--r--mm/filemap.h94
-rw-r--r--mm/filemap_xip.c447
-rw-r--r--mm/madvise.c6
-rw-r--r--mm/memory.c4
-rw-r--r--mm/mempool.c20
-rw-r--r--mm/page_alloc.c51
-rw-r--r--mm/rmap.c4
-rw-r--r--mm/slab.c24
-rw-r--r--mm/sparse.c137
-rw-r--r--net/core/dev.c125
-rw-r--r--net/core/neighbour.c3
-rw-r--r--net/core/skbuff.c157
-rw-r--r--net/core/sysctl_net_core.c61
-rw-r--r--net/ipv4/Kconfig90
-rw-r--r--net/ipv4/Makefile10
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c114
-rw-r--r--net/ipv4/tcp.c33
-rw-r--r--net/ipv4/tcp_bic.c331
-rw-r--r--net/ipv4/tcp_cong.c237
-rw-r--r--net/ipv4/tcp_diag.c34
-rw-r--r--net/ipv4/tcp_highspeed.c181
-rw-r--r--net/ipv4/tcp_htcp.c289
-rw-r--r--net/ipv4/tcp_hybla.c187
-rw-r--r--net/ipv4/tcp_input.c737
-rw-r--r--net/ipv4/tcp_ipv4.c3
-rw-r--r--net/ipv4/tcp_minisocks.c4
-rw-r--r--net/ipv4/tcp_output.c23
-rw-r--r--net/ipv4/tcp_scalable.c68
-rw-r--r--net/ipv4/tcp_vegas.c411
-rw-r--r--net/ipv4/tcp_westwood.c259
-rw-r--r--net/ipv6/addrconf.c3
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/sched/Kconfig12
-rw-r--r--net/sched/Makefile1
-rw-r--r--net/sched/em_text.c157
-rw-r--r--net/sctp/sm_statefuns.c16
-rw-r--r--net/sunrpc/sunrpc_syms.c1
-rw-r--r--net/sunrpc/svcauth_unix.c11
-rw-r--r--scripts/Makefile.build4
-rw-r--r--scripts/kconfig/gconf.glade10
-rw-r--r--security/commoncap.c2
-rw-r--r--security/dummy.c2
-rw-r--r--security/keys/Makefile5
-rw-r--r--security/keys/compat.c7
-rw-r--r--security/keys/internal.h45
-rw-r--r--security/keys/key.c118
-rw-r--r--security/keys/keyctl.c199
-rw-r--r--security/keys/keyring.c312
-rw-r--r--security/keys/proc.c21
-rw-r--r--security/keys/process_keys.c213
-rw-r--r--security/keys/request_key.c221
-rw-r--r--security/keys/request_key_auth.c180
-rw-r--r--security/keys/user_defined.c87
-rw-r--r--sound/core/info.c3
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/memory.c41
-rw-r--r--sound/core/oss/mixer_oss.c3
-rw-r--r--sound/core/oss/pcm_oss.c3
-rw-r--r--sound/core/sound.c2
-rw-r--r--sound/core/timer.c3
-rw-r--r--sound/isa/gus/gus_mem.c7
-rw-r--r--sound/pci/hda/patch_realtek.c2
-rw-r--r--sound/synth/emux/emux.c3
861 files changed, 59492 insertions, 10288 deletions
diff --git a/Documentation/Changes b/Documentation/Changes
index 57542bc25edd..b37600754762 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -63,7 +63,7 @@ o PPP 2.4.0 # pppd --version
63o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version 63o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
64o nfs-utils 1.0.5 # showmount --version 64o nfs-utils 1.0.5 # showmount --version
65o procps 3.2.0 # ps --version 65o procps 3.2.0 # ps --version
66o oprofile 0.5.3 # oprofiled --version 66o oprofile 0.9 # oprofiled --version
67 67
68Kernel compilation 68Kernel compilation
69================== 69==================
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 87da3478fada..fa3e29ad8a46 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -49,7 +49,7 @@ installmandocs: mandocs
49KERNELDOC = scripts/kernel-doc 49KERNELDOC = scripts/kernel-doc
50DOCPROC = scripts/basic/docproc 50DOCPROC = scripts/basic/docproc
51 51
52XMLTOFLAGS = -m Documentation/DocBook/stylesheet.xsl 52XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
53#XMLTOFLAGS += --skip-validation 53#XMLTOFLAGS += --skip-validation
54 54
55### 55###
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index bb6a0106be11..d650ce36485f 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -266,7 +266,7 @@ X!Ekernel/module.c
266 <chapter id="hardware"> 266 <chapter id="hardware">
267 <title>Hardware Interfaces</title> 267 <title>Hardware Interfaces</title>
268 <sect1><title>Interrupt Handling</title> 268 <sect1><title>Interrupt Handling</title>
269!Iarch/i386/kernel/irq.c 269!Ikernel/irq/manage.c
270 </sect1> 270 </sect1>
271 271
272 <sect1><title>Resources Management</title> 272 <sect1><title>Resources Management</title>
diff --git a/Documentation/DocBook/stylesheet.xsl b/Documentation/DocBook/stylesheet.xsl
index e14c21dda403..64be9f7ee3bb 100644
--- a/Documentation/DocBook/stylesheet.xsl
+++ b/Documentation/DocBook/stylesheet.xsl
@@ -2,4 +2,5 @@
2<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0"> 2<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
3<param name="chunk.quietly">1</param> 3<param name="chunk.quietly">1</param>
4<param name="funcsynopsis.style">ansi</param> 4<param name="funcsynopsis.style">ansi</param>
5<param name="funcsynopsis.tabular.threshold">80</param>
5</stylesheet> 6</stylesheet>
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
index 90d10e708ca3..84d3d4d10c17 100644
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -25,9 +25,10 @@ subject and I can't cover it all here!
25Configuration 25Configuration
26------------- 26-------------
27 27
28The LinuxIPMI driver is modular, which means you have to pick several 28The Linux IPMI driver is modular, which means you have to pick several
29things to have it work right depending on your hardware. Most of 29things to have it work right depending on your hardware. Most of
30these are available in the 'Character Devices' menu. 30these are available in the 'Character Devices' menu then the IPMI
31menu.
31 32
32No matter what, you must pick 'IPMI top-level message handler' to use 33No matter what, you must pick 'IPMI top-level message handler' to use
33IPMI. What you do beyond that depends on your needs and hardware. 34IPMI. What you do beyond that depends on your needs and hardware.
@@ -35,33 +36,30 @@ IPMI. What you do beyond that depends on your needs and hardware.
35The message handler does not provide any user-level interfaces. 36The message handler does not provide any user-level interfaces.
36Kernel code (like the watchdog) can still use it. If you need access 37Kernel code (like the watchdog) can still use it. If you need access
37from userland, you need to select 'Device interface for IPMI' if you 38from userland, you need to select 'Device interface for IPMI' if you
38want access through a device driver. Another interface is also 39want access through a device driver.
39available, you may select 'IPMI sockets' in the 'Networking Support' 40
40main menu. This provides a socket interface to IPMI. You may select 41The driver interface depends on your hardware. If your system
41both of these at the same time, they will both work together. 42properly provides the SMBIOS info for IPMI, the driver will detect it
42 43and just work. If you have a board with a standard interface (These
43The driver interface depends on your hardware. If you have a board 44will generally be either "KCS", "SMIC", or "BT", consult your hardware
44with a standard interface (These will generally be either "KCS", 45manual), choose the 'IPMI SI handler' option. A driver also exists
45"SMIC", or "BT", consult your hardware manual), choose the 'IPMI SI 46for direct I2C access to the IPMI management controller. Some boards
46handler' option. A driver also exists for direct I2C access to the 47support this, but it is unknown if it will work on every board. For
47IPMI management controller. Some boards support this, but it is 48this, choose 'IPMI SMBus handler', but be ready to try to do some
48unknown if it will work on every board. For this, choose 'IPMI SMBus 49figuring to see if it will work on your system if the SMBIOS/APCI
49handler', but be ready to try to do some figuring to see if it will 50information is wrong or not present. It is fairly safe to have both
50work. 51these enabled and let the drivers auto-detect what is present.
51
52There is also a KCS-only driver interface supplied, but it is
53depracated in favor of the SI interface.
54 52
55You should generally enable ACPI on your system, as systems with IPMI 53You should generally enable ACPI on your system, as systems with IPMI
56should have ACPI tables describing them. 54can have ACPI tables describing them.
57 55
58If you have a standard interface and the board manufacturer has done 56If you have a standard interface and the board manufacturer has done
59their job correctly, the IPMI controller should be automatically 57their job correctly, the IPMI controller should be automatically
60detect (via ACPI or SMBIOS tables) and should just work. Sadly, many 58detected (via ACPI or SMBIOS tables) and should just work. Sadly,
61boards do not have this information. The driver attempts standard 59many boards do not have this information. The driver attempts
62defaults, but they may not work. If you fall into this situation, you 60standard defaults, but they may not work. If you fall into this
63need to read the section below named 'The SI Driver' on how to 61situation, you need to read the section below named 'The SI Driver' or
64hand-configure your system. 62"The SMBus Driver" on how to hand-configure your system.
65 63
66IPMI defines a standard watchdog timer. You can enable this with the 64IPMI defines a standard watchdog timer. You can enable this with the
67'IPMI Watchdog Timer' config option. If you compile the driver into 65'IPMI Watchdog Timer' config option. If you compile the driver into
@@ -73,6 +71,18 @@ closed (by default it is disabled on close). Go into the 'Watchdog
73Cards' menu, enable 'Watchdog Timer Support', and enable the option 71Cards' menu, enable 'Watchdog Timer Support', and enable the option
74'Disable watchdog shutdown on close'. 72'Disable watchdog shutdown on close'.
75 73
74IPMI systems can often be powered off using IPMI commands. Select
75'IPMI Poweroff' to do this. The driver will auto-detect if the system
76can be powered off by IPMI. It is safe to enable this even if your
77system doesn't support this option. This works on ATCA systems, the
78Radisys CPI1 card, and any IPMI system that supports standard chassis
79management commands.
80
81If you want the driver to put an event into the event log on a panic,
82enable the 'Generate a panic event to all BMCs on a panic' option. If
83you want the whole panic string put into the event log using OEM
84events, enable the 'Generate OEM events containing the panic string'
85option.
76 86
77Basic Design 87Basic Design
78------------ 88------------
@@ -80,7 +90,7 @@ Basic Design
80The Linux IPMI driver is designed to be very modular and flexible, you 90The Linux IPMI driver is designed to be very modular and flexible, you
81only need to take the pieces you need and you can use it in many 91only need to take the pieces you need and you can use it in many
82different ways. Because of that, it's broken into many chunks of 92different ways. Because of that, it's broken into many chunks of
83code. These chunks are: 93code. These chunks (by module name) are:
84 94
85ipmi_msghandler - This is the central piece of software for the IPMI 95ipmi_msghandler - This is the central piece of software for the IPMI
86system. It handles all messages, message timing, and responses. The 96system. It handles all messages, message timing, and responses. The
@@ -93,18 +103,26 @@ ipmi_devintf - This provides a userland IOCTL interface for the IPMI
93driver, each open file for this device ties in to the message handler 103driver, each open file for this device ties in to the message handler
94as an IPMI user. 104as an IPMI user.
95 105
96ipmi_si - A driver for various system interfaces. This supports 106ipmi_si - A driver for various system interfaces. This supports KCS,
97KCS, SMIC, and may support BT in the future. Unless you have your own 107SMIC, and BT interfaces. Unless you have an SMBus interface or your
98custom interface, you probably need to use this. 108own custom interface, you probably need to use this.
99 109
100ipmi_smb - A driver for accessing BMCs on the SMBus. It uses the 110ipmi_smb - A driver for accessing BMCs on the SMBus. It uses the
101I2C kernel driver's SMBus interfaces to send and receive IPMI messages 111I2C kernel driver's SMBus interfaces to send and receive IPMI messages
102over the SMBus. 112over the SMBus.
103 113
104af_ipmi - A network socket interface to IPMI. This doesn't take up 114ipmi_watchdog - IPMI requires systems to have a very capable watchdog
105a character device in your system. 115timer. This driver implements the standard Linux watchdog timer
116interface on top of the IPMI message handler.
117
118ipmi_poweroff - Some systems support the ability to be turned off via
119IPMI commands.
106 120
107Note that the KCS-only interface ahs been removed. 121These are all individually selectable via configuration options.
122
123Note that the KCS-only interface has been removed. The af_ipmi driver
124is no longer supported and has been removed because it was impossible
125to do 32 bit emulation on 64-bit kernels with it.
108 126
109Much documentation for the interface is in the include files. The 127Much documentation for the interface is in the include files. The
110IPMI include files are: 128IPMI include files are:
@@ -424,7 +442,7 @@ at module load time (for a module) with:
424 modprobe ipmi_smb.o 442 modprobe ipmi_smb.o
425 addr=<adapter1>,<i2caddr1>[,<adapter2>,<i2caddr2>[,...]] 443 addr=<adapter1>,<i2caddr1>[,<adapter2>,<i2caddr2>[,...]]
426 dbg=<flags1>,<flags2>... 444 dbg=<flags1>,<flags2>...
427 [defaultprobe=0] [dbg_probe=1] 445 [defaultprobe=1] [dbg_probe=1]
428 446
429The addresses are specified in pairs, the first is the adapter ID and the 447The addresses are specified in pairs, the first is the adapter ID and the
430second is the I2C address on that adapter. 448second is the I2C address on that adapter.
@@ -532,3 +550,67 @@ Once you open the watchdog timer, you must write a 'V' character to the
532device to close it, or the timer will not stop. This is a new semantic 550device to close it, or the timer will not stop. This is a new semantic
533for the driver, but makes it consistent with the rest of the watchdog 551for the driver, but makes it consistent with the rest of the watchdog
534drivers in Linux. 552drivers in Linux.
553
554
555Panic Timeouts
556--------------
557
558The OpenIPMI driver supports the ability to put semi-custom and custom
559events in the system event log if a panic occurs. if you enable the
560'Generate a panic event to all BMCs on a panic' option, you will get
561one event on a panic in a standard IPMI event format. If you enable
562the 'Generate OEM events containing the panic string' option, you will
563also get a bunch of OEM events holding the panic string.
564
565
566The field settings of the events are:
567* Generator ID: 0x21 (kernel)
568* EvM Rev: 0x03 (this event is formatting in IPMI 1.0 format)
569* Sensor Type: 0x20 (OS critical stop sensor)
570* Sensor #: The first byte of the panic string (0 if no panic string)
571* Event Dir | Event Type: 0x6f (Assertion, sensor-specific event info)
572* Event Data 1: 0xa1 (Runtime stop in OEM bytes 2 and 3)
573* Event data 2: second byte of panic string
574* Event data 3: third byte of panic string
575See the IPMI spec for the details of the event layout. This event is
576always sent to the local management controller. It will handle routing
577the message to the right place
578
579Other OEM events have the following format:
580Record ID (bytes 0-1): Set by the SEL.
581Record type (byte 2): 0xf0 (OEM non-timestamped)
582byte 3: The slave address of the card saving the panic
583byte 4: A sequence number (starting at zero)
584The rest of the bytes (11 bytes) are the panic string. If the panic string
585is longer than 11 bytes, multiple messages will be sent with increasing
586sequence numbers.
587
588Because you cannot send OEM events using the standard interface, this
589function will attempt to find an SEL and add the events there. It
590will first query the capabilities of the local management controller.
591If it has an SEL, then they will be stored in the SEL of the local
592management controller. If not, and the local management controller is
593an event generator, the event receiver from the local management
594controller will be queried and the events sent to the SEL on that
595device. Otherwise, the events go nowhere since there is nowhere to
596send them.
597
598
599Poweroff
600--------
601
602If the poweroff capability is selected, the IPMI driver will install
603a shutdown function into the standard poweroff function pointer. This
604is in the ipmi_poweroff module. When the system requests a powerdown,
605it will send the proper IPMI commands to do this. This is supported on
606several platforms.
607
608There is a module parameter named "poweroff_control" that may either be zero
609(do a power down) or 2 (do a power cycle, power the system off, then power
610it on in a few seconds). Setting ipmi_poweroff.poweroff_control=x will do
611the same thing on the kernel command line. The parameter is also available
612via the proc filesystem in /proc/ipmi/poweroff_control. Note that if the
613system does not support power cycling, it will always to the power off.
614
615Note that if you have ACPI enabled, the system will prefer using ACPI to
616power off.
diff --git a/Documentation/basic_profiling.txt b/Documentation/basic_profiling.txt
index 65e3dc2d4437..8764e9f70821 100644
--- a/Documentation/basic_profiling.txt
+++ b/Documentation/basic_profiling.txt
@@ -27,9 +27,13 @@ dump output readprofile -m /boot/System.map > captured_profile
27 27
28Oprofile 28Oprofile
29-------- 29--------
30Get the source (I use 0.8) from http://oprofile.sourceforge.net/ 30
31and add "idle=poll" to the kernel command line 31Get the source (see Changes for required version) from
32http://oprofile.sourceforge.net/ and add "idle=poll" to the kernel command
33line.
34
32Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel 35Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel
36
33./configure --with-kernel-support 37./configure --with-kernel-support
34make install 38make install
35 39
@@ -46,7 +50,7 @@ start opcontrol --start
46stop opcontrol --stop 50stop opcontrol --stop
47dump output opreport > output_file 51dump output opreport > output_file
48 52
49To only report on the kernel, run opreport /boot/vmlinux > output_file 53To only report on the kernel, run opreport -l /boot/vmlinux > output_file
50 54
51A reset is needed to clear old statistics, which survive a reboot. 55A reset is needed to clear old statistics, which survive a reboot.
52 56
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 9a33bb94f74f..d4fda25db868 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -111,6 +111,7 @@ mkdep
111mktables 111mktables
112modpost 112modpost
113modversions.h* 113modversions.h*
114offset.h
114offsets.h 115offsets.h
115oui.c* 116oui.c*
116parse.c* 117parse.c*
diff --git a/Documentation/dvb/README.dibusb b/Documentation/dvb/README.dvb-usb
index 7a9e958513f3..c7ed01b9f8f4 100644
--- a/Documentation/dvb/README.dibusb
+++ b/Documentation/dvb/README.dvb-usb
@@ -1,16 +1,40 @@
1Documentation for dib3000* frontend drivers and dibusb device driver 1Documentation for dvb-usb-framework module and its devices
2====================================================================
3 2
4Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de), 3Idea behind the dvb-usb-framework
4=================================
5 5
6dibusb and dib3000mb/mc drivers based on GPL code, which has 6In March 2005 I got the new Twinhan USB2.0 DVB-T device. They provided specs and a firmware.
7 7
8Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) 8Quite keen I wanted to put the driver (with some quirks of course) into dibusb.
9After reading some specs and doing some USB snooping, it realized, that the
10dibusb-driver would be a complete mess afterwards. So I decided to do it in a
11different way: With the help of a dvb-usb-framework.
9 12
10This program is free software; you can redistribute it and/or 13The framework provides generic functions (mostly kernel API calls), such as:
11modify it under the terms of the GNU General Public License as
12published by the Free Software Foundation, version 2.
13 14
15- Transport Stream URB handling in conjunction with dvb-demux-feed-control
16 (bulk and isoc (TODO) are supported)
17- registering the device for the DVB-API
18- registering an I2C-adapter if applicable
19- remote-control/input-device handling
20- firmware requesting and loading (currently just for the Cypress USB
21 controller)
22- other functions/methods which can be shared by several drivers (such as
23 functions for bulk-control-commands)
24
25The source code of the particular DVB USB devices does just the communication
26with the device via the bus. The connection between the DVB-API-functionality
27is done via callbacks, assigned in a static device-description (struct
28dvb_usb_device) each device-driver has to have.
29
30For an example have a look in drivers/media/dvb/dvb-usb/vp7045*.
31
32Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
33ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
34the dvb-usb-lib.
35
36TODO: dynamic enabling and disabling of the pid-filter in regard to number of
37feeds requested.
14 38
15Supported devices USB1.1 39Supported devices USB1.1
16======================== 40========================
@@ -55,22 +79,34 @@ Others:
55- Grandtec USB DVB-T 79- Grandtec USB DVB-T
56 http://www.grand.com.tw/ 80 http://www.grand.com.tw/
57 81
58- Avermedia AverTV DVBT USB (2) 82- AVerMedia AverTV DVBT USB
59 http://www.avermedia.com/ 83 http://www.avermedia.com/
60 84
61- DiBcom USB DVB-T reference device (non-public) 85- DiBcom USB DVB-T reference device (non-public)
62 86
63 87
64Supported devices USB2.0 88Supported devices USB2.0-only
65======================== 89=============================
66- Twinhan MagicBox II (2) 90- Twinhan MagicBox II
67 http://www.twinhan.com/product_terrestrial_7.asp 91 http://www.twinhan.com/product_terrestrial_7.asp
68 92
69- Hanftek UMT-010 (1) 93- TwinhanDTV Alpha
94 http://www.twinhan.com/product_terrestrial_8.asp
95
96- DigitalNow TinyUSB 2 DVB-t Receiver
97 http://www.digitalnow.com.au/DigitalNow%20tinyUSB2%20Specifications.html
98
99- Hanftek UMT-010
70 http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529 100 http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529
71 101
72- Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 (1) 102
103Supported devices USB2.0 and USB1.1
104=============================
105- Typhoon/Yakumo/HAMA/Yuan DVB-T mobile USB2.0
73 http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T 106 http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T
107 http://www.yuan.com.tw/en/products/vdo_ub300.html
108 http://www.hama.de/portal/articleId*114663/action*2563
109 http://www.anubisline.com/english/articlec.asp?id=50502&catid=002
74 110
75- Artec T1 USB TVBOX (FX2) (2) 111- Artec T1 USB TVBOX (FX2) (2)
76 112
@@ -81,14 +117,24 @@ Supported devices USB2.0
81 117
82- DiBcom USB2.0 DVB-T reference device (non-public) 118- DiBcom USB2.0 DVB-T reference device (non-public)
83 119
841) It is working almost. 120- AVerMedia AverTV A800 DVB-T USB2.0
121
1221) It is working almost - work-in-progress.
852) No test reports received yet. 1232) No test reports received yet.
86 124
1250. History & News:
126 2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework
127 2005-04-02 - re-enabled and improved remote control code.
128 2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
129 2005-03-30 - first commit of the dvb-usb-module based on the dibusb-source. First device is a new driver for the
130 TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
87 131
880. NEWS: 132 (change from dvb-dibusb to dvb-usb)
133 2005-03-28 - added support for the AVerMedia AverTV DVB-T USB2.0 device (Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia)
134 2005-03-14 - added support for the Typhoon/Yakumo/HAMA DVB-T mobile USB2.0
89 2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron 135 2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron
90 2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2 136 2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2
91 2005-01-31 - distorted streaming is finally gone for USB1.1 devices 137 2005-01-31 - distorted streaming is gone for USB1.1 devices
92 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb 138 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
93 - first almost working version for HanfTek UMT-010 139 - first almost working version for HanfTek UMT-010
94 - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010 140 - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010
@@ -99,7 +145,7 @@ Supported devices USB2.0
99 2004-12-26 - refactored the dibusb-driver, splitted into separate files 145 2004-12-26 - refactored the dibusb-driver, splitted into separate files
100 - i2c-probing enabled 146 - i2c-probing enabled
101 2004-12-06 - possibility for demod i2c-address probing 147 2004-12-06 - possibility for demod i2c-address probing
102 - new usb IDs (Compro,Artec) 148 - new usb IDs (Compro, Artec)
103 2004-11-23 - merged changes from DiB3000MC_ver2.1 149 2004-11-23 - merged changes from DiB3000MC_ver2.1
104 - revised the debugging 150 - revised the debugging
105 - possibility to deliver the complete TS for USB2.0 151 - possibility to deliver the complete TS for USB2.0
@@ -127,8 +173,8 @@ Supported devices USB2.0
127 CTS Portable (Chinese Television System) 173 CTS Portable (Chinese Television System)
128 2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working 174 2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working
129 properly with firmware extracted from 2.422 175 properly with firmware extracted from 2.422
130 - #if for 2.6.4 (dvb), compile issue 176 - #if for 2.6.4 (dvb), compile issue
131 - changed firmware handling, see vp7041.txt sec 1.1 177 - changed firmware handling, see vp7041.txt sec 1.1
132 2004-07-02 - some tuner modifications, v0.1, cleanups, first public 178 2004-07-02 - some tuner modifications, v0.1, cleanups, first public
133 2004-06-28 - now using the dvb_dmx_swfilter_packets, everything 179 2004-06-28 - now using the dvb_dmx_swfilter_packets, everything
134 runs fine now 180 runs fine now
@@ -139,38 +185,27 @@ Supported devices USB2.0
139 2004-05-11 - start writing the driver 185 2004-05-11 - start writing the driver
140 186
1411. How to use? 1871. How to use?
142NOTE: This driver was developed using Linux 2.6.6.,
143it is working with 2.6.7 and above.
144
145Linux 2.4.x support is not planned, but patches are very welcome.
146
147NOTE: I'm using Debian testing, so the following explaination (especially
148the hotplug-path) needn't match your system, but probably it will :).
149
150The driver is included in the kernel since Linux 2.6.10.
151
1521.1. Firmware 1881.1. Firmware
153 189
154The USB driver needs to download a firmware to start working. 190Most of the USB drivers need to download a firmware to start working.
155
156You can either use "get_dvb_firmware dibusb" to download the firmware or you
157can get it directly via
158 191
159for USB1.1 (AN2135) 192for USB1.1 (AN2135) you need: dvb-usb-dibusb-5.0.0.11.fw
160http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw 193for USB2.0 HanfTek: dvb-usb-umt-010-02.fw
194for USB2.0 DiBcom: dvb-usb-dibusb-6.0.0.8.fw
195for USB2.0 AVerMedia AverTV DVB-T USB2: dvb-usb-avertv-a800-01.fw
196for USB2.0 TwinhanDTV Alpha/MagicBox II: dvb-usb-vp7045-01.fw
161 197
162for USB1.1 (AN2235) (a few Artec T1 devices) 198The files can be found on http://www.linuxtv.org/download/firmware/ .
163http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw
164 199
165for USB2.0 (FX2) Hauppauge, DiBcom 200We do not have the permission (yet) to publish the following firmware-files.
166http://www.linuxtv.org/downloads/firmware/dvb-dibusb-6.0.0.5.fw 201You'll need to extract them from the windows drivers.
167 202
168for USB2.0 ADSTech/Kworld USB2.0 203You should be able to use "get_dvb_firmware dvb-usb" to get the firmware:
169http://www.linuxtv.org/downloads/firmware/dvb-dibusb-adstech-usb2-1.fw
170
171for USB2.0 HanfTek
172http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw
173 204
205for USB1.1 (AN2235) (a few Artec T1 devices): dvb-usb-dibusb-an2235-01.fw
206for USB2.0 Hauppauge: dvb-usb-nova-t-usb2-01.fw
207for USB2.0 ADSTech/Kworld USB2.0: dvb-usb-adstech-usb2-01.fw
208for USB2.0 Yakumo/Typhoon/Hama: dvb-usb-dtt200u-01.fw
174 209
1751.2. Compiling 2101.2. Compiling
176 211
@@ -178,6 +213,9 @@ Since the driver is in the linux kernel, activating the driver in
178your favorite config-environment should sufficient. I recommend 213your favorite config-environment should sufficient. I recommend
179to compile the driver as module. Hotplug does the rest. 214to compile the driver as module. Hotplug does the rest.
180 215
216If you use dvb-kernel enter the build-2.6 directory run 'make' and 'insmod.sh
217load' afterwards.
218
1811.3. Loading the drivers 2191.3. Loading the drivers
182 220
183Hotplug is able to load the driver, when it is needed (because you plugged 221Hotplug is able to load the driver, when it is needed (because you plugged
@@ -188,15 +226,13 @@ from withing the dvb-kernel cvs repository.
188 226
189first have a look, which debug level are available: 227first have a look, which debug level are available:
190 228
191modinfo dib3000mb 229modinfo dvb-usb
192modinfo dib3000-common 230modinfo dvb-usb-vp7045
193modinfo dib3000mc 231etc.
194modinfo dvb-dibusb
195 232
196modprobe dib3000-common debug=<level> 233modprobe dvb-usb debug=<level>
197modprobe dib3000mb debug=<level> 234modprobe dvb-usb-vp7045 debug=<level>
198modprobe dib3000mc debug=<level> 235etc.
199modprobe dvb-dibusb debug=<level>
200 236
201should do the trick. 237should do the trick.
202 238
@@ -204,52 +240,32 @@ When the driver is loaded successfully, the firmware file was in
204the right place and the device is connected, the "Power"-LED should be 240the right place and the device is connected, the "Power"-LED should be
205turned on. 241turned on.
206 242
207At this point you should be able to start a dvb-capable application. For myself 243At this point you should be able to start a dvb-capable application. I'm use
208I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device 244(t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the
209in vdr is working now also. 245long-term test scenario.
210 246
2112. Known problems and bugs 2472. Known problems and bugs
212 248
213- Don't remove the USB device while running an DVB application, your system will die. 249- Don't remove the USB device while running an DVB application, your system
250 will go crazy or die most likely.
214 251
2152.1. Adding support for devices 2522.1. Adding support for devices
216 253
217It is not possible to determine the range of devices based on the DiBcom 254TODO
218reference designs. This is because the reference design of DiBcom can be sold
219to thirds, without telling DiBcom (so done with the Twinhan VP7041 and
220the HAMA device).
221
222When you think you have a device like this and the driver does not recognizes it,
223please send the ****load*.inf and the ****cap*.inf of the Windows driver to me.
224
225Sometimes the Vendor or Product ID is identical to the ones of Twinhan, even
226though it is not a Twinhan device (e.g. HAMA), then please send me the name
227of the device. I will add it to this list in order to make this clear to
228others.
229
230If you are familar with C you can also add the VID and PID of the device to
231the dvb-dibusb-core.c-file and create a patch and send it over to me or to
232the linux-dvb mailing list, _after_ you have tried compiling and modprobing
233it.
234 255
2352.2. USB1.1 Bandwidth limitation 2562.2. USB1.1 Bandwidth limitation
236 257
237Most of the currently supported devices are USB1.1 and thus they have a 258A lot of the currently supported devices are USB1.1 and thus they have a
238maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub. 259maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
239This is not enough for receiving the complete transport stream of a 260This is not enough for receiving the complete transport stream of a
240DVB-T channel (which can be about 16 MBit/s). Normally this is not a 261DVB-T channel (which is about 16 MBit/s). Normally this is not a
241problem, if you only want to watch TV (this does not apply for HDTV), 262problem, if you only want to watch TV (this does not apply for HDTV),
242but watching a channel while recording another channel on the same 263but watching a channel while recording another channel on the same
243frequency simply does not work very well. This applies to all USB1.1 264frequency simply does not work very well. This applies to all USB1.1
244DVB-T devices, not just dibusb) 265DVB-T devices, not just the dvb-usb-devices)
245
246Update: For the USB1.1 and VDR some work has been done (patches and comments
247are still very welcome). Maybe the problem is solved in the meantime because I
248now use the dmx_sw_filter function instead of dmx_sw_filter_packet. I hope the
249linux-dvb software filter is able to get the best of the garbled TS.
250 266
251The bug, where the TS is distorted by a heavy usage of the device is gone 267The bug, where the TS is distorted by a heavy usage of the device is gone
252definitely. All dibusb-devices I was using (Twinhan, Kworld, DiBcom) are 268definitely. All dvb-usb-devices I was using (Twinhan, Kworld, DiBcom) are
253working like charm now with VDR. Sometimes I even was able to record a channel 269working like charm now with VDR. Sometimes I even was able to record a channel
254and watch another one. 270and watch another one.
255 271
@@ -258,7 +274,7 @@ and watch another one.
258Patches, comments and suggestions are very very welcome. 274Patches, comments and suggestions are very very welcome.
259 275
2603. Acknowledgements 2763. Acknowledgements
261 Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for 277 Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for
262 providing specs, code and help, on which the dvb-dibusb, dib3000mb and 278 providing specs, code and help, on which the dvb-dibusb, dib3000mb and
263 dib3000mc are based. 279 dib3000mc are based.
264 280
@@ -270,9 +286,16 @@ Patches, comments and suggestions are very very welcome.
270 286
271 Bernd Wagner for helping with huge bug reports and discussions. 287 Bernd Wagner for helping with huge bug reports and discussions.
272 288
273 Gunnar Wittich and Joachim von Caron for their trust for giving me 289 Gunnar Wittich and Joachim von Caron for their trust for providing
274 root-shells on their machines to implement support for new devices. 290 root-shells on their machines to implement support for new devices.
275 291
292 Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei
293 Jung from AVerMedia who kindly provided a special firmware to get the device
294 up and running in Linux.
295
296 Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
297 writing the vp7045-driver.
298
276 Some guys on the linux-dvb mailing list for encouraging me 299 Some guys on the linux-dvb mailing list for encouraging me
277 300
278 Peter Schildmann >peter.schildmann-nospam-at-web.de< for his 301 Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
@@ -282,4 +305,4 @@ Patches, comments and suggestions are very very welcome.
282 Ulf Hermenau for helping me out with traditional chinese. 305 Ulf Hermenau for helping me out with traditional chinese.
283 306
284 André Smoktun and Christian Frömmel for supporting me with 307 André Smoktun and Christian Frömmel for supporting me with
285 hardware and listening to my problems very patient 308 hardware and listening to my problems very patient.
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 26414bc87c65..77511af45362 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -66,6 +66,14 @@ Who: Paul E. McKenney <paulmck@us.ibm.com>
66 66
67--------------------------- 67---------------------------
68 68
69What: remove verify_area()
70When: July 2006
71Files: Various uaccess.h headers.
72Why: Deprecated and redundant. access_ok() should be used instead.
73Who: Jesper Juhl <juhl-lkml@dif.dk>
74
75---------------------------
76
69What: IEEE1394 Audio and Music Data Transmission Protocol driver, 77What: IEEE1394 Audio and Music Data Transmission Protocol driver,
70 Connection Management Procedures driver 78 Connection Management Procedures driver
71When: November 2005 79When: November 2005
@@ -86,6 +94,16 @@ Who: Jody McIntyre <scjody@steamballoon.com>
86 94
87--------------------------- 95---------------------------
88 96
97What: register_serial/unregister_serial
98When: December 2005
99Why: This interface does not allow serial ports to be registered against
100 a struct device, and as such does not allow correct power management
101 of such ports. 8250-based ports should use serial8250_register_port
102 and serial8250_unregister_port instead.
103Who: Russell King <rmk@arm.linux.org.uk>
104
105---------------------------
106
89What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid 107What: i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
90When: November 2005 108When: November 2005
91Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c 109Files: drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
index b5cb9110cc6b..d16334ec48ba 100644
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -58,6 +58,8 @@ noacl Don't support POSIX ACLs.
58 58
59nobh Do not attach buffer_heads to file pagecache. 59nobh Do not attach buffer_heads to file pagecache.
60 60
61xip Use execute in place (no caching) if possible
62
61grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2. 63grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2.
62 64
63 65
diff --git a/Documentation/filesystems/xip.txt b/Documentation/filesystems/xip.txt
new file mode 100644
index 000000000000..6c0cef10eb4d
--- /dev/null
+++ b/Documentation/filesystems/xip.txt
@@ -0,0 +1,67 @@
1Execute-in-place for file mappings
2----------------------------------
3
4Motivation
5----------
6File mappings are performed by mapping page cache pages to userspace. In
7addition, read&write type file operations also transfer data from/to the page
8cache.
9
10For memory backed storage devices that use the block device interface, the page
11cache pages are in fact copies of the original storage. Various approaches
12exist to work around the need for an extra copy. The ramdisk driver for example
13does read the data into the page cache, keeps a reference, and discards the
14original data behind later on.
15
16Execute-in-place solves this issue the other way around: instead of keeping
17data in the page cache, the need to have a page cache copy is eliminated
18completely. With execute-in-place, read&write type operations are performed
19directly from/to the memory backed storage device. For file mappings, the
20storage device itself is mapped directly into userspace.
21
22This implementation was initialy written for shared memory segments between
23different virtual machines on s390 hardware to allow multiple machines to
24share the same binaries and libraries.
25
26Implementation
27--------------
28Execute-in-place is implemented in three steps: block device operation,
29address space operation, and file operations.
30
31A block device operation named direct_access is used to retrieve a
32reference (pointer) to a block on-disk. The reference is supposed to be
33cpu-addressable, physical address and remain valid until the release operation
34is performed. A struct block_device reference is used to address the device,
35and a sector_t argument is used to identify the individual block. As an
36alternative, memory technology devices can be used for this.
37
38The block device operation is optional, these block devices support it as of
39today:
40- dcssblk: s390 dcss block device driver
41
42An address space operation named get_xip_page is used to retrieve reference
43to a struct page. To address the target page, a reference to an address_space,
44and a sector number is provided. A 3rd argument indicates whether the
45function should allocate blocks if needed.
46
47This address space operation is mutually exclusive with readpage&writepage that
48do page cache read/write operations.
49The following filesystems support it as of today:
50- ext2: the second extended filesystem, see Documentation/filesystems/ext2.txt
51
52A set of file operations that do utilize get_xip_page can be found in
53mm/filemap_xip.c . The following file operation implementations are provided:
54- aio_read/aio_write
55- readv/writev
56- sendfile
57
58The generic file operations do_sync_read/do_sync_write can be used to implement
59classic synchronous IO calls.
60
61Shortcomings
62------------
63This implementation is limited to storage devices that are cpu addressable at
64all times (no highmem or such). It works well on rom/ram, but enhancements are
65needed to make it work with flash in read+write mode.
66Putting the Linux kernel and/or its modules on a xip filesystem does not mean
67they are not copied.
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 36d80aeeaf28..0321ded4b9ae 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -22,6 +22,7 @@ This document has the following sections:
22 - New procfs files 22 - New procfs files
23 - Userspace system call interface 23 - Userspace system call interface
24 - Kernel services 24 - Kernel services
25 - Notes on accessing payload contents
25 - Defining a key type 26 - Defining a key type
26 - Request-key callback service 27 - Request-key callback service
27 - Key access filesystem 28 - Key access filesystem
@@ -45,27 +46,26 @@ Each key has a number of attributes:
45 - State. 46 - State.
46 47
47 48
48 (*) Each key is issued a serial number of type key_serial_t that is unique 49 (*) Each key is issued a serial number of type key_serial_t that is unique for
49 for the lifetime of that key. All serial numbers are positive non-zero 50 the lifetime of that key. All serial numbers are positive non-zero 32-bit
50 32-bit integers. 51 integers.
51 52
52 Userspace programs can use a key's serial numbers as a way to gain access 53 Userspace programs can use a key's serial numbers as a way to gain access
53 to it, subject to permission checking. 54 to it, subject to permission checking.
54 55
55 (*) Each key is of a defined "type". Types must be registered inside the 56 (*) Each key is of a defined "type". Types must be registered inside the
56 kernel by a kernel service (such as a filesystem) before keys of that 57 kernel by a kernel service (such as a filesystem) before keys of that type
57 type can be added or used. Userspace programs cannot define new types 58 can be added or used. Userspace programs cannot define new types directly.
58 directly.
59 59
60 Key types are represented in the kernel by struct key_type. This defines 60 Key types are represented in the kernel by struct key_type. This defines a
61 a number of operations that can be performed on a key of that type. 61 number of operations that can be performed on a key of that type.
62 62
63 Should a type be removed from the system, all the keys of that type will 63 Should a type be removed from the system, all the keys of that type will
64 be invalidated. 64 be invalidated.
65 65
66 (*) Each key has a description. This should be a printable string. The key 66 (*) Each key has a description. This should be a printable string. The key
67 type provides an operation to perform a match between the description on 67 type provides an operation to perform a match between the description on a
68 a key and a criterion string. 68 key and a criterion string.
69 69
70 (*) Each key has an owner user ID, a group ID and a permissions mask. These 70 (*) Each key has an owner user ID, a group ID and a permissions mask. These
71 are used to control what a process may do to a key from userspace, and 71 are used to control what a process may do to a key from userspace, and
@@ -74,10 +74,10 @@ Each key has a number of attributes:
74 (*) Each key can be set to expire at a specific time by the key type's 74 (*) Each key can be set to expire at a specific time by the key type's
75 instantiation function. Keys can also be immortal. 75 instantiation function. Keys can also be immortal.
76 76
77 (*) Each key can have a payload. This is a quantity of data that represent 77 (*) Each key can have a payload. This is a quantity of data that represent the
78 the actual "key". In the case of a keyring, this is a list of keys to 78 actual "key". In the case of a keyring, this is a list of keys to which
79 which the keyring links; in the case of a user-defined key, it's an 79 the keyring links; in the case of a user-defined key, it's an arbitrary
80 arbitrary blob of data. 80 blob of data.
81 81
82 Having a payload is not required; and the payload can, in fact, just be a 82 Having a payload is not required; and the payload can, in fact, just be a
83 value stored in the struct key itself. 83 value stored in the struct key itself.
@@ -92,8 +92,8 @@ Each key has a number of attributes:
92 92
93 (*) Each key can be in one of a number of basic states: 93 (*) Each key can be in one of a number of basic states:
94 94
95 (*) Uninstantiated. The key exists, but does not have any data 95 (*) Uninstantiated. The key exists, but does not have any data attached.
96 attached. Keys being requested from userspace will be in this state. 96 Keys being requested from userspace will be in this state.
97 97
98 (*) Instantiated. This is the normal state. The key is fully formed, and 98 (*) Instantiated. This is the normal state. The key is fully formed, and
99 has data attached. 99 has data attached.
@@ -140,10 +140,10 @@ The key service provides a number of features besides keys:
140 clone, fork, vfork or execve occurs. A new keyring is created only when 140 clone, fork, vfork or execve occurs. A new keyring is created only when
141 required. 141 required.
142 142
143 The process-specific keyring is replaced with an empty one in the child 143 The process-specific keyring is replaced with an empty one in the child on
144 on clone, fork, vfork unless CLONE_THREAD is supplied, in which case it 144 clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is
145 is shared. execve also discards the process's process keyring and creates 145 shared. execve also discards the process's process keyring and creates a
146 a new one. 146 new one.
147 147
148 The session-specific keyring is persistent across clone, fork, vfork and 148 The session-specific keyring is persistent across clone, fork, vfork and
149 execve, even when the latter executes a set-UID or set-GID binary. A 149 execve, even when the latter executes a set-UID or set-GID binary. A
@@ -177,11 +177,11 @@ The key service provides a number of features besides keys:
177 If a system call that modifies a key or keyring in some way would put the 177 If a system call that modifies a key or keyring in some way would put the
178 user over quota, the operation is refused and error EDQUOT is returned. 178 user over quota, the operation is refused and error EDQUOT is returned.
179 179
180 (*) There's a system call interface by which userspace programs can create 180 (*) There's a system call interface by which userspace programs can create and
181 and manipulate keys and keyrings. 181 manipulate keys and keyrings.
182 182
183 (*) There's a kernel interface by which services can register types and 183 (*) There's a kernel interface by which services can register types and search
184 search for keys. 184 for keys.
185 185
186 (*) There's a way for the a search done from the kernel to call back to 186 (*) There's a way for the a search done from the kernel to call back to
187 userspace to request a key that can't be found in a process's keyrings. 187 userspace to request a key that can't be found in a process's keyrings.
@@ -194,9 +194,9 @@ The key service provides a number of features besides keys:
194KEY ACCESS PERMISSIONS 194KEY ACCESS PERMISSIONS
195====================== 195======================
196 196
197Keys have an owner user ID, a group access ID, and a permissions mask. The 197Keys have an owner user ID, a group access ID, and a permissions mask. The mask
198mask has up to eight bits each for user, group and other access. Only five of 198has up to eight bits each for user, group and other access. Only five of each
199each set of eight bits are defined. These permissions granted are: 199set of eight bits are defined. These permissions granted are:
200 200
201 (*) View 201 (*) View
202 202
@@ -210,8 +210,8 @@ each set of eight bits are defined. These permissions granted are:
210 210
211 (*) Write 211 (*) Write
212 212
213 This permits a key's payload to be instantiated or updated, or it allows 213 This permits a key's payload to be instantiated or updated, or it allows a
214 a link to be added to or removed from a keyring. 214 link to be added to or removed from a keyring.
215 215
216 (*) Search 216 (*) Search
217 217
@@ -238,8 +238,8 @@ about the status of the key service:
238 (*) /proc/keys 238 (*) /proc/keys
239 239
240 This lists all the keys on the system, giving information about their 240 This lists all the keys on the system, giving information about their
241 type, description and permissions. The payload of the key is not 241 type, description and permissions. The payload of the key is not available
242 available this way: 242 this way:
243 243
244 SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY 244 SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
245 00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4 245 00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4
@@ -318,21 +318,21 @@ The main syscalls are:
318 If a key of the same type and description as that proposed already exists 318 If a key of the same type and description as that proposed already exists
319 in the keyring, this will try to update it with the given payload, or it 319 in the keyring, this will try to update it with the given payload, or it
320 will return error EEXIST if that function is not supported by the key 320 will return error EEXIST if that function is not supported by the key
321 type. The process must also have permission to write to the key to be 321 type. The process must also have permission to write to the key to be able
322 able to update it. The new key will have all user permissions granted and 322 to update it. The new key will have all user permissions granted and no
323 no group or third party permissions. 323 group or third party permissions.
324 324
325 Otherwise, this will attempt to create a new key of the specified type 325 Otherwise, this will attempt to create a new key of the specified type and
326 and description, and to instantiate it with the supplied payload and 326 description, and to instantiate it with the supplied payload and attach it
327 attach it to the keyring. In this case, an error will be generated if the 327 to the keyring. In this case, an error will be generated if the process
328 process does not have permission to write to the keyring. 328 does not have permission to write to the keyring.
329 329
330 The payload is optional, and the pointer can be NULL if not required by 330 The payload is optional, and the pointer can be NULL if not required by
331 the type. The payload is plen in size, and plen can be zero for an empty 331 the type. The payload is plen in size, and plen can be zero for an empty
332 payload. 332 payload.
333 333
334 A new keyring can be generated by setting type "keyring", the keyring 334 A new keyring can be generated by setting type "keyring", the keyring name
335 name as the description (or NULL) and setting the payload to NULL. 335 as the description (or NULL) and setting the payload to NULL.
336 336
337 User defined keys can be created by specifying type "user". It is 337 User defined keys can be created by specifying type "user". It is
338 recommended that a user defined key's description by prefixed with a type 338 recommended that a user defined key's description by prefixed with a type
@@ -369,9 +369,9 @@ The keyctl syscall functions are:
369 key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id, 369 key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id,
370 int create); 370 int create);
371 371
372 The special key specified by "id" is looked up (with the key being 372 The special key specified by "id" is looked up (with the key being created
373 created if necessary) and the ID of the key or keyring thus found is 373 if necessary) and the ID of the key or keyring thus found is returned if
374 returned if it exists. 374 it exists.
375 375
376 If the key does not yet exist, the key will be created if "create" is 376 If the key does not yet exist, the key will be created if "create" is
377 non-zero; and the error ENOKEY will be returned if "create" is zero. 377 non-zero; and the error ENOKEY will be returned if "create" is zero.
@@ -402,8 +402,8 @@ The keyctl syscall functions are:
402 402
403 This will try to update the specified key with the given payload, or it 403 This will try to update the specified key with the given payload, or it
404 will return error EOPNOTSUPP if that function is not supported by the key 404 will return error EOPNOTSUPP if that function is not supported by the key
405 type. The process must also have permission to write to the key to be 405 type. The process must also have permission to write to the key to be able
406 able to update it. 406 to update it.
407 407
408 The payload is of length plen, and may be absent or empty as for 408 The payload is of length plen, and may be absent or empty as for
409 add_key(). 409 add_key().
@@ -422,8 +422,8 @@ The keyctl syscall functions are:
422 422
423 long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid); 423 long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid);
424 424
425 This function permits a key's owner and group ID to be changed. Either 425 This function permits a key's owner and group ID to be changed. Either one
426 one of uid or gid can be set to -1 to suppress that change. 426 of uid or gid can be set to -1 to suppress that change.
427 427
428 Only the superuser can change a key's owner to something other than the 428 Only the superuser can change a key's owner to something other than the
429 key's current owner. Similarly, only the superuser can change a key's 429 key's current owner. Similarly, only the superuser can change a key's
@@ -484,12 +484,12 @@ The keyctl syscall functions are:
484 484
485 long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key); 485 long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key);
486 486
487 This function creates a link from the keyring to the key. The process 487 This function creates a link from the keyring to the key. The process must
488 must have write permission on the keyring and must have link permission 488 have write permission on the keyring and must have link permission on the
489 on the key. 489 key.
490 490
491 Should the keyring not be a keyring, error ENOTDIR will result; and if 491 Should the keyring not be a keyring, error ENOTDIR will result; and if the
492 the keyring is full, error ENFILE will result. 492 keyring is full, error ENFILE will result.
493 493
494 The link procedure checks the nesting of the keyrings, returning ELOOP if 494 The link procedure checks the nesting of the keyrings, returning ELOOP if
495 it appears to deep or EDEADLK if the link would introduce a cycle. 495 it appears to deep or EDEADLK if the link would introduce a cycle.
@@ -503,8 +503,8 @@ The keyctl syscall functions are:
503 specified key, and removes it if found. Subsequent links to that key are 503 specified key, and removes it if found. Subsequent links to that key are
504 ignored. The process must have write permission on the keyring. 504 ignored. The process must have write permission on the keyring.
505 505
506 If the keyring is not a keyring, error ENOTDIR will result; and if the 506 If the keyring is not a keyring, error ENOTDIR will result; and if the key
507 key is not present, error ENOENT will be the result. 507 is not present, error ENOENT will be the result.
508 508
509 509
510 (*) Search a keyring tree for a key: 510 (*) Search a keyring tree for a key:
@@ -513,9 +513,9 @@ The keyctl syscall functions are:
513 const char *type, const char *description, 513 const char *type, const char *description,
514 key_serial_t dest_keyring); 514 key_serial_t dest_keyring);
515 515
516 This searches the keyring tree headed by the specified keyring until a 516 This searches the keyring tree headed by the specified keyring until a key
517 key is found that matches the type and description criteria. Each keyring 517 is found that matches the type and description criteria. Each keyring is
518 is checked for keys before recursion into its children occurs. 518 checked for keys before recursion into its children occurs.
519 519
520 The process must have search permission on the top level keyring, or else 520 The process must have search permission on the top level keyring, or else
521 error EACCES will result. Only keyrings that the process has search 521 error EACCES will result. Only keyrings that the process has search
@@ -549,8 +549,8 @@ The keyctl syscall functions are:
549 As much of the data as can be fitted into the buffer will be copied to 549 As much of the data as can be fitted into the buffer will be copied to
550 userspace if the buffer pointer is not NULL. 550 userspace if the buffer pointer is not NULL.
551 551
552 On a successful return, the function will always return the amount of 552 On a successful return, the function will always return the amount of data
553 data available rather than the amount copied. 553 available rather than the amount copied.
554 554
555 555
556 (*) Instantiate a partially constructed key. 556 (*) Instantiate a partially constructed key.
@@ -568,8 +568,8 @@ The keyctl syscall functions are:
568 it, and the key must be uninstantiated. 568 it, and the key must be uninstantiated.
569 569
570 If a keyring is specified (non-zero), the key will also be linked into 570 If a keyring is specified (non-zero), the key will also be linked into
571 that keyring, however all the constraints applying in KEYCTL_LINK apply 571 that keyring, however all the constraints applying in KEYCTL_LINK apply in
572 in this case too. 572 this case too.
573 573
574 The payload and plen arguments describe the payload data as for add_key(). 574 The payload and plen arguments describe the payload data as for add_key().
575 575
@@ -587,8 +587,39 @@ The keyctl syscall functions are:
587 it, and the key must be uninstantiated. 587 it, and the key must be uninstantiated.
588 588
589 If a keyring is specified (non-zero), the key will also be linked into 589 If a keyring is specified (non-zero), the key will also be linked into
590 that keyring, however all the constraints applying in KEYCTL_LINK apply 590 that keyring, however all the constraints applying in KEYCTL_LINK apply in
591 in this case too. 591 this case too.
592
593
594 (*) Set the default request-key destination keyring.
595
596 long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);
597
598 This sets the default keyring to which implicitly requested keys will be
599 attached for this thread. reqkey_defl should be one of these constants:
600
601 CONSTANT VALUE NEW DEFAULT KEYRING
602 ====================================== ====== =======================
603 KEY_REQKEY_DEFL_NO_CHANGE -1 No change
604 KEY_REQKEY_DEFL_DEFAULT 0 Default[1]
605 KEY_REQKEY_DEFL_THREAD_KEYRING 1 Thread keyring
606 KEY_REQKEY_DEFL_PROCESS_KEYRING 2 Process keyring
607 KEY_REQKEY_DEFL_SESSION_KEYRING 3 Session keyring
608 KEY_REQKEY_DEFL_USER_KEYRING 4 User keyring
609 KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 User session keyring
610 KEY_REQKEY_DEFL_GROUP_KEYRING 6 Group keyring
611
612 The old default will be returned if successful and error EINVAL will be
613 returned if reqkey_defl is not one of the above values.
614
615 The default keyring can be overridden by the keyring indicated to the
616 request_key() system call.
617
618 Note that this setting is inherited across fork/exec.
619
620 [1] The default default is: the thread keyring if there is one, otherwise
621 the process keyring if there is one, otherwise the session keyring if
622 there is one, otherwise the user default session keyring.
592 623
593 624
594=============== 625===============
@@ -601,17 +632,14 @@ be broken down into two areas: keys and key types.
601Dealing with keys is fairly straightforward. Firstly, the kernel service 632Dealing with keys is fairly straightforward. Firstly, the kernel service
602registers its type, then it searches for a key of that type. It should retain 633registers its type, then it searches for a key of that type. It should retain
603the key as long as it has need of it, and then it should release it. For a 634the key as long as it has need of it, and then it should release it. For a
604filesystem or device file, a search would probably be performed during the 635filesystem or device file, a search would probably be performed during the open
605open call, and the key released upon close. How to deal with conflicting keys 636call, and the key released upon close. How to deal with conflicting keys due to
606due to two different users opening the same file is left to the filesystem 637two different users opening the same file is left to the filesystem author to
607author to solve. 638solve.
608 639
609When accessing a key's payload data, key->lock should be at least read locked, 640When accessing a key's payload contents, certain precautions must be taken to
610or else the data may be changed by an update being performed from userspace 641prevent access vs modification races. See the section "Notes on accessing
611whilst the driver or filesystem is trying to access it. If no update method is 642payload contents" for more information.
612supplied, then the key's payload may be accessed without holding a lock as
613there is no way to change it, provided it can be guaranteed that the key's
614type definition won't go away.
615 643
616(*) To search for a key, call: 644(*) To search for a key, call:
617 645
@@ -629,6 +657,9 @@ type definition won't go away.
629 Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be 657 Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
630 returned. 658 returned.
631 659
660 If successful, the key will have been attached to the default keyring for
661 implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
662
632 663
633(*) When it is no longer required, the key should be released using: 664(*) When it is no longer required, the key should be released using:
634 665
@@ -690,6 +721,54 @@ type definition won't go away.
690 void unregister_key_type(struct key_type *type); 721 void unregister_key_type(struct key_type *type);
691 722
692 723
724===================================
725NOTES ON ACCESSING PAYLOAD CONTENTS
726===================================
727
728The simplest payload is just a number in key->payload.value. In this case,
729there's no need to indulge in RCU or locking when accessing the payload.
730
731More complex payload contents must be allocated and a pointer to them set in
732key->payload.data. One of the following ways must be selected to access the
733data:
734
735 (1) Unmodifyable key type.
736
737 If the key type does not have a modify method, then the key's payload can
738 be accessed without any form of locking, provided that it's known to be
739 instantiated (uninstantiated keys cannot be "found").
740
741 (2) The key's semaphore.
742
743 The semaphore could be used to govern access to the payload and to control
744 the payload pointer. It must be write-locked for modifications and would
745 have to be read-locked for general access. The disadvantage of doing this
746 is that the accessor may be required to sleep.
747
748 (3) RCU.
749
750 RCU must be used when the semaphore isn't already held; if the semaphore
751 is held then the contents can't change under you unexpectedly as the
752 semaphore must still be used to serialise modifications to the key. The
753 key management code takes care of this for the key type.
754
755 However, this means using:
756
757 rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock()
758
759 to read the pointer, and:
760
761 rcu_dereference() ... rcu_assign_pointer() ... call_rcu()
762
763 to set the pointer and dispose of the old contents after a grace period.
764 Note that only the key type should ever modify a key's payload.
765
766 Furthermore, an RCU controlled payload must hold a struct rcu_head for the
767 use of call_rcu() and, if the payload is of variable size, the length of
768 the payload. key->datalen cannot be relied upon to be consistent with the
769 payload just dereferenced if the key's semaphore is not held.
770
771
693=================== 772===================
694DEFINING A KEY TYPE 773DEFINING A KEY TYPE
695=================== 774===================
@@ -717,15 +796,15 @@ The structure has a number of fields, some of which are mandatory:
717 796
718 int key_payload_reserve(struct key *key, size_t datalen); 797 int key_payload_reserve(struct key *key, size_t datalen);
719 798
720 With the revised data length. Error EDQUOT will be returned if this is 799 With the revised data length. Error EDQUOT will be returned if this is not
721 not viable. 800 viable.
722 801
723 802
724 (*) int (*instantiate)(struct key *key, const void *data, size_t datalen); 803 (*) int (*instantiate)(struct key *key, const void *data, size_t datalen);
725 804
726 This method is called to attach a payload to a key during construction. 805 This method is called to attach a payload to a key during construction.
727 The payload attached need not bear any relation to the data passed to 806 The payload attached need not bear any relation to the data passed to this
728 this function. 807 function.
729 808
730 If the amount of data attached to the key differs from the size in 809 If the amount of data attached to the key differs from the size in
731 keytype->def_datalen, then key_payload_reserve() should be called. 810 keytype->def_datalen, then key_payload_reserve() should be called.
@@ -734,38 +813,47 @@ The structure has a number of fields, some of which are mandatory:
734 The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents 813 The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
735 anything else from gaining access to the key. 814 anything else from gaining access to the key.
736 815
737 This method may sleep if it wishes. 816 It is safe to sleep in this method.
738 817
739 818
740 (*) int (*duplicate)(struct key *key, const struct key *source); 819 (*) int (*duplicate)(struct key *key, const struct key *source);
741 820
742 If this type of key can be duplicated, then this method should be 821 If this type of key can be duplicated, then this method should be
743 provided. It is called to copy the payload attached to the source into 822 provided. It is called to copy the payload attached to the source into the
744 the new key. The data length on the new key will have been updated and 823 new key. The data length on the new key will have been updated and the
745 the quota adjusted already. 824 quota adjusted already.
746 825
747 This method will be called with the source key's semaphore read-locked to 826 This method will be called with the source key's semaphore read-locked to
748 prevent its payload from being changed. It is safe to sleep here. 827 prevent its payload from being changed, thus RCU constraints need not be
828 applied to the source key.
829
830 This method does not have to lock the destination key in order to attach a
831 payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags
832 prevents anything else from gaining access to the key.
833
834 It is safe to sleep in this method.
749 835
750 836
751 (*) int (*update)(struct key *key, const void *data, size_t datalen); 837 (*) int (*update)(struct key *key, const void *data, size_t datalen);
752 838
753 If this type of key can be updated, then this method should be 839 If this type of key can be updated, then this method should be provided.
754 provided. It is called to update a key's payload from the blob of data 840 It is called to update a key's payload from the blob of data provided.
755 provided.
756 841
757 key_payload_reserve() should be called if the data length might change 842 key_payload_reserve() should be called if the data length might change
758 before any changes are actually made. Note that if this succeeds, the 843 before any changes are actually made. Note that if this succeeds, the type
759 type is committed to changing the key because it's already been altered, 844 is committed to changing the key because it's already been altered, so all
760 so all memory allocation must be done first. 845 memory allocation must be done first.
846
847 The key will have its semaphore write-locked before this method is called,
848 but this only deters other writers; any changes to the key's payload must
849 be made under RCU conditions, and call_rcu() must be used to dispose of
850 the old payload.
761 851
762 key_payload_reserve() should be called with the key->lock write locked, 852 key_payload_reserve() should be called before the changes are made, but
763 and the changes to the key's attached payload should be made before the 853 after all allocations and other potentially failing function calls are
764 key is locked. 854 made.
765 855
766 The key will have its semaphore write-locked before this method is 856 It is safe to sleep in this method.
767 called. Any changes to the key should be made with the key's rwlock
768 write-locked also. It is safe to sleep here.
769 857
770 858
771 (*) int (*match)(const struct key *key, const void *desc); 859 (*) int (*match)(const struct key *key, const void *desc);
@@ -782,12 +870,12 @@ The structure has a number of fields, some of which are mandatory:
782 870
783 (*) void (*destroy)(struct key *key); 871 (*) void (*destroy)(struct key *key);
784 872
785 This method is optional. It is called to discard the payload data on a 873 This method is optional. It is called to discard the payload data on a key
786 key when it is being destroyed. 874 when it is being destroyed.
787 875
788 This method does not need to lock the key; it can consider the key as 876 This method does not need to lock the key to access the payload; it can
789 being inaccessible. Note that the key's type may have changed before this 877 consider the key as being inaccessible at this time. Note that the key's
790 function is called. 878 type may have been changed before this function is called.
791 879
792 It is not safe to sleep in this method; the caller may hold spinlocks. 880 It is not safe to sleep in this method; the caller may hold spinlocks.
793 881
@@ -797,26 +885,31 @@ The structure has a number of fields, some of which are mandatory:
797 This method is optional. It is called during /proc/keys reading to 885 This method is optional. It is called during /proc/keys reading to
798 summarise a key's description and payload in text form. 886 summarise a key's description and payload in text form.
799 887
800 This method will be called with the key's rwlock read-locked. This will 888 This method will be called with the RCU read lock held. rcu_dereference()
801 prevent the key's payload and state changing; also the description should 889 should be used to read the payload pointer if the payload is to be
802 not change. This also means it is not safe to sleep in this method. 890 accessed. key->datalen cannot be trusted to stay consistent with the
891 contents of the payload.
892
893 The description will not change, though the key's state may.
894
895 It is not safe to sleep in this method; the RCU read lock is held by the
896 caller.
803 897
804 898
805 (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen); 899 (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen);
806 900
807 This method is optional. It is called by KEYCTL_READ to translate the 901 This method is optional. It is called by KEYCTL_READ to translate the
808 key's payload into something a blob of data for userspace to deal 902 key's payload into something a blob of data for userspace to deal with.
809 with. Ideally, the blob should be in the same format as that passed in to 903 Ideally, the blob should be in the same format as that passed in to the
810 the instantiate and update methods. 904 instantiate and update methods.
811 905
812 If successful, the blob size that could be produced should be returned 906 If successful, the blob size that could be produced should be returned
813 rather than the size copied. 907 rather than the size copied.
814 908
815 This method will be called with the key's semaphore read-locked. This 909 This method will be called with the key's semaphore read-locked. This will
816 will prevent the key's payload changing. It is not necessary to also 910 prevent the key's payload changing. It is not necessary to use RCU locking
817 read-lock key->lock when accessing the key's payload. It is safe to sleep 911 when accessing the key's payload. It is safe to sleep in this method, such
818 in this method, such as might happen when the userspace buffer is 912 as might happen when the userspace buffer is accessed.
819 accessed.
820 913
821 914
822============================ 915============================
@@ -853,8 +946,8 @@ If it returns with the key remaining in the unconstructed state, the key will
853be marked as being negative, it will be added to the session keyring, and an 946be marked as being negative, it will be added to the session keyring, and an
854error will be returned to the key requestor. 947error will be returned to the key requestor.
855 948
856Supplementary information may be provided from whoever or whatever invoked 949Supplementary information may be provided from whoever or whatever invoked this
857this service. This will be passed as the <callout_info> parameter. If no such 950service. This will be passed as the <callout_info> parameter. If no such
858information was made available, then "-" will be passed as this parameter 951information was made available, then "-" will be passed as this parameter
859instead. 952instead.
860 953
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index a2c893a7475d..ab65714d95fc 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -304,57 +304,6 @@ tcp_low_latency - BOOLEAN
304 changed would be a Beowulf compute cluster. 304 changed would be a Beowulf compute cluster.
305 Default: 0 305 Default: 0
306 306
307tcp_westwood - BOOLEAN
308 Enable TCP Westwood+ congestion control algorithm.
309 TCP Westwood+ is a sender-side only modification of the TCP Reno
310 protocol stack that optimizes the performance of TCP congestion
311 control. It is based on end-to-end bandwidth estimation to set
312 congestion window and slow start threshold after a congestion
313 episode. Using this estimation, TCP Westwood+ adaptively sets a
314 slow start threshold and a congestion window which takes into
315 account the bandwidth used at the time congestion is experienced.
316 TCP Westwood+ significantly increases fairness wrt TCP Reno in
317 wired networks and throughput over wireless links.
318 Default: 0
319
320tcp_vegas_cong_avoid - BOOLEAN
321 Enable TCP Vegas congestion avoidance algorithm.
322 TCP Vegas is a sender-side only change to TCP that anticipates
323 the onset of congestion by estimating the bandwidth. TCP Vegas
324 adjusts the sending rate by modifying the congestion
325 window. TCP Vegas should provide less packet loss, but it is
326 not as aggressive as TCP Reno.
327 Default:0
328
329tcp_bic - BOOLEAN
330 Enable BIC TCP congestion control algorithm.
331 BIC-TCP is a sender-side only change that ensures a linear RTT
332 fairness under large windows while offering both scalability and
333 bounded TCP-friendliness. The protocol combines two schemes
334 called additive increase and binary search increase. When the
335 congestion window is large, additive increase with a large
336 increment ensures linear RTT fairness as well as good
337 scalability. Under small congestion windows, binary search
338 increase provides TCP friendliness.
339 Default: 0
340
341tcp_bic_low_window - INTEGER
342 Sets the threshold window (in packets) where BIC TCP starts to
343 adjust the congestion window. Below this threshold BIC TCP behaves
344 the same as the default TCP Reno.
345 Default: 14
346
347tcp_bic_fast_convergence - BOOLEAN
348 Forces BIC TCP to more quickly respond to changes in congestion
349 window. Allows two flows sharing the same connection to converge
350 more rapidly.
351 Default: 1
352
353tcp_default_win_scale - INTEGER
354 Sets the minimum window scale TCP will negotiate for on all
355 conections.
356 Default: 7
357
358tcp_tso_win_divisor - INTEGER 307tcp_tso_win_divisor - INTEGER
359 This allows control over what percentage of the congestion window 308 This allows control over what percentage of the congestion window
360 can be consumed by a single TSO frame. 309 can be consumed by a single TSO frame.
@@ -368,6 +317,11 @@ tcp_frto - BOOLEAN
368 where packet loss is typically due to random radio interference 317 where packet loss is typically due to random radio interference
369 rather than intermediate router congestion. 318 rather than intermediate router congestion.
370 319
320tcp_congestion_control - STRING
321 Set the congestion control algorithm to be used for new
322 connections. The algorithm "reno" is always available, but
323 additional choices may be available based on kernel configuration.
324
371somaxconn - INTEGER 325somaxconn - INTEGER
372 Limit of socket listen() backlog, known in userspace as SOMAXCONN. 326 Limit of socket listen() backlog, known in userspace as SOMAXCONN.
373 Defaults to 128. See also tcp_max_syn_backlog for additional tuning 327 Defaults to 128. See also tcp_max_syn_backlog for additional tuning
diff --git a/Documentation/networking/tcp.txt b/Documentation/networking/tcp.txt
index 71749007091e..0fa300425575 100644
--- a/Documentation/networking/tcp.txt
+++ b/Documentation/networking/tcp.txt
@@ -1,5 +1,72 @@
1How the new TCP output machine [nyi] works. 1TCP protocol
2============
3
4Last updated: 21 June 2005
5
6Contents
7========
8
9- Congestion control
10- How the new TCP output machine [nyi] works
11
12Congestion control
13==================
14
15The following variables are used in the tcp_sock for congestion control:
16snd_cwnd The size of the congestion window
17snd_ssthresh Slow start threshold. We are in slow start if
18 snd_cwnd is less than this.
19snd_cwnd_cnt A counter used to slow down the rate of increase
20 once we exceed slow start threshold.
21snd_cwnd_clamp This is the maximum size that snd_cwnd can grow to.
22snd_cwnd_stamp Timestamp for when congestion window last validated.
23snd_cwnd_used Used as a highwater mark for how much of the
24 congestion window is in use. It is used to adjust
25 snd_cwnd down when the link is limited by the
26 application rather than the network.
27
28As of 2.6.13, Linux supports pluggable congestion control algorithms.
29A congestion control mechanism can be registered through functions in
30tcp_cong.c. The functions used by the congestion control mechanism are
31registered via passing a tcp_congestion_ops struct to
32tcp_register_congestion_control. As a minimum name, ssthresh,
33cong_avoid, min_cwnd must be valid.
2 34
35Private data for a congestion control mechanism is stored in tp->ca_priv.
36tcp_ca(tp) returns a pointer to this space. This is preallocated space - it
37is important to check the size of your private data will fit this space, or
38alternatively space could be allocated elsewhere and a pointer to it could
39be stored here.
40
41There are three kinds of congestion control algorithms currently: The
42simplest ones are derived from TCP reno (highspeed, scalable) and just
43provide an alternative the congestion window calculation. More complex
44ones like BIC try to look at other events to provide better
45heuristics. There are also round trip time based algorithms like
46Vegas and Westwood+.
47
48Good TCP congestion control is a complex problem because the algorithm
49needs to maintain fairness and performance. Please review current
50research and RFC's before developing new modules.
51
52The method that is used to determine which congestion control mechanism is
53determined by the setting of the sysctl net.ipv4.tcp_congestion_control.
54The default congestion control will be the last one registered (LIFO);
55so if you built everything as modules. the default will be reno. If you
56build with the default's from Kconfig, then BIC will be builtin (not a module)
57and it will end up the default.
58
59If you really want a particular default value then you will need
60to set it with the sysctl. If you use a sysctl, the module will be autoloaded
61if needed and you will get the expected protocol. If you ask for an
62unknown congestion method, then the sysctl attempt will fail.
63
64If you remove a tcp congestion control module, then you will get the next
65available one. Since reno can not be built as a module, and can not be
66deleted, it will always be available.
67
68How the new TCP output machine [nyi] works.
69===========================================
3 70
4Data is kept on a single queue. The skb->users flag tells us if the frame is 71Data is kept on a single queue. The skb->users flag tells us if the frame is
5one that has been queued already. To add a frame we throw it on the end. Ack 72one that has been queued already. To add a frame we throw it on the end. Ack
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 35159176997b..9f11d36a8c10 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -49,6 +49,7 @@ show up in /proc/sys/kernel:
49- shmmax [ sysv ipc ] 49- shmmax [ sysv ipc ]
50- shmmni 50- shmmni
51- stop-a [ SPARC only ] 51- stop-a [ SPARC only ]
52- suid_dumpable
52- sysrq ==> Documentation/sysrq.txt 53- sysrq ==> Documentation/sysrq.txt
53- tainted 54- tainted
54- threads-max 55- threads-max
@@ -300,6 +301,25 @@ kernel. This value defaults to SHMMAX.
300 301
301============================================================== 302==============================================================
302 303
304suid_dumpable:
305
306This value can be used to query and set the core dump mode for setuid
307or otherwise protected/tainted binaries. The modes are
308
3090 - (default) - traditional behaviour. Any process which has changed
310 privilege levels or is execute only will not be dumped
3111 - (debug) - all processes dump core when possible. The core dump is
312 owned by the current user and no security is applied. This is
313 intended for system debugging situations only. Ptrace is unchecked.
3142 - (suidsafe) - any binary which normally would not be dumped is dumped
315 readable by root only. This allows the end user to remove
316 such a dump but not access it directly. For security reasons
317 core dumps in this mode will not overwrite one another or
318 other files. This mode is appropriate when adminstrators are
319 attempting to debug problems in a normal environment.
320
321==============================================================
322
303tainted: 323tainted:
304 324
305Non-zero if the kernel has been tainted. Numeric values, which 325Non-zero if the kernel has been tainted. Numeric values, which
diff --git a/Documentation/tty.txt b/Documentation/tty.txt
index 3958cf746dde..8ff7bc2a0811 100644
--- a/Documentation/tty.txt
+++ b/Documentation/tty.txt
@@ -22,7 +22,7 @@ copy of the structure. You must not re-register over the top of the line
22discipline even with the same data or your computer again will be eaten by 22discipline even with the same data or your computer again will be eaten by
23demons. 23demons.
24 24
25In order to remove a line discipline call tty_register_ldisc passing NULL. 25In order to remove a line discipline call tty_unregister_ldisc().
26In ancient times this always worked. In modern times the function will 26In ancient times this always worked. In modern times the function will
27return -EBUSY if the ldisc is currently in use. Since the ldisc referencing 27return -EBUSY if the ldisc is currently in use. Since the ldisc referencing
28code manages the module counts this should not usually be a concern. 28code manages the module counts this should not usually be a concern.
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index e46761c39e3f..aeeafec0594c 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -119,3 +119,17 @@ card=117 - NGS NGSTV+
119card=118 - LMLBT4 119card=118 - LMLBT4
120card=119 - Tekram M205 PRO 120card=119 - Tekram M205 PRO
121card=120 - Conceptronic CONTVFMi 121card=120 - Conceptronic CONTVFMi
122card=121 - Euresys Picolo Tetra
123card=122 - Spirit TV Tuner
124card=123 - AVerMedia AVerTV DVB-T 771
125card=124 - AverMedia AverTV DVB-T 761
126card=125 - MATRIX Vision Sigma-SQ
127card=126 - MATRIX Vision Sigma-SLC
128card=127 - APAC Viewcomp 878(AMAX)
129card=128 - DVICO FusionHDTV DVB-T Lite
130card=129 - V-Gear MyVCD
131card=130 - Super TV Tuner
132card=131 - Tibet Systems 'Progress DVR' CS16
133card=132 - Kodicom 4400R (master)
134card=133 - Kodicom 4400R (slave)
135card=134 - Adlink RTV24
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
new file mode 100644
index 000000000000..216f705495cc
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -0,0 +1,29 @@
1card=0 - UNKNOWN/GENERIC
2card=1 - Hauppauge WinTV 34xxx models
3card=2 - GDI Black Gold
4card=3 - PixelView
5card=4 - ATI TV Wonder Pro
6card=5 - Leadtek Winfast 2000XP Expert
7card=6 - AverTV Studio 303 (M126)
8card=7 - MSI TV-@nywhere Master
9card=8 - Leadtek Winfast DV2000
10card=9 - Leadtek PVR 2000
11card=10 - IODATA GV-VCP3/PCI
12card=11 - Prolink PlayTV PVR
13card=12 - ASUS PVR-416
14card=13 - MSI TV-@nywhere
15card=14 - KWorld/VStream XPert DVB-T
16card=15 - DVICO FusionHDTV DVB-T1
17card=16 - KWorld LTV883RF
18card=17 - DViCO - FusionHDTV 3 Gold
19card=18 - Hauppauge Nova-T DVB-T
20card=19 - Conexant DVB-T reference design
21card=20 - Provideo PV259
22card=21 - DVICO FusionHDTV DVB-T Plus
23card=22 - digitalnow DNTV Live! DVB-T
24card=23 - pcHDTV HD3000 HDTV
25card=24 - Hauppauge WinTV 28xxx (Roslyn) models
26card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
27card=26 - IODATA GV/BCTV7E
28card=27 - PixelView PlayTV Ultra Pro (Stereo)
29card=28 - DViCO - FusionHDTV 3 Gold-T
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index a6c82fa4de02..d5ed95d28500 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -20,16 +20,37 @@
20 19 -> Compro VideoMate TV [185b:c100] 20 19 -> Compro VideoMate TV [185b:c100]
21 20 -> Matrox CronosPlus [102B:48d0] 21 20 -> Matrox CronosPlus [102B:48d0]
22 21 -> 10MOONS PCI TV CAPTURE CARD [1131:2001] 22 21 -> 10MOONS PCI TV CAPTURE CARD [1131:2001]
23 22 -> Medion 2819/ AverMedia M156 [1461:a70b,1461:2115] 23 22 -> AverMedia M156 / Medion 2819 [1461:a70b]
24 23 -> BMK MPEX Tuner 24 23 -> BMK MPEX Tuner
25 24 -> KNC One TV-Station DVR [1894:a006] 25 24 -> KNC One TV-Station DVR [1894:a006]
26 25 -> ASUS TV-FM 7133 [1043:4843] 26 25 -> ASUS TV-FM 7133 [1043:4843]
27 26 -> Pinnacle PCTV Stereo (saa7134) [11bd:002b] 27 26 -> Pinnacle PCTV Stereo (saa7134) [11bd:002b]
28 27 -> Manli MuchTV M-TV002 28 27 -> Manli MuchTV M-TV002/Behold TV 403 FM
29 28 -> Manli MuchTV M-TV001 29 28 -> Manli MuchTV M-TV001/Behold TV 401
30 29 -> Nagase Sangyo TransGear 3000TV [1461:050c] 30 29 -> Nagase Sangyo TransGear 3000TV [1461:050c]
31 30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) [1019:4cb4] 31 30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) [1019:4cb4]
32 31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5] 32 31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5]
33 32 -> AVACS SmartTV 33 32 -> AVACS SmartTV
34 33 -> AVerMedia DVD EZMaker [1461:10ff] 34 33 -> AVerMedia DVD EZMaker [1461:10ff]
35 34 -> LifeView FlyTV Platinum33 mini [5168:0212] 35 34 -> Noval Prime TV 7133
36 35 -> AverMedia AverTV Studio 305 [1461:2115]
37 37 -> Items MuchTV Plus / IT-005
38 38 -> Terratec Cinergy 200 TV [153B:1152]
39 39 -> LifeView FlyTV Platinum Mini [5168:0212]
40 40 -> Compro VideoMate TV PVR/FM [185b:c100]
41 41 -> Compro VideoMate TV Gold+ [185b:c100]
42 42 -> Sabrent SBT-TVFM (saa7130)
43 43 -> :Zolid Xpert TV7134
44 44 -> Empire PCI TV-Radio LE
45 45 -> Avermedia AVerTV Studio 307 [1461:9715]
46 46 -> AVerMedia Cardbus TV/Radio [1461:d6ee]
47 47 -> Terratec Cinergy 400 mobile [153b:1162]
48 48 -> Terratec Cinergy 600 TV MK3 [153B:1158]
49 49 -> Compro VideoMate Gold+ Pal [185b:c200]
50 50 -> Pinnacle PCTV 300i DVB-T + PAL [11bd:002d]
51 51 -> ProVideo PV952 [1540:9524]
52 52 -> AverMedia AverTV/305 [1461:2108]
53 54 -> LifeView FlyTV Platinum FM [5168:0214,1489:0214]
54 55 -> LifeView FlyDVB-T DUO [5168:0306]
55 56 -> Avermedia AVerTV 307 [1461:a70a]
56 57 -> Avermedia AVerTV GO 007 FM [1461:f31f]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index f7bafe862ba0..aeb8df8ce890 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -44,3 +44,18 @@ tuner=42 - Philips 1236D ATSC/NTSC daul in
44tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F) 44tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F)
45tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant) 45tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
46tuner=45 - Microtune 4049 FM5 46tuner=45 - Microtune 4049 FM5
47tuner=46 - Panasonic VP27s/ENGE4324D
48tuner=47 - LG NTSC (TAPE series)
49tuner=48 - Tenna TNF 8831 BGFF)
50tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in
51tuner=50 - TCL 2002N
52tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
53tuner=52 - Thomson DDT 7610 (ATSC/NTSC)
54tuner=53 - Philips FQ1286
55tuner=54 - tda8290+75
56tuner=55 - LG PAL (TAPE series)
57tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
58tuner=57 - Philips FQ1236A MK4
59tuner=58 - Ymec TVision TVF-8531MF
60tuner=59 - Ymec TVision TVF-5533MF
61tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
diff --git a/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
new file mode 100644
index 000000000000..93fec32a1188
--- /dev/null
+++ b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
@@ -0,0 +1,54 @@
1The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting.
2
3GPIO0 GPIO1
4 0 0 TV Audio
5 1 0 FM radio
6 0 1 Line-In
7 1 1 Mono tuner bypass or CD passthru (tuner specific)
8
9GPIO 16(i believe) is tied to the IR port (if present).
10
11------------------------------------------------------------------------------------
12
13>From the data sheet:
14 Register 24'h20004 PCI Interrupt Status
15 bit [18] IR_SMP_INT Set when 32 input samples have been collected over
16 gpio[16] pin into GP_SAMPLE register.
17
18What's missing from the data sheet:
19
20Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5
21compat remote)
22set register 0x35C050 to 0xa80a80
23
24enable sampling
25set register 0x35C054 to 0x5
26
27Of course, enable the IRQ bit 18 in the interrupt mask register .(and
28provide for a handler)
29
30GP_SAMPLE register is at 0x35C058
31
32Bits are then right shifted into the GP_SAMPLE register at the specified
33rate; you get an interrupt when a full DWORD is recieved.
34You need to recover the actual RC5 bits out of the (oversampled) IR sensor
35bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data) An
36actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
37
38I'm pretty sure when no IR signal is present the receiver is always in a
39marking state(1); but stray light, etc can cause intermittent noise values
40as well. Remember, this is a free running sample of the IR receiver state
41over time, so don't assume any sample starts at any particular place.
42
43http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf
44This data sheet (google search) seems to have a lovely description of the
45RC5 basics
46
47http://users.pandora.be/nenya/electronics/rc5/ and more data
48
49http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt
50and even a reference to how to decode a bi-phase data stream.
51
52http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm
53still more info
54
diff --git a/Documentation/video4linux/lifeview.txt b/Documentation/video4linux/lifeview.txt
new file mode 100644
index 000000000000..b07ea79c2b7e
--- /dev/null
+++ b/Documentation/video4linux/lifeview.txt
@@ -0,0 +1,42 @@
1collecting data about the lifeview models and the config coding on
2gpio pins 0-9 ...
3==================================================================
4
5bt878:
6 LR50 rev. Q ("PARTS: 7031505116), Tuner wurde als Nr. 5 erkannt, Eingänge
7 SVideo, TV, Composite, Audio, Remote. CP9..1=100001001 (1: 0-Ohm-Widerstand
8 gegen GND unbestückt; 0: bestückt)
9
10------------------------------------------------------------------------------
11
12saa7134:
13 /* LifeView FlyTV Platinum FM (LR214WF) */
14 /* "Peter Missel <peter.missel@onlinehome.de> */
15 .name = "LifeView FlyTV Platinum FM",
16 /* GP27 MDT2005 PB4 pin 10 */
17 /* GP26 MDT2005 PB3 pin 9 */
18 /* GP25 MDT2005 PB2 pin 8 */
19 /* GP23 MDT2005 PB1 pin 7 */
20 /* GP22 MDT2005 PB0 pin 6 */
21 /* GP21 MDT2005 PB5 pin 11 */
22 /* GP20 MDT2005 PB6 pin 12 */
23 /* GP19 MDT2005 PB7 pin 13 */
24 /* nc MDT2005 PA3 pin 2 */
25 /* Remote MDT2005 PA2 pin 1 */
26 /* GP18 MDT2005 PA1 pin 18 */
27 /* nc MDT2005 PA0 pin 17 strap low */
28
29 /* GP17 Strap "GP7"=High */
30 /* GP16 Strap "GP6"=High
31 0=Radio 1=TV
32 Drives SA630D ENCH1 and HEF4052 A1 pins
33 to do FM radio through SIF input */
34 /* GP15 nc */
35 /* GP14 nc */
36 /* GP13 nc */
37 /* GP12 Strap "GP5" = High */
38 /* GP11 Strap "GP4" = High */
39 /* GP10 Strap "GP3" = High */
40 /* GP09 Strap "GP2" = Low */
41 /* GP08 Strap "GP1" = Low */
42 /* GP07.00 nc */
diff --git a/Documentation/video4linux/not-in-cx2388x-datasheet.txt b/Documentation/video4linux/not-in-cx2388x-datasheet.txt
new file mode 100644
index 000000000000..96b638b5ba1d
--- /dev/null
+++ b/Documentation/video4linux/not-in-cx2388x-datasheet.txt
@@ -0,0 +1,37 @@
1=================================================================================
2MO_OUTPUT_FORMAT (0x310164)
3
4 Previous default from DScaler: 0x1c1f0008
5 Digit 8: 31-28
6 28: PREVREMOD = 1
7
8 Digit 7: 27-24 (0xc = 12 = b1100 )
9 27: COMBALT = 1
10 26: PAL_INV_PHASE
11 (DScaler apparently set this to 1, resulted in sucky picture)
12
13 Digits 6,5: 23-16
14 25-16: COMB_RANGE = 0x1f [default] (9 bits -> max 512)
15
16 Digit 4: 15-12
17 15: DISIFX = 0
18 14: INVCBF = 0
19 13: DISADAPT = 0
20 12: NARROWADAPT = 0
21
22 Digit 3: 11-8
23 11: FORCE2H
24 10: FORCEREMD
25 9: NCHROMAEN
26 8: NREMODEN
27
28 Digit 2: 7-4
29 7-6: YCORE
30 5-4: CCORE
31
32 Digit 1: 3-0
33 3: RANGE = 1
34 2: HACTEXT
35 1: HSFMT
36
37=================================================================================
diff --git a/MAINTAINERS b/MAINTAINERS
index 4d44824884ef..a07eeb411370 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -304,7 +304,7 @@ S: Maintained
304ARM/PT DIGITAL BOARD PORT 304ARM/PT DIGITAL BOARD PORT
305P: Stefan Eletzhofer 305P: Stefan Eletzhofer
306M: stefan.eletzhofer@eletztrick.de 306M: stefan.eletzhofer@eletztrick.de
307L: linux-arm-kernel@lists.arm.linux.org.uk 307L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
308W: http://www.arm.linux.org.uk/ 308W: http://www.arm.linux.org.uk/
309S: Maintained 309S: Maintained
310 310
@@ -317,21 +317,21 @@ S: Maintained
317ARM/STRONGARM110 PORT 317ARM/STRONGARM110 PORT
318P: Russell King 318P: Russell King
319M: rmk@arm.linux.org.uk 319M: rmk@arm.linux.org.uk
320L: linux-arm-kernel@lists.arm.linux.org.uk 320L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
321W: http://www.arm.linux.org.uk/ 321W: http://www.arm.linux.org.uk/
322S: Maintained 322S: Maintained
323 323
324ARM/S3C2410 ARM ARCHITECTURE 324ARM/S3C2410 ARM ARCHITECTURE
325P: Ben Dooks 325P: Ben Dooks
326M: ben-s3c2410@fluff.org 326M: ben-s3c2410@fluff.org
327L: linux-arm-kernel@lists.arm.linux.org.uk 327L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
328W: http://www.fluff.org/ben/linux/ 328W: http://www.fluff.org/ben/linux/
329S: Maintained 329S: Maintained
330 330
331ARM/S3C2440 ARM ARCHITECTURE 331ARM/S3C2440 ARM ARCHITECTURE
332P: Ben Dooks 332P: Ben Dooks
333M: ben-s3c2440@fluff.org 333M: ben-s3c2440@fluff.org
334L: linux-arm-kernel@lists.arm.linux.org.uk 334L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
335W: http://www.fluff.org/ben/linux/ 335W: http://www.fluff.org/ben/linux/
336S: Maintained 336S: Maintained
337 337
@@ -504,6 +504,13 @@ L: bonding-devel@lists.sourceforge.net
504W: http://sourceforge.net/projects/bonding/ 504W: http://sourceforge.net/projects/bonding/
505S: Supported 505S: Supported
506 506
507BROADBAND PROCESSOR ARCHITECTURE
508P: Arnd Bergmann
509M: arnd@arndb.de
510L: linuxppc64-dev@ozlabs.org
511W: http://linuxppc64.org
512S: Supported
513
507BTTV VIDEO4LINUX DRIVER 514BTTV VIDEO4LINUX DRIVER
508P: Gerd Knorr 515P: Gerd Knorr
509M: kraxel@bytesex.org 516M: kraxel@bytesex.org
@@ -1853,7 +1860,7 @@ S: Maintained
1853PXA2xx SUPPORT 1860PXA2xx SUPPORT
1854P: Nicolas Pitre 1861P: Nicolas Pitre
1855M: nico@cam.org 1862M: nico@cam.org
1856L: linux-arm-kernel@lists.arm.linux.org.uk 1863L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
1857S: Maintained 1864S: Maintained
1858 1865
1859QLOGIC QLA2XXX FC-SCSI DRIVER 1866QLOGIC QLA2XXX FC-SCSI DRIVER
@@ -2138,6 +2145,11 @@ W: http://tpmdd.sourceforge.net
2138L: tpmdd-devel@lists.sourceforge.net 2145L: tpmdd-devel@lists.sourceforge.net
2139S: Maintained 2146S: Maintained
2140 2147
2148TENSILICA XTENSA PORT (xtensa):
2149P: Chris Zankel
2150M: chris@zankel.net
2151S: Maintained
2152
2141UltraSPARC (sparc64): 2153UltraSPARC (sparc64):
2142P: David S. Miller 2154P: David S. Miller
2143M: davem@davemloft.net 2155M: davem@davemloft.net
@@ -2155,7 +2167,7 @@ SHARP LH SUPPORT (LH7952X & LH7A40X)
2155P: Marc Singer 2167P: Marc Singer
2156M: elf@buici.com 2168M: elf@buici.com
2157W: http://projects.buici.com/arm 2169W: http://projects.buici.com/arm
2158L: linux-arm-kernel@lists.arm.linux.org.uk 2170L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
2159S: Maintained 2171S: Maintained
2160 2172
2161SPARC (sparc32): 2173SPARC (sparc32):
diff --git a/Makefile b/Makefile
index 0d1e74d50067..fad349724e99 100644
--- a/Makefile
+++ b/Makefile
@@ -518,7 +518,7 @@ CFLAGS += $(call add-align,CONFIG_CC_ALIGN_LOOPS,-loops)
518CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps) 518CFLAGS += $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps)
519 519
520ifdef CONFIG_FRAME_POINTER 520ifdef CONFIG_FRAME_POINTER
521CFLAGS += -fno-omit-frame-pointer 521CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
522else 522else
523CFLAGS += -fomit-frame-pointer 523CFLAGS += -fomit-frame-pointer
524endif 524endif
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index f7c96635d3b4..c5739d6309df 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -509,7 +509,7 @@ config NR_CPUS
509 depends on SMP 509 depends on SMP
510 default "64" 510 default "64"
511 511
512config DISCONTIGMEM 512config ARCH_DISCONTIGMEM_ENABLE
513 bool "Discontiguous Memory Support (EXPERIMENTAL)" 513 bool "Discontiguous Memory Support (EXPERIMENTAL)"
514 depends on EXPERIMENTAL 514 depends on EXPERIMENTAL
515 help 515 help
@@ -518,6 +518,8 @@ config DISCONTIGMEM
518 or have huge holes in the physical address space for other reasons. 518 or have huge holes in the physical address space for other reasons.
519 See <file:Documentation/vm/numa> for more. 519 See <file:Documentation/vm/numa> for more.
520 520
521source "mm/Kconfig"
522
521config NUMA 523config NUMA
522 bool "NUMA Support (EXPERIMENTAL)" 524 bool "NUMA Support (EXPERIMENTAL)"
523 depends on DISCONTIGMEM 525 depends on DISCONTIGMEM
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index 5e39b7a7c8f4..6da9c3dbde44 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -96,7 +96,7 @@ CONFIG_ALPHA_CORE_AGP=y
96CONFIG_ALPHA_BROKEN_IRQ_MASK=y 96CONFIG_ALPHA_BROKEN_IRQ_MASK=y
97CONFIG_EISA=y 97CONFIG_EISA=y
98# CONFIG_SMP is not set 98# CONFIG_SMP is not set
99# CONFIG_DISCONTIGMEM is not set 99# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
100CONFIG_VERBOSE_MCHECK=y 100CONFIG_VERBOSE_MCHECK=y
101CONFIG_VERBOSE_MCHECK_ON=1 101CONFIG_VERBOSE_MCHECK_ON=1
102CONFIG_PCI_LEGACY_PROC=y 102CONFIG_PCI_LEGACY_PROC=y
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
index ba81c4422aaf..c7481d59b6df 100644
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -327,8 +327,6 @@ void __init mem_init(void)
327 extern char _text, _etext, _data, _edata; 327 extern char _text, _etext, _data, _edata;
328 extern char __init_begin, __init_end; 328 extern char __init_begin, __init_end;
329 unsigned long nid, i; 329 unsigned long nid, i;
330 struct page * lmem_map;
331
332 high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); 330 high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
333 331
334 reservedpages = 0; 332 reservedpages = 0;
@@ -338,10 +336,10 @@ void __init mem_init(void)
338 */ 336 */
339 totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); 337 totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
340 338
341 lmem_map = node_mem_map(nid);
342 pfn = NODE_DATA(nid)->node_start_pfn; 339 pfn = NODE_DATA(nid)->node_start_pfn;
343 for (i = 0; i < node_spanned_pages(nid); i++, pfn++) 340 for (i = 0; i < node_spanned_pages(nid); i++, pfn++)
344 if (page_is_ram(pfn) && PageReserved(lmem_map+i)) 341 if (page_is_ram(pfn) &&
342 PageReserved(nid_page_nr(nid, i)))
345 reservedpages++; 343 reservedpages++;
346 } 344 }
347 345
@@ -373,18 +371,18 @@ show_mem(void)
373 show_free_areas(); 371 show_free_areas();
374 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 372 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
375 for_each_online_node(nid) { 373 for_each_online_node(nid) {
376 struct page * lmem_map = node_mem_map(nid);
377 i = node_spanned_pages(nid); 374 i = node_spanned_pages(nid);
378 while (i-- > 0) { 375 while (i-- > 0) {
376 struct page *page = nid_page_nr(nid, i);
379 total++; 377 total++;
380 if (PageReserved(lmem_map+i)) 378 if (PageReserved(page))
381 reserved++; 379 reserved++;
382 else if (PageSwapCache(lmem_map+i)) 380 else if (PageSwapCache(page))
383 cached++; 381 cached++;
384 else if (!page_count(lmem_map+i)) 382 else if (!page_count(page))
385 free++; 383 free++;
386 else 384 else
387 shared += page_count(lmem_map + i) - 1; 385 shared += page_count(page) - 1;
388 } 386 }
389 } 387 }
390 printk("%ld pages of RAM\n",total); 388 printk("%ld pages of RAM\n",total);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ee8a9ad7bbd9..07ba77c19f6c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -346,7 +346,7 @@ config PREEMPT
346 Say Y here if you are building a kernel for a desktop, embedded 346 Say Y here if you are building a kernel for a desktop, embedded
347 or real-time system. Say N if you are unsure. 347 or real-time system. Say N if you are unsure.
348 348
349config DISCONTIGMEM 349config ARCH_DISCONTIGMEM_ENABLE
350 bool 350 bool
351 default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) 351 default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
352 help 352 help
@@ -355,6 +355,8 @@ config DISCONTIGMEM
355 or have huge holes in the physical address space for other reasons. 355 or have huge holes in the physical address space for other reasons.
356 See <file:Documentation/vm/numa> for more. 356 See <file:Documentation/vm/numa> for more.
357 357
358source "mm/Kconfig"
359
358config LEDS 360config LEDS
359 bool "Timer and CPU usage LEDs" 361 bool "Timer and CPU usage LEDs"
360 depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \ 362 depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
index 935bb27369e9..9f9bed207345 100644
--- a/arch/arm/boot/install.sh
+++ b/arch/arm/boot/install.sh
@@ -21,8 +21,8 @@
21# 21#
22 22
23# User may have a custom install script 23# User may have a custom install script
24if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi 24if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
25if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi 25if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
26 26
27if [ "$(basename $2)" = "zImage" ]; then 27if [ "$(basename $2)" = "zImage" ]; then
28# Compressed install 28# Compressed install
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 2a63fb277196..98b72ff38832 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,14 +1,13 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.12-rc1-bk2 3# Linux kernel version: 2.6.12-git4
4# Sun Mar 27 17:47:45 2005 4# Wed Jun 22 15:56:42 2005
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
8CONFIG_UID16=y 8CONFIG_UID16=y
9CONFIG_RWSEM_GENERIC_SPINLOCK=y 9CONFIG_RWSEM_GENERIC_SPINLOCK=y
10CONFIG_GENERIC_CALIBRATE_DELAY=y 10CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_GENERIC_IOMAP=y
12 11
13# 12#
14# Code maturity level options 13# Code maturity level options
@@ -17,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
17# CONFIG_CLEAN_COMPILE is not set 16# CONFIG_CLEAN_COMPILE is not set
18CONFIG_BROKEN=y 17CONFIG_BROKEN=y
19CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
20 20
21# 21#
22# General setup 22# General setup
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
35CONFIG_KALLSYMS=y 35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set 36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set 37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_PRINTK=y
39CONFIG_BUG=y
38CONFIG_BASE_FULL=y 40CONFIG_BASE_FULL=y
39CONFIG_FUTEX=y 41CONFIG_FUTEX=y
40CONFIG_EPOLL=y 42CONFIG_EPOLL=y
@@ -81,6 +83,7 @@ CONFIG_ARCH_S3C2410=y
81# CONFIG_ARCH_VERSATILE is not set 83# CONFIG_ARCH_VERSATILE is not set
82# CONFIG_ARCH_IMX is not set 84# CONFIG_ARCH_IMX is not set
83# CONFIG_ARCH_H720X is not set 85# CONFIG_ARCH_H720X is not set
86# CONFIG_ARCH_AAEC2000 is not set
84 87
85# 88#
86# S3C24XX Implementations 89# S3C24XX Implementations
@@ -134,6 +137,7 @@ CONFIG_CPU_TLB_V4WBI=y
134# 137#
135# Bus support 138# Bus support
136# 139#
140CONFIG_ISA_DMA_API=y
137 141
138# 142#
139# PCCARD (PCMCIA/CardBus) support 143# PCCARD (PCMCIA/CardBus) support
@@ -143,7 +147,9 @@ CONFIG_CPU_TLB_V4WBI=y
143# 147#
144# Kernel Features 148# Kernel Features
145# 149#
150# CONFIG_SMP is not set
146# CONFIG_PREEMPT is not set 151# CONFIG_PREEMPT is not set
152# CONFIG_DISCONTIGMEM is not set
147CONFIG_ALIGNMENT_TRAP=y 153CONFIG_ALIGNMENT_TRAP=y
148 154
149# 155#
@@ -297,7 +303,6 @@ CONFIG_PARPORT_1284=y
297# 303#
298# Block devices 304# Block devices
299# 305#
300# CONFIG_BLK_DEV_FD is not set
301# CONFIG_PARIDE is not set 306# CONFIG_PARIDE is not set
302# CONFIG_BLK_DEV_COW_COMMON is not set 307# CONFIG_BLK_DEV_COW_COMMON is not set
303CONFIG_BLK_DEV_LOOP=y 308CONFIG_BLK_DEV_LOOP=y
@@ -359,6 +364,7 @@ CONFIG_BLK_DEV_IDE_BAST=y
359# 364#
360# Fusion MPT device support 365# Fusion MPT device support
361# 366#
367# CONFIG_FUSION is not set
362 368
363# 369#
364# IEEE 1394 (FireWire) support 370# IEEE 1394 (FireWire) support
@@ -378,10 +384,11 @@ CONFIG_NET=y
378# Networking options 384# Networking options
379# 385#
380# CONFIG_PACKET is not set 386# CONFIG_PACKET is not set
381# CONFIG_NETLINK_DEV is not set
382CONFIG_UNIX=y 387CONFIG_UNIX=y
383# CONFIG_NET_KEY is not set 388# CONFIG_NET_KEY is not set
384CONFIG_INET=y 389CONFIG_INET=y
390CONFIG_IP_FIB_HASH=y
391# CONFIG_IP_FIB_TRIE is not set
385# CONFIG_IP_MULTICAST is not set 392# CONFIG_IP_MULTICAST is not set
386# CONFIG_IP_ADVANCED_ROUTER is not set 393# CONFIG_IP_ADVANCED_ROUTER is not set
387CONFIG_IP_PNP=y 394CONFIG_IP_PNP=y
@@ -443,8 +450,9 @@ CONFIG_NETDEVICES=y
443# Ethernet (10 or 100Mbit) 450# Ethernet (10 or 100Mbit)
444# 451#
445CONFIG_NET_ETHERNET=y 452CONFIG_NET_ETHERNET=y
446# CONFIG_MII is not set 453CONFIG_MII=m
447# CONFIG_SMC91X is not set 454# CONFIG_SMC91X is not set
455CONFIG_DM9000=m
448 456
449# 457#
450# Ethernet (1000 Mbit) 458# Ethernet (1000 Mbit)
@@ -521,7 +529,6 @@ CONFIG_SERIO_SERPORT=y
521CONFIG_SERIO_LIBPS2=y 529CONFIG_SERIO_LIBPS2=y
522# CONFIG_SERIO_RAW is not set 530# CONFIG_SERIO_RAW is not set
523# CONFIG_GAMEPORT is not set 531# CONFIG_GAMEPORT is not set
524CONFIG_SOUND_GAMEPORT=y
525 532
526# 533#
527# Character devices 534# Character devices
@@ -605,7 +612,6 @@ CONFIG_S3C2410_RTC=y
605# 612#
606# TPM devices 613# TPM devices
607# 614#
608# CONFIG_TCG_TPM is not set
609 615
610# 616#
611# I2C support 617# I2C support
@@ -654,6 +660,7 @@ CONFIG_SENSORS_LM78=m
654CONFIG_SENSORS_LM85=m 660CONFIG_SENSORS_LM85=m
655# CONFIG_SENSORS_LM87 is not set 661# CONFIG_SENSORS_LM87 is not set
656# CONFIG_SENSORS_LM90 is not set 662# CONFIG_SENSORS_LM90 is not set
663# CONFIG_SENSORS_LM92 is not set
657# CONFIG_SENSORS_MAX1619 is not set 664# CONFIG_SENSORS_MAX1619 is not set
658# CONFIG_SENSORS_PC87360 is not set 665# CONFIG_SENSORS_PC87360 is not set
659# CONFIG_SENSORS_SMSC47B397 is not set 666# CONFIG_SENSORS_SMSC47B397 is not set
@@ -665,6 +672,7 @@ CONFIG_SENSORS_LM85=m
665# 672#
666# Other I2C Chip support 673# Other I2C Chip support
667# 674#
675# CONFIG_SENSORS_DS1337 is not set
668CONFIG_SENSORS_EEPROM=m 676CONFIG_SENSORS_EEPROM=m
669# CONFIG_SENSORS_PCF8574 is not set 677# CONFIG_SENSORS_PCF8574 is not set
670# CONFIG_SENSORS_PCF8591 is not set 678# CONFIG_SENSORS_PCF8591 is not set
@@ -696,8 +704,10 @@ CONFIG_FB=y
696# CONFIG_FB_CFB_COPYAREA is not set 704# CONFIG_FB_CFB_COPYAREA is not set
697# CONFIG_FB_CFB_IMAGEBLIT is not set 705# CONFIG_FB_CFB_IMAGEBLIT is not set
698# CONFIG_FB_SOFT_CURSOR is not set 706# CONFIG_FB_SOFT_CURSOR is not set
707# CONFIG_FB_MACMODES is not set
699CONFIG_FB_MODE_HELPERS=y 708CONFIG_FB_MODE_HELPERS=y
700# CONFIG_FB_TILEBLITTING is not set 709# CONFIG_FB_TILEBLITTING is not set
710# CONFIG_FB_S1D13XXX is not set
701# CONFIG_FB_VIRTUAL is not set 711# CONFIG_FB_VIRTUAL is not set
702 712
703# 713#
@@ -782,7 +792,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
782# 792#
783CONFIG_PROC_FS=y 793CONFIG_PROC_FS=y
784CONFIG_SYSFS=y 794CONFIG_SYSFS=y
785# CONFIG_DEVFS_FS is not set
786# CONFIG_DEVPTS_FS_XATTR is not set 795# CONFIG_DEVPTS_FS_XATTR is not set
787# CONFIG_TMPFS is not set 796# CONFIG_TMPFS is not set
788# CONFIG_HUGETLBFS is not set 797# CONFIG_HUGETLBFS is not set
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index fc0555596d6d..0ee34acb8d7b 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -40,6 +40,8 @@
40#include <asm/mach/time.h> 40#include <asm/mach/time.h>
41#include <asm/mach/irq.h> 41#include <asm/mach/irq.h>
42 42
43#include <asm/arch/gpio.h>
44
43static DEFINE_SPINLOCK(ixp2000_slowport_lock); 45static DEFINE_SPINLOCK(ixp2000_slowport_lock);
44static unsigned long ixp2000_slowport_irq_flags; 46static unsigned long ixp2000_slowport_irq_flags;
45 47
@@ -179,7 +181,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
179 181
180 /* clear timer 1 */ 182 /* clear timer 1 */
181 ixp2000_reg_write(IXP2000_T1_CLR, 1); 183 ixp2000_reg_write(IXP2000_T1_CLR, 1);
182 184
183 while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) { 185 while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
184 timer_tick(regs); 186 timer_tick(regs);
185 next_jiffy_time -= ticks_per_jiffy; 187 next_jiffy_time -= ticks_per_jiffy;
@@ -238,35 +240,40 @@ void __init ixp2000_init_time(unsigned long tick_rate)
238/************************************************************************* 240/*************************************************************************
239 * GPIO helpers 241 * GPIO helpers
240 *************************************************************************/ 242 *************************************************************************/
241static unsigned long GPIO_IRQ_rising_edge;
242static unsigned long GPIO_IRQ_falling_edge; 243static unsigned long GPIO_IRQ_falling_edge;
244static unsigned long GPIO_IRQ_rising_edge;
243static unsigned long GPIO_IRQ_level_low; 245static unsigned long GPIO_IRQ_level_low;
244static unsigned long GPIO_IRQ_level_high; 246static unsigned long GPIO_IRQ_level_high;
245 247
246void gpio_line_config(int line, int style) 248static void update_gpio_int_csrs(void)
249{
250 ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
251 ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
252 ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
253 ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
254}
255
256void gpio_line_config(int line, int direction)
247{ 257{
248 unsigned long flags; 258 unsigned long flags;
249 259
250 local_irq_save(flags); 260 local_irq_save(flags);
261 if (direction == GPIO_OUT) {
262 irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0;
251 263
252 if(style == GPIO_OUT) {
253 /* if it's an output, it ain't an interrupt anymore */ 264 /* if it's an output, it ain't an interrupt anymore */
254 ixp2000_reg_write(IXP2000_GPIO_PDSR, (1 << line));
255 GPIO_IRQ_falling_edge &= ~(1 << line); 265 GPIO_IRQ_falling_edge &= ~(1 << line);
256 GPIO_IRQ_rising_edge &= ~(1 << line); 266 GPIO_IRQ_rising_edge &= ~(1 << line);
257 GPIO_IRQ_level_low &= ~(1 << line); 267 GPIO_IRQ_level_low &= ~(1 << line);
258 GPIO_IRQ_level_high &= ~(1 << line); 268 GPIO_IRQ_level_high &= ~(1 << line);
259 ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); 269 update_gpio_int_csrs();
260 ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge); 270
261 ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high); 271 ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line);
262 ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); 272 } else if (direction == GPIO_IN) {
263 irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0; 273 ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
264 } else if(style == GPIO_IN) {
265 ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line));
266 } 274 }
267
268 local_irq_restore(flags); 275 local_irq_restore(flags);
269} 276}
270 277
271 278
272/************************************************************************* 279/*************************************************************************
@@ -285,9 +292,50 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str
285 } 292 }
286} 293}
287 294
295static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
296{
297 int line = irq - IRQ_IXP2000_GPIO0;
298
299 /*
300 * First, configure this GPIO line as an input.
301 */
302 ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
303
304 /*
305 * Then, set the proper trigger type.
306 */
307 if (type & IRQT_FALLING)
308 GPIO_IRQ_falling_edge |= 1 << line;
309 else
310 GPIO_IRQ_falling_edge &= ~(1 << line);
311 if (type & IRQT_RISING)
312 GPIO_IRQ_rising_edge |= 1 << line;
313 else
314 GPIO_IRQ_rising_edge &= ~(1 << line);
315 if (type & IRQT_LOW)
316 GPIO_IRQ_level_low |= 1 << line;
317 else
318 GPIO_IRQ_level_low &= ~(1 << line);
319 if (type & IRQT_HIGH)
320 GPIO_IRQ_level_high |= 1 << line;
321 else
322 GPIO_IRQ_level_high &= ~(1 << line);
323 update_gpio_int_csrs();
324
325 /*
326 * Finally, mark the corresponding IRQ as valid.
327 */
328 irq_desc[irq].valid = 1;
329
330 return 0;
331}
332
288static void ixp2000_GPIO_irq_mask_ack(unsigned int irq) 333static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
289{ 334{
290 ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); 335 ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
336
337 ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
338 ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
291 ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); 339 ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
292} 340}
293 341
@@ -302,6 +350,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq)
302} 350}
303 351
304static struct irqchip ixp2000_GPIO_irq_chip = { 352static struct irqchip ixp2000_GPIO_irq_chip = {
353 .type = ixp2000_GPIO_irq_type,
305 .ack = ixp2000_GPIO_irq_mask_ack, 354 .ack = ixp2000_GPIO_irq_mask_ack,
306 .mask = ixp2000_GPIO_irq_mask, 355 .mask = ixp2000_GPIO_irq_mask,
307 .unmask = ixp2000_GPIO_irq_unmask 356 .unmask = ixp2000_GPIO_irq_unmask
@@ -338,7 +387,7 @@ static void ixp2000_irq_mask(unsigned int irq)
338 387
339static void ixp2000_irq_unmask(unsigned int irq) 388static void ixp2000_irq_unmask(unsigned int irq)
340{ 389{
341 ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq)); 390 ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
342} 391}
343 392
344static struct irqchip ixp2000_irq_chip = { 393static struct irqchip ixp2000_irq_chip = {
@@ -375,16 +424,16 @@ void __init ixp2000_init_irq(void)
375 * our mask/unmask code much simpler. 424 * our mask/unmask code much simpler.
376 */ 425 */
377 for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { 426 for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
378 if((1 << irq) & IXP2000_VALID_IRQ_MASK) { 427 if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
379 set_irq_chip(irq, &ixp2000_irq_chip); 428 set_irq_chip(irq, &ixp2000_irq_chip);
380 set_irq_handler(irq, do_level_IRQ); 429 set_irq_handler(irq, do_level_IRQ);
381 set_irq_flags(irq, IRQF_VALID); 430 set_irq_flags(irq, IRQF_VALID);
382 } else set_irq_flags(irq, 0); 431 } else set_irq_flags(irq, 0);
383 } 432 }
384 433
385 /* 434 /*
386 * GPIO IRQs are invalid until someone sets the interrupt mode 435 * GPIO IRQs are invalid until someone sets the interrupt mode
387 * by calling gpio_line_set(); 436 * by calling set_irq_type().
388 */ 437 */
389 for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { 438 for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
390 set_irq_chip(irq, &ixp2000_GPIO_irq_chip); 439 set_irq_chip(irq, &ixp2000_GPIO_irq_chip);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 267ba02d77dc..f39e8408488f 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -141,7 +141,15 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
141 .physical = IXP4XX_PCI_CFG_BASE_PHYS, 141 .physical = IXP4XX_PCI_CFG_BASE_PHYS,
142 .length = IXP4XX_PCI_CFG_REGION_SIZE, 142 .length = IXP4XX_PCI_CFG_REGION_SIZE,
143 .type = MT_DEVICE 143 .type = MT_DEVICE
144 },
145#ifdef CONFIG_DEBUG_LL
146 { /* Debug UART mapping */
147 .virtual = IXP4XX_DEBUG_UART_BASE_VIRT,
148 .physical = IXP4XX_DEBUG_UART_BASE_PHYS,
149 .length = IXP4XX_DEBUG_UART_REGION_SIZE,
150 .type = MT_DEVICE
144 } 151 }
152#endif
145}; 153};
146 154
147void __init ixp4xx_map_io(void) 155void __init ixp4xx_map_io(void)
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 3bb97eb6e693..f3e970039b65 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -26,6 +26,7 @@
26 * 03-Mar-2005 BJD Ensured that bast-cpld.h is included 26 * 03-Mar-2005 BJD Ensured that bast-cpld.h is included
27 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA 27 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
28 * 14-Mar-2006 BJD Updated for __iomem changes 28 * 14-Mar-2006 BJD Updated for __iomem changes
29 * 22-Jun-2006 BJD Added DM9000 platform information
29*/ 30*/
30 31
31#include <linux/kernel.h> 32#include <linux/kernel.h>
@@ -35,6 +36,7 @@
35#include <linux/timer.h> 36#include <linux/timer.h>
36#include <linux/init.h> 37#include <linux/init.h>
37#include <linux/device.h> 38#include <linux/device.h>
39#include <linux/dm9000.h>
38 40
39#include <asm/mach/arch.h> 41#include <asm/mach/arch.h>
40#include <asm/mach/map.h> 42#include <asm/mach/map.h>
@@ -53,6 +55,7 @@
53#include <asm/arch/regs-serial.h> 55#include <asm/arch/regs-serial.h>
54#include <asm/arch/regs-gpio.h> 56#include <asm/arch/regs-gpio.h>
55#include <asm/arch/regs-mem.h> 57#include <asm/arch/regs-mem.h>
58#include <asm/arch/regs-lcd.h>
56#include <asm/arch/nand.h> 59#include <asm/arch/nand.h>
57 60
58#include <linux/mtd/mtd.h> 61#include <linux/mtd/mtd.h>
@@ -112,7 +115,6 @@ static struct map_desc bast_iodesc[] __initdata = {
112 { VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 115 { VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
113 { VA_C2(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, 116 { VA_C2(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
114 { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 117 { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
115 { VA_C2(BAST_VA_DM9000), PA_CS2(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
116 { VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 118 { VA_C2(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
117 { VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 119 { VA_C2(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
118 { VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 120 { VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -123,7 +125,6 @@ static struct map_desc bast_iodesc[] __initdata = {
123 { VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 125 { VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
124 { VA_C3(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, 126 { VA_C3(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
125 { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 127 { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
126 { VA_C3(BAST_VA_DM9000), PA_CS3(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
127 { VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 128 { VA_C3(BAST_VA_IDEPRI), PA_CS3(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
128 { VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 129 { VA_C3(BAST_VA_IDESEC), PA_CS3(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
129 { VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 130 { VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -134,7 +135,6 @@ static struct map_desc bast_iodesc[] __initdata = {
134 { VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 135 { VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
135 { VA_C4(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, 136 { VA_C4(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
136 { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 137 { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
137 { VA_C4(BAST_VA_DM9000), PA_CS4(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
138 { VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 138 { VA_C4(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
139 { VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 139 { VA_C4(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
140 { VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 140 { VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -145,7 +145,6 @@ static struct map_desc bast_iodesc[] __initdata = {
145 { VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE }, 145 { VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
146 { VA_C5(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE }, 146 { VA_C5(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET), SZ_1M, MT_DEVICE },
147 { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE }, 147 { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
148 { VA_C5(BAST_VA_DM9000), PA_CS5(BAST_PA_DM9000), SZ_1M, MT_DEVICE },
149 { VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE }, 148 { VA_C5(BAST_VA_IDEPRI), PA_CS5(BAST_PA_IDEPRI), SZ_1M, MT_DEVICE },
150 { VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE }, 149 { VA_C5(BAST_VA_IDESEC), PA_CS5(BAST_PA_IDESEC), SZ_1M, MT_DEVICE },
151 { VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 150 { VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -313,6 +312,45 @@ static struct s3c2410_platform_nand bast_nand_info = {
313 .select_chip = bast_nand_select, 312 .select_chip = bast_nand_select,
314}; 313};
315 314
315/* DM9000 */
316
317static struct resource bast_dm9k_resource[] = {
318 [0] = {
319 .start = S3C2410_CS5 + BAST_PA_DM9000,
320 .end = S3C2410_CS5 + BAST_PA_DM9000 + 3,
321 .flags = IORESOURCE_MEM
322 },
323 [1] = {
324 .start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
325 .end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
326 .flags = IORESOURCE_MEM
327 },
328 [2] = {
329 .start = IRQ_DM9000,
330 .end = IRQ_DM9000,
331 .flags = IORESOURCE_IRQ
332 }
333
334};
335
336/* for the moment we limit ourselves to 16bit IO until some
337 * better IO routines can be written and tested
338*/
339
340struct dm9000_plat_data bast_dm9k_platdata = {
341 .flags = DM9000_PLATF_16BITONLY
342};
343
344static struct platform_device bast_device_dm9k = {
345 .name = "dm9000",
346 .id = 0,
347 .num_resources = ARRAY_SIZE(bast_dm9k_resource),
348 .resource = bast_dm9k_resource,
349 .dev = {
350 .platform_data = &bast_dm9k_platdata,
351 }
352};
353
316 354
317/* Standard BAST devices */ 355/* Standard BAST devices */
318 356
@@ -324,7 +362,8 @@ static struct platform_device *bast_devices[] __initdata = {
324 &s3c_device_iis, 362 &s3c_device_iis,
325 &s3c_device_rtc, 363 &s3c_device_rtc,
326 &s3c_device_nand, 364 &s3c_device_nand,
327 &bast_device_nor 365 &bast_device_nor,
366 &bast_device_dm9k,
328}; 367};
329 368
330static struct clk *bast_clocks[] = { 369static struct clk *bast_clocks[] = {
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 5512146b1ce4..76be074944a0 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -27,6 +27,7 @@
27 * 10-Feb-2005 BJD Added power-off capability 27 * 10-Feb-2005 BJD Added power-off capability
28 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA 28 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
29 * 14-Mar-2006 BJD void __iomem fixes 29 * 14-Mar-2006 BJD void __iomem fixes
30 * 22-Jun-2006 BJD Added DM9000 platform information
30*/ 31*/
31 32
32#include <linux/kernel.h> 33#include <linux/kernel.h>
@@ -35,6 +36,7 @@
35#include <linux/list.h> 36#include <linux/list.h>
36#include <linux/timer.h> 37#include <linux/timer.h>
37#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/dm9000.h>
38 40
39#include <linux/serial.h> 41#include <linux/serial.h>
40#include <linux/tty.h> 42#include <linux/tty.h>
@@ -98,28 +100,24 @@ static struct map_desc vr1000_iodesc[] __initdata = {
98 * are only 8bit */ 100 * are only 8bit */
99 101
100 /* slow, byte */ 102 /* slow, byte */
101 { VA_C2(VR1000_VA_DM9000), PA_CS2(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
102 { VA_C2(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, 103 { VA_C2(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
103 { VA_C2(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, 104 { VA_C2(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
104 { VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 105 { VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
105 { VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, 106 { VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
106 107
107 /* slow, word */ 108 /* slow, word */
108 { VA_C3(VR1000_VA_DM9000), PA_CS3(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
109 { VA_C3(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, 109 { VA_C3(VR1000_VA_IDEPRI), PA_CS3(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
110 { VA_C3(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, 110 { VA_C3(VR1000_VA_IDESEC), PA_CS3(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
111 { VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 111 { VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
112 { VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, 112 { VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
113 113
114 /* fast, byte */ 114 /* fast, byte */
115 { VA_C4(VR1000_VA_DM9000), PA_CS4(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
116 { VA_C4(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, 115 { VA_C4(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
117 { VA_C4(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, 116 { VA_C4(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
118 { VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 117 { VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
119 { VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE }, 118 { VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
120 119
121 /* fast, word */ 120 /* fast, word */
122 { VA_C5(VR1000_VA_DM9000), PA_CS5(VR1000_PA_DM9000), SZ_1M, MT_DEVICE },
123 { VA_C5(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE }, 121 { VA_C5(VR1000_VA_IDEPRI), PA_CS5(VR1000_PA_IDEPRI), SZ_1M, MT_DEVICE },
124 { VA_C5(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE }, 122 { VA_C5(VR1000_VA_IDESEC), PA_CS5(VR1000_PA_IDESEC), SZ_1M, MT_DEVICE },
125 { VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE }, 123 { VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -246,6 +244,74 @@ static struct platform_device vr1000_nor = {
246 .resource = vr1000_nor_resource, 244 .resource = vr1000_nor_resource,
247}; 245};
248 246
247/* DM9000 ethernet devices */
248
249static struct resource vr1000_dm9k0_resource[] = {
250 [0] = {
251 .start = S3C2410_CS5 + VR1000_PA_DM9000,
252 .end = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
253 .flags = IORESOURCE_MEM
254 },
255 [1] = {
256 .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
257 .end = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
258 .flags = IORESOURCE_MEM
259 },
260 [2] = {
261 .start = IRQ_VR1000_DM9000A,
262 .end = IRQ_VR1000_DM9000A,
263 .flags = IORESOURCE_IRQ
264 }
265
266};
267
268static struct resource vr1000_dm9k1_resource[] = {
269 [0] = {
270 .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
271 .end = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
272 .flags = IORESOURCE_MEM
273 },
274 [1] = {
275 .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
276 .end = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
277 .flags = IORESOURCE_MEM
278 },
279 [2] = {
280 .start = IRQ_VR1000_DM9000N,
281 .end = IRQ_VR1000_DM9000N,
282 .flags = IORESOURCE_IRQ
283 }
284};
285
286/* for the moment we limit ourselves to 16bit IO until some
287 * better IO routines can be written and tested
288*/
289
290struct dm9000_plat_data vr1000_dm9k_platdata = {
291 .flags = DM9000_PLATF_16BITONLY,
292};
293
294static struct platform_device vr1000_dm9k0 = {
295 .name = "dm9000",
296 .id = 0,
297 .num_resources = ARRAY_SIZE(vr1000_dm9k0_resource),
298 .resource = vr1000_dm9k0_resource,
299 .dev = {
300 .platform_data = &vr1000_dm9k_platdata,
301 }
302};
303
304static struct platform_device vr1000_dm9k1 = {
305 .name = "dm9000",
306 .id = 1,
307 .num_resources = ARRAY_SIZE(vr1000_dm9k1_resource),
308 .resource = vr1000_dm9k1_resource,
309 .dev = {
310 .platform_data = &vr1000_dm9k_platdata,
311 }
312};
313
314/* devices for this board */
249 315
250static struct platform_device *vr1000_devices[] __initdata = { 316static struct platform_device *vr1000_devices[] __initdata = {
251 &s3c_device_usb, 317 &s3c_device_usb,
@@ -253,8 +319,11 @@ static struct platform_device *vr1000_devices[] __initdata = {
253 &s3c_device_wdt, 319 &s3c_device_wdt,
254 &s3c_device_i2c, 320 &s3c_device_i2c,
255 &s3c_device_iis, 321 &s3c_device_iis,
322 &s3c_device_adc,
256 &serial_device, 323 &serial_device,
257 &vr1000_nor, 324 &vr1000_nor,
325 &vr1000_dm9k0,
326 &vr1000_dm9k1
258}; 327};
259 328
260static struct clk *vr1000_clocks[] = { 329static struct clk *vr1000_clocks[] = {
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 0aa73d414783..e3d8510f4340 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -132,8 +132,8 @@ ENTRY(cpu_v6_switch_mm)
132 * 100x 1 0 1 r/o no acc 132 * 100x 1 0 1 r/o no acc
133 * 10x0 1 0 1 r/o no acc 133 * 10x0 1 0 1 r/o no acc
134 * 1011 0 0 1 r/w no acc 134 * 1011 0 0 1 r/w no acc
135 * 110x 1 1 0 r/o r/o 135 * 110x 0 1 0 r/w r/o
136 * 11x0 1 1 0 r/o r/o 136 * 11x0 0 1 0 r/w r/o
137 * 1111 0 1 1 r/w r/w 137 * 1111 0 1 1 r/w r/w
138 */ 138 */
139ENTRY(cpu_v6_set_pte) 139ENTRY(cpu_v6_set_pte)
@@ -150,7 +150,7 @@ ENTRY(cpu_v6_set_pte)
150 tst r1, #L_PTE_USER 150 tst r1, #L_PTE_USER
151 orrne r2, r2, #AP1 | nG 151 orrne r2, r2, #AP1 | nG
152 tstne r2, #APX 152 tstne r2, #APX
153 eorne r2, r2, #AP0 153 bicne r2, r2, #APX | AP0
154 154
155 tst r1, #L_PTE_YOUNG 155 tst r1, #L_PTE_YOUNG
156 biceq r2, r2, #APX | AP1 | AP0 156 biceq r2, r2, #APX | AP1 | AP0
diff --git a/arch/arm/nwfpe/softfloat-macros b/arch/arm/nwfpe/softfloat-macros
index 5469989f2c5e..5a060f95a58f 100644
--- a/arch/arm/nwfpe/softfloat-macros
+++ b/arch/arm/nwfpe/softfloat-macros
@@ -563,8 +563,14 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
563 bits64 rem0, rem1, term0, term1; 563 bits64 rem0, rem1, term0, term1;
564 bits64 z; 564 bits64 z;
565 if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); 565 if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
566 b0 = b>>32; 566 b0 = b>>32; /* hence b0 is 32 bits wide now */
567 z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; 567 if ( b0<<32 <= a0 ) {
568 z = LIT64( 0xFFFFFFFF00000000 );
569 } else {
570 z = a0;
571 do_div( z, b0 );
572 z <<= 32;
573 }
568 mul64To128( b, z, &term0, &term1 ); 574 mul64To128( b, z, &term0, &term1 );
569 sub128( a0, a1, term0, term1, &rem0, &rem1 ); 575 sub128( a0, a1, term0, term1, &rem0, &rem1 );
570 while ( ( (sbits64) rem0 ) < 0 ) { 576 while ( ( (sbits64) rem0 ) < 0 ) {
@@ -573,7 +579,12 @@ static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
573 add128( rem0, rem1, b0, b1, &rem0, &rem1 ); 579 add128( rem0, rem1, b0, b1, &rem0, &rem1 );
574 } 580 }
575 rem0 = ( rem0<<32 ) | ( rem1>>32 ); 581 rem0 = ( rem0<<32 ) | ( rem1>>32 );
576 z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; 582 if ( b0<<32 <= rem0 ) {
583 z |= 0xFFFFFFFF;
584 } else {
585 do_div( rem0, b0 );
586 z |= rem0;
587 }
577 return z; 588 return z;
578 589
579} 590}
@@ -601,6 +612,7 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a )
601 }; 612 };
602 int8 index; 613 int8 index;
603 bits32 z; 614 bits32 z;
615 bits64 A;
604 616
605 index = ( a>>27 ) & 15; 617 index = ( a>>27 ) & 15;
606 if ( aExp & 1 ) { 618 if ( aExp & 1 ) {
@@ -614,7 +626,9 @@ static bits32 estimateSqrt32( int16 aExp, bits32 a )
614 z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); 626 z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
615 if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); 627 if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
616 } 628 }
617 return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); 629 A = ( (bits64) a )<<31;
630 do_div( A, z );
631 return ( (bits32) A ) + ( z>>1 );
618 632
619} 633}
620 634
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
index 9d743ae29062..e038dd3be9b3 100644
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -28,6 +28,8 @@ this code that are retained.
28=============================================================================== 28===============================================================================
29*/ 29*/
30 30
31#include <asm/div64.h>
32
31#include "fpa11.h" 33#include "fpa11.h"
32//#include "milieu.h" 34//#include "milieu.h"
33//#include "softfloat.h" 35//#include "softfloat.h"
@@ -1331,7 +1333,11 @@ float32 float32_div( float32 a, float32 b )
1331 aSig >>= 1; 1333 aSig >>= 1;
1332 ++zExp; 1334 ++zExp;
1333 } 1335 }
1334 zSig = ( ( (bits64) aSig )<<32 ) / bSig; 1336 {
1337 bits64 tmp = ( (bits64) aSig )<<32;
1338 do_div( tmp, bSig );
1339 zSig = tmp;
1340 }
1335 if ( ( zSig & 0x3F ) == 0 ) { 1341 if ( ( zSig & 0x3F ) == 0 ) {
1336 zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 ); 1342 zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
1337 } 1343 }
@@ -1397,7 +1403,9 @@ float32 float32_rem( float32 a, float32 b )
1397 q = ( bSig <= aSig ); 1403 q = ( bSig <= aSig );
1398 if ( q ) aSig -= bSig; 1404 if ( q ) aSig -= bSig;
1399 if ( 0 < expDiff ) { 1405 if ( 0 < expDiff ) {
1400 q = ( ( (bits64) aSig )<<32 ) / bSig; 1406 bits64 tmp = ( (bits64) aSig )<<32;
1407 do_div( tmp, bSig );
1408 q = tmp;
1401 q >>= 32 - expDiff; 1409 q >>= 32 - expDiff;
1402 bSig >>= 2; 1410 bSig >>= 2;
1403 aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; 1411 aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 6caed90661fc..dc0c1936969b 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -179,6 +179,8 @@ config CMDLINE
179 time by entering them here. As a minimum, you should specify the 179 time by entering them here. As a minimum, you should specify the
180 memory size and the root device (e.g., mem=64M root=/dev/nfs). 180 memory size and the root device (e.g., mem=64M root=/dev/nfs).
181 181
182source "mm/Kconfig"
183
182endmenu 184endmenu
183 185
184source "drivers/base/Kconfig" 186source "drivers/base/Kconfig"
diff --git a/arch/arm26/boot/install.sh b/arch/arm26/boot/install.sh
index c628328dd9ec..8a8399b26cf7 100644
--- a/arch/arm26/boot/install.sh
+++ b/arch/arm26/boot/install.sh
@@ -23,8 +23,8 @@
23 23
24# User may have a custom install script 24# User may have a custom install script
25 25
26if [ -x /sbin/installkernel ]; then 26if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then
27 exec /sbin/installkernel "$@" 27 exec /sbin/${CROSS_COMPILE}installkernel "$@"
28fi 28fi
29 29
30if [ "$2" = "zImage" ]; then 30if [ "$2" = "zImage" ]; then
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 4332ca348d51..f848e3761491 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -74,6 +74,8 @@ config PREEMPT
74 Say Y here if you are building a kernel for a desktop, embedded 74 Say Y here if you are building a kernel for a desktop, embedded
75 or real-time system. Say N if you are unsure. 75 or real-time system. Say N if you are unsure.
76 76
77source mm/Kconfig
78
77endmenu 79endmenu
78 80
79menu "Hardware setup" 81menu "Hardware setup"
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 2b19372767eb..c93f95146cc2 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -74,6 +74,8 @@ config HIGHPTE
74 with a lot of RAM, this can be wasteful of precious low memory. 74 with a lot of RAM, this can be wasteful of precious low memory.
75 Setting this option will put user-space page tables in high memory. 75 Setting this option will put user-space page tables in high memory.
76 76
77source "mm/Kconfig"
78
77choice 79choice
78 prompt "uClinux kernel load address" 80 prompt "uClinux kernel load address"
79 depends on !MMU 81 depends on !MMU
diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
index d9dd62a565a9..a380167a13cf 100644
--- a/arch/h8300/Kconfig.cpu
+++ b/arch/h8300/Kconfig.cpu
@@ -180,4 +180,7 @@ config CPU_H8S
180config PREEMPT 180config PREEMPT
181 bool "Preemptible Kernel" 181 bool "Preemptible Kernel"
182 default n 182 default n
183
184source "mm/Kconfig"
185
183endmenu 186endmenu
diff --git a/arch/h8300/platform/h8300h/ptrace_h8300h.c b/arch/h8300/platform/h8300h/ptrace_h8300h.c
index 18e51a7167d3..6ac93c05a1ae 100644
--- a/arch/h8300/platform/h8300h/ptrace_h8300h.c
+++ b/arch/h8300/platform/h8300h/ptrace_h8300h.c
@@ -245,12 +245,12 @@ static unsigned short *getnextpc(struct task_struct *child, unsigned short *pc)
245 addr = h8300_get_reg(child, regno-1+PT_ER1); 245 addr = h8300_get_reg(child, regno-1+PT_ER1);
246 return (unsigned short *)addr; 246 return (unsigned short *)addr;
247 case relb: 247 case relb:
248 if ((inst = 0x55) || isbranch(child,inst & 0x0f)) 248 if (inst == 0x55 || isbranch(child,inst & 0x0f))
249 pc = (unsigned short *)((unsigned long)pc + 249 pc = (unsigned short *)((unsigned long)pc +
250 ((signed char)(*fetch_p))); 250 ((signed char)(*fetch_p)));
251 return pc+1; /* skip myself */ 251 return pc+1; /* skip myself */
252 case relw: 252 case relw:
253 if ((inst = 0x5c) || isbranch(child,(*fetch_p & 0xf0) >> 4)) 253 if (inst == 0x5c || isbranch(child,(*fetch_p & 0xf0) >> 4))
254 pc = (unsigned short *)((unsigned long)pc + 254 pc = (unsigned short *)((unsigned long)pc +
255 ((signed short)(*(pc+1)))); 255 ((signed short)(*(pc+1))));
256 return pc+2; /* skip myself */ 256 return pc+2; /* skip myself */
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index dfd904f6883b..d4ae5f9ceae6 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -68,7 +68,6 @@ config X86_VOYAGER
68 68
69config X86_NUMAQ 69config X86_NUMAQ
70 bool "NUMAQ (IBM/Sequent)" 70 bool "NUMAQ (IBM/Sequent)"
71 select DISCONTIGMEM
72 select NUMA 71 select NUMA
73 help 72 help
74 This option is used for getting Linux to run on a (IBM/Sequent) NUMA 73 This option is used for getting Linux to run on a (IBM/Sequent) NUMA
@@ -783,25 +782,48 @@ comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
783comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" 782comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
784 depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) 783 depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
785 784
786config DISCONTIGMEM
787 bool
788 depends on NUMA
789 default y
790
791config HAVE_ARCH_BOOTMEM_NODE 785config HAVE_ARCH_BOOTMEM_NODE
792 bool 786 bool
793 depends on NUMA 787 depends on NUMA
794 default y 788 default y
795 789
796config HAVE_MEMORY_PRESENT 790config ARCH_HAVE_MEMORY_PRESENT
797 bool 791 bool
798 depends on DISCONTIGMEM 792 depends on DISCONTIGMEM
799 default y 793 default y
800 794
801config NEED_NODE_MEMMAP_SIZE 795config NEED_NODE_MEMMAP_SIZE
802 bool 796 bool
803 depends on DISCONTIGMEM 797 depends on DISCONTIGMEM || SPARSEMEM
798 default y
799
800config HAVE_ARCH_ALLOC_REMAP
801 bool
802 depends on NUMA
803 default y
804
805config ARCH_DISCONTIGMEM_ENABLE
806 def_bool y
807 depends on NUMA
808
809config ARCH_DISCONTIGMEM_DEFAULT
810 def_bool y
811 depends on NUMA
812
813config ARCH_SPARSEMEM_ENABLE
814 def_bool y
815 depends on NUMA
816
817config ARCH_SELECT_MEMORY_MODEL
818 def_bool y
819 depends on ARCH_SPARSEMEM_ENABLE
820
821source "mm/Kconfig"
822
823config HAVE_ARCH_EARLY_PFN_TO_NID
824 bool
804 default y 825 default y
826 depends on NUMA
805 827
806config HIGHPTE 828config HIGHPTE
807 bool "Allocate 3rd-level pagetables from highmem" 829 bool "Allocate 3rd-level pagetables from highmem"
@@ -939,6 +961,8 @@ config SECCOMP
939 961
940 If unsure, say Y. Only embedded should say N here. 962 If unsure, say Y. Only embedded should say N here.
941 963
964source kernel/Kconfig.hz
965
942endmenu 966endmenu
943 967
944 968
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 1c36ca332a96..bf7c9ba709f3 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -17,6 +17,13 @@
17# 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net> 17# 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net>
18# Added support for GEODE CPU 18# Added support for GEODE CPU
19 19
20HAS_BIARCH := $(call cc-option-yn, -m32)
21ifeq ($(HAS_BIARCH),y)
22AS := $(AS) --32
23LD := $(LD) -m elf_i386
24CC := $(CC) -m32
25endif
26
20LDFLAGS := -m elf_i386 27LDFLAGS := -m elf_i386
21OBJCOPYFLAGS := -O binary -R .note -R .comment -S 28OBJCOPYFLAGS := -O binary -R .note -R .comment -S
22LDFLAGS_vmlinux := 29LDFLAGS_vmlinux :=
diff --git a/arch/i386/boot/install.sh b/arch/i386/boot/install.sh
index 90f2452b3b9e..f17b40dfc0f4 100644
--- a/arch/i386/boot/install.sh
+++ b/arch/i386/boot/install.sh
@@ -21,8 +21,8 @@
21 21
22# User may have a custom install script 22# User may have a custom install script
23 23
24if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi 24if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
25if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi 25if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
26 26
27# Default install - same as make zlilo 27# Default install - same as make zlilo
28 28
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index d509836b70c3..8d993fa71754 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -1133,7 +1133,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
1133 } 1133 }
1134 1134
1135#ifdef CONFIG_SMP 1135#ifdef CONFIG_SMP
1136 update_process_times(user_mode(regs)); 1136 update_process_times(user_mode_vm(regs));
1137#endif 1137#endif
1138 } 1138 }
1139 1139
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index d199e525680a..b9954248d0aa 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -635,7 +635,7 @@ void __init cpu_init (void)
635 635
636 /* Clear all 6 debug registers: */ 636 /* Clear all 6 debug registers: */
637 637
638#define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) ); 638#define CD(register) set_debugreg(0, register)
639 639
640 CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7); 640 CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7);
641 641
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index e1c2042b9b7e..d66b09e0c820 100644
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -375,6 +375,19 @@ int mtrr_add_page(unsigned long base, unsigned long size,
375 return error; 375 return error;
376} 376}
377 377
378static int mtrr_check(unsigned long base, unsigned long size)
379{
380 if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
381 printk(KERN_WARNING
382 "mtrr: size and base must be multiples of 4 kiB\n");
383 printk(KERN_DEBUG
384 "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
385 dump_stack();
386 return -1;
387 }
388 return 0;
389}
390
378/** 391/**
379 * mtrr_add - Add a memory type region 392 * mtrr_add - Add a memory type region
380 * @base: Physical base address of region 393 * @base: Physical base address of region
@@ -415,11 +428,8 @@ int
415mtrr_add(unsigned long base, unsigned long size, unsigned int type, 428mtrr_add(unsigned long base, unsigned long size, unsigned int type,
416 char increment) 429 char increment)
417{ 430{
418 if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { 431 if (mtrr_check(base, size))
419 printk(KERN_WARNING "mtrr: size and base must be multiples of 4 kiB\n");
420 printk(KERN_DEBUG "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
421 return -EINVAL; 432 return -EINVAL;
422 }
423 return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, 433 return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
424 increment); 434 increment);
425} 435}
@@ -511,11 +521,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
511int 521int
512mtrr_del(int reg, unsigned long base, unsigned long size) 522mtrr_del(int reg, unsigned long base, unsigned long size)
513{ 523{
514 if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { 524 if (mtrr_check(base, size))
515 printk(KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
516 printk(KERN_DEBUG "mtrr: size: 0x%lx base: 0x%lx\n", size, base);
517 return -EINVAL; 525 return -EINVAL;
518 }
519 return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); 526 return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
520} 527}
521 528
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 7323c19f354e..8bd77d948a84 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -86,7 +86,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
86 seq_printf(m, "stepping\t: unknown\n"); 86 seq_printf(m, "stepping\t: unknown\n");
87 87
88 if ( cpu_has(c, X86_FEATURE_TSC) ) { 88 if ( cpu_has(c, X86_FEATURE_TSC) ) {
89 seq_printf(m, "cpu MHz\t\t: %lu.%03lu\n", 89 seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
90 cpu_khz / 1000, (cpu_khz % 1000)); 90 cpu_khz / 1000, (cpu_khz % 1000));
91 } 91 }
92 92
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 903190a4b3ff..180f070d03cb 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -1,97 +1,17 @@
1#include <linux/config.h> 1#include <linux/config.h>
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/smp.h>
4#include <linux/user.h>
5#include <linux/elfcore.h>
6#include <linux/mca.h>
7#include <linux/sched.h>
8#include <linux/in6.h>
9#include <linux/interrupt.h>
10#include <linux/smp_lock.h>
11#include <linux/pm.h>
12#include <linux/pci.h>
13#include <linux/apm_bios.h>
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <linux/tty.h>
17#include <linux/highmem.h>
18#include <linux/time.h>
19
20#include <asm/semaphore.h>
21#include <asm/processor.h>
22#include <asm/i387.h>
23#include <asm/uaccess.h>
24#include <asm/checksum.h> 3#include <asm/checksum.h>
25#include <asm/io.h>
26#include <asm/delay.h>
27#include <asm/irq.h>
28#include <asm/mmx.h>
29#include <asm/desc.h> 4#include <asm/desc.h>
30#include <asm/pgtable.h>
31#include <asm/tlbflush.h>
32#include <asm/nmi.h>
33#include <asm/ist.h>
34#include <asm/kdebug.h>
35
36extern void dump_thread(struct pt_regs *, struct user *);
37extern spinlock_t rtc_lock;
38 5
39/* This is definitely a GPL-only symbol */ 6/* This is definitely a GPL-only symbol */
40EXPORT_SYMBOL_GPL(cpu_gdt_table); 7EXPORT_SYMBOL_GPL(cpu_gdt_table);
41 8
42#if defined(CONFIG_APM_MODULE)
43extern void machine_real_restart(unsigned char *, int);
44EXPORT_SYMBOL(machine_real_restart);
45extern void default_idle(void);
46EXPORT_SYMBOL(default_idle);
47#endif
48
49#ifdef CONFIG_SMP
50extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
51extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
52#endif
53
54#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
55extern struct drive_info_struct drive_info;
56EXPORT_SYMBOL(drive_info);
57#endif
58
59extern unsigned long cpu_khz;
60extern unsigned long get_cmos_time(void);
61
62/* platform dependent support */
63EXPORT_SYMBOL(boot_cpu_data);
64#ifdef CONFIG_DISCONTIGMEM
65EXPORT_SYMBOL(node_data);
66EXPORT_SYMBOL(physnode_map);
67#endif
68#ifdef CONFIG_X86_NUMAQ
69EXPORT_SYMBOL(xquad_portio);
70#endif
71EXPORT_SYMBOL(dump_thread);
72EXPORT_SYMBOL(dump_fpu);
73EXPORT_SYMBOL_GPL(kernel_fpu_begin);
74EXPORT_SYMBOL(__ioremap);
75EXPORT_SYMBOL(ioremap_nocache);
76EXPORT_SYMBOL(iounmap);
77EXPORT_SYMBOL(kernel_thread);
78EXPORT_SYMBOL(pm_idle);
79EXPORT_SYMBOL(pm_power_off);
80EXPORT_SYMBOL(get_cmos_time);
81EXPORT_SYMBOL(cpu_khz);
82EXPORT_SYMBOL(apm_info);
83
84EXPORT_SYMBOL(__down_failed); 9EXPORT_SYMBOL(__down_failed);
85EXPORT_SYMBOL(__down_failed_interruptible); 10EXPORT_SYMBOL(__down_failed_interruptible);
86EXPORT_SYMBOL(__down_failed_trylock); 11EXPORT_SYMBOL(__down_failed_trylock);
87EXPORT_SYMBOL(__up_wakeup); 12EXPORT_SYMBOL(__up_wakeup);
88/* Networking helper routines. */ 13/* Networking helper routines. */
89EXPORT_SYMBOL(csum_partial_copy_generic); 14EXPORT_SYMBOL(csum_partial_copy_generic);
90/* Delay loops */
91EXPORT_SYMBOL(__ndelay);
92EXPORT_SYMBOL(__udelay);
93EXPORT_SYMBOL(__delay);
94EXPORT_SYMBOL(__const_udelay);
95 15
96EXPORT_SYMBOL(__get_user_1); 16EXPORT_SYMBOL(__get_user_1);
97EXPORT_SYMBOL(__get_user_2); 17EXPORT_SYMBOL(__get_user_2);
@@ -105,87 +25,11 @@ EXPORT_SYMBOL(__put_user_8);
105EXPORT_SYMBOL(strpbrk); 25EXPORT_SYMBOL(strpbrk);
106EXPORT_SYMBOL(strstr); 26EXPORT_SYMBOL(strstr);
107 27
108EXPORT_SYMBOL(strncpy_from_user);
109EXPORT_SYMBOL(__strncpy_from_user);
110EXPORT_SYMBOL(clear_user);
111EXPORT_SYMBOL(__clear_user);
112EXPORT_SYMBOL(__copy_from_user_ll);
113EXPORT_SYMBOL(__copy_to_user_ll);
114EXPORT_SYMBOL(strnlen_user);
115
116EXPORT_SYMBOL(dma_alloc_coherent);
117EXPORT_SYMBOL(dma_free_coherent);
118
119#ifdef CONFIG_PCI
120EXPORT_SYMBOL(pci_mem_start);
121#endif
122
123#ifdef CONFIG_PCI_BIOS
124EXPORT_SYMBOL(pcibios_set_irq_routing);
125EXPORT_SYMBOL(pcibios_get_irq_routing_table);
126#endif
127
128#ifdef CONFIG_X86_USE_3DNOW
129EXPORT_SYMBOL(_mmx_memcpy);
130EXPORT_SYMBOL(mmx_clear_page);
131EXPORT_SYMBOL(mmx_copy_page);
132#endif
133
134#ifdef CONFIG_X86_HT
135EXPORT_SYMBOL(smp_num_siblings);
136EXPORT_SYMBOL(cpu_sibling_map);
137#endif
138
139#ifdef CONFIG_SMP 28#ifdef CONFIG_SMP
140EXPORT_SYMBOL(cpu_data); 29extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
141EXPORT_SYMBOL(cpu_online_map); 30extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
142EXPORT_SYMBOL(cpu_callout_map);
143EXPORT_SYMBOL(__write_lock_failed); 31EXPORT_SYMBOL(__write_lock_failed);
144EXPORT_SYMBOL(__read_lock_failed); 32EXPORT_SYMBOL(__read_lock_failed);
145
146/* Global SMP stuff */
147EXPORT_SYMBOL(smp_call_function);
148
149/* TLB flushing */
150EXPORT_SYMBOL(flush_tlb_page);
151#endif
152
153#ifdef CONFIG_X86_IO_APIC
154EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
155#endif
156
157#ifdef CONFIG_MCA
158EXPORT_SYMBOL(machine_id);
159#endif
160
161#ifdef CONFIG_VT
162EXPORT_SYMBOL(screen_info);
163#endif
164
165EXPORT_SYMBOL(get_wchan);
166
167EXPORT_SYMBOL(rtc_lock);
168
169EXPORT_SYMBOL_GPL(set_nmi_callback);
170EXPORT_SYMBOL_GPL(unset_nmi_callback);
171
172EXPORT_SYMBOL(register_die_notifier);
173#ifdef CONFIG_HAVE_DEC_LOCK
174EXPORT_SYMBOL(_atomic_dec_and_lock);
175#endif
176
177EXPORT_SYMBOL(__PAGE_KERNEL);
178
179#ifdef CONFIG_HIGHMEM
180EXPORT_SYMBOL(kmap);
181EXPORT_SYMBOL(kunmap);
182EXPORT_SYMBOL(kmap_atomic);
183EXPORT_SYMBOL(kunmap_atomic);
184EXPORT_SYMBOL(kmap_atomic_to_page);
185#endif
186
187#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
188EXPORT_SYMBOL(ist_info);
189#endif 33#endif
190 34
191EXPORT_SYMBOL(csum_partial); 35EXPORT_SYMBOL(csum_partial);
diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
index c55e037f08f7..b817168d9c62 100644
--- a/arch/i386/kernel/i387.c
+++ b/arch/i386/kernel/i387.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/config.h> 11#include <linux/config.h>
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include <linux/module.h>
13#include <asm/processor.h> 14#include <asm/processor.h>
14#include <asm/i387.h> 15#include <asm/i387.h>
15#include <asm/math_emu.h> 16#include <asm/math_emu.h>
@@ -79,6 +80,7 @@ void kernel_fpu_begin(void)
79 } 80 }
80 clts(); 81 clts();
81} 82}
83EXPORT_SYMBOL_GPL(kernel_fpu_begin);
82 84
83void restore_fpu( struct task_struct *tsk ) 85void restore_fpu( struct task_struct *tsk )
84{ 86{
@@ -526,6 +528,7 @@ int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu )
526 528
527 return fpvalid; 529 return fpvalid;
528} 530}
531EXPORT_SYMBOL(dump_fpu);
529 532
530int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu) 533int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
531{ 534{
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 7a324e8b86f9..08540bc4ba3e 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -31,7 +31,7 @@
31#include <linux/mc146818rtc.h> 31#include <linux/mc146818rtc.h>
32#include <linux/compiler.h> 32#include <linux/compiler.h>
33#include <linux/acpi.h> 33#include <linux/acpi.h>
34 34#include <linux/module.h>
35#include <linux/sysdev.h> 35#include <linux/sysdev.h>
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/smp.h> 37#include <asm/smp.h>
@@ -812,6 +812,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
812 } 812 }
813 return best_guess; 813 return best_guess;
814} 814}
815EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
815 816
816/* 817/*
817 * This function currently is only a helper for the i386 smp boot process where 818 * This function currently is only a helper for the i386 smp boot process where
@@ -1659,6 +1660,12 @@ static void __init setup_ioapic_ids_from_mpc(void)
1659 unsigned long flags; 1660 unsigned long flags;
1660 1661
1661 /* 1662 /*
1663 * Don't check I/O APIC IDs for xAPIC systems. They have
1664 * no meaning without the serial APIC bus.
1665 */
1666 if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15))
1667 return;
1668 /*
1662 * This is broken; anything with a real cpu count has to 1669 * This is broken; anything with a real cpu count has to
1663 * circumvent this idiocy regardless. 1670 * circumvent this idiocy regardless.
1664 */ 1671 */
@@ -1684,10 +1691,6 @@ static void __init setup_ioapic_ids_from_mpc(void)
1684 mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; 1691 mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
1685 } 1692 }
1686 1693
1687 /* Don't check I/O APIC IDs for some xAPIC systems. They have
1688 * no meaning without the serial APIC bus. */
1689 if (NO_IOAPIC_CHECK)
1690 continue;
1691 /* 1694 /*
1692 * Sanity check, is the ID really free? Every APIC in a 1695 * Sanity check, is the ID really free? Every APIC in a
1693 * system must have a unique ID or we get lots of nice 1696 * system must have a unique ID or we get lots of nice
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 59ff9b455069..3762f6b35ab2 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -23,6 +23,9 @@
23 * Rusty Russell). 23 * Rusty Russell).
24 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes 24 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
25 * interface to access function arguments. 25 * interface to access function arguments.
26 * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston
27 * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
28 * <prasanna@in.ibm.com> added function-return probes.
26 */ 29 */
27 30
28#include <linux/config.h> 31#include <linux/config.h>
@@ -30,15 +33,14 @@
30#include <linux/ptrace.h> 33#include <linux/ptrace.h>
31#include <linux/spinlock.h> 34#include <linux/spinlock.h>
32#include <linux/preempt.h> 35#include <linux/preempt.h>
36#include <asm/cacheflush.h>
33#include <asm/kdebug.h> 37#include <asm/kdebug.h>
34#include <asm/desc.h> 38#include <asm/desc.h>
35 39
36/* kprobe_status settings */
37#define KPROBE_HIT_ACTIVE 0x00000001
38#define KPROBE_HIT_SS 0x00000002
39
40static struct kprobe *current_kprobe; 40static struct kprobe *current_kprobe;
41static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags; 41static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
42static struct kprobe *kprobe_prev;
43static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
42static struct pt_regs jprobe_saved_regs; 44static struct pt_regs jprobe_saved_regs;
43static long *jprobe_saved_esp; 45static long *jprobe_saved_esp;
44/* copy of the kernel stack at the probe fire time */ 46/* copy of the kernel stack at the probe fire time */
@@ -68,16 +70,50 @@ int arch_prepare_kprobe(struct kprobe *p)
68void arch_copy_kprobe(struct kprobe *p) 70void arch_copy_kprobe(struct kprobe *p)
69{ 71{
70 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 72 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
73 p->opcode = *p->addr;
71} 74}
72 75
73void arch_remove_kprobe(struct kprobe *p) 76void arch_arm_kprobe(struct kprobe *p)
74{ 77{
78 *p->addr = BREAKPOINT_INSTRUCTION;
79 flush_icache_range((unsigned long) p->addr,
80 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
75} 81}
76 82
77static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) 83void arch_disarm_kprobe(struct kprobe *p)
78{ 84{
79 *p->addr = p->opcode; 85 *p->addr = p->opcode;
80 regs->eip = (unsigned long)p->addr; 86 flush_icache_range((unsigned long) p->addr,
87 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
88}
89
90void arch_remove_kprobe(struct kprobe *p)
91{
92}
93
94static inline void save_previous_kprobe(void)
95{
96 kprobe_prev = current_kprobe;
97 kprobe_status_prev = kprobe_status;
98 kprobe_old_eflags_prev = kprobe_old_eflags;
99 kprobe_saved_eflags_prev = kprobe_saved_eflags;
100}
101
102static inline void restore_previous_kprobe(void)
103{
104 current_kprobe = kprobe_prev;
105 kprobe_status = kprobe_status_prev;
106 kprobe_old_eflags = kprobe_old_eflags_prev;
107 kprobe_saved_eflags = kprobe_saved_eflags_prev;
108}
109
110static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
111{
112 current_kprobe = p;
113 kprobe_saved_eflags = kprobe_old_eflags
114 = (regs->eflags & (TF_MASK | IF_MASK));
115 if (is_IF_modifier(p->opcode))
116 kprobe_saved_eflags &= ~IF_MASK;
81} 117}
82 118
83static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 119static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -91,6 +127,50 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
91 regs->eip = (unsigned long)&p->ainsn.insn; 127 regs->eip = (unsigned long)&p->ainsn.insn;
92} 128}
93 129
130struct task_struct *arch_get_kprobe_task(void *ptr)
131{
132 return ((struct thread_info *) (((unsigned long) ptr) &
133 (~(THREAD_SIZE -1))))->task;
134}
135
136void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
137{
138 unsigned long *sara = (unsigned long *)&regs->esp;
139 struct kretprobe_instance *ri;
140 static void *orig_ret_addr;
141
142 /*
143 * Save the return address when the return probe hits
144 * the first time, and use it to populate the (krprobe
145 * instance)->ret_addr for subsequent return probes at
146 * the same addrress since stack address would have
147 * the kretprobe_trampoline by then.
148 */
149 if (((void*) *sara) != kretprobe_trampoline)
150 orig_ret_addr = (void*) *sara;
151
152 if ((ri = get_free_rp_inst(rp)) != NULL) {
153 ri->rp = rp;
154 ri->stack_addr = sara;
155 ri->ret_addr = orig_ret_addr;
156 add_rp_inst(ri);
157 /* Replace the return addr with trampoline addr */
158 *sara = (unsigned long) &kretprobe_trampoline;
159 } else {
160 rp->nmissed++;
161 }
162}
163
164void arch_kprobe_flush_task(struct task_struct *tk)
165{
166 struct kretprobe_instance *ri;
167 while ((ri = get_rp_inst_tsk(tk)) != NULL) {
168 *((unsigned long *)(ri->stack_addr)) =
169 (unsigned long) ri->ret_addr;
170 recycle_rp_inst(ri);
171 }
172}
173
94/* 174/*
95 * Interrupts are disabled on entry as trap3 is an interrupt gate and they 175 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
96 * remain disabled thorough out this function. 176 * remain disabled thorough out this function.
@@ -127,8 +207,18 @@ static int kprobe_handler(struct pt_regs *regs)
127 unlock_kprobes(); 207 unlock_kprobes();
128 goto no_kprobe; 208 goto no_kprobe;
129 } 209 }
130 disarm_kprobe(p, regs); 210 /* We have reentered the kprobe_handler(), since
131 ret = 1; 211 * another probe was hit while within the handler.
212 * We here save the original kprobes variables and
213 * just single step on the instruction of the new probe
214 * without calling any user handlers.
215 */
216 save_previous_kprobe();
217 set_current_kprobe(p, regs);
218 p->nmissed++;
219 prepare_singlestep(p, regs);
220 kprobe_status = KPROBE_REENTER;
221 return 1;
132 } else { 222 } else {
133 p = current_kprobe; 223 p = current_kprobe;
134 if (p->break_handler && p->break_handler(p, regs)) { 224 if (p->break_handler && p->break_handler(p, regs)) {
@@ -163,11 +253,7 @@ static int kprobe_handler(struct pt_regs *regs)
163 } 253 }
164 254
165 kprobe_status = KPROBE_HIT_ACTIVE; 255 kprobe_status = KPROBE_HIT_ACTIVE;
166 current_kprobe = p; 256 set_current_kprobe(p, regs);
167 kprobe_saved_eflags = kprobe_old_eflags
168 = (regs->eflags & (TF_MASK | IF_MASK));
169 if (is_IF_modifier(p->opcode))
170 kprobe_saved_eflags &= ~IF_MASK;
171 257
172 if (p->pre_handler && p->pre_handler(p, regs)) 258 if (p->pre_handler && p->pre_handler(p, regs))
173 /* handler has already set things up, so skip ss setup */ 259 /* handler has already set things up, so skip ss setup */
@@ -184,6 +270,55 @@ no_kprobe:
184} 270}
185 271
186/* 272/*
273 * For function-return probes, init_kprobes() establishes a probepoint
274 * here. When a retprobed function returns, this probe is hit and
275 * trampoline_probe_handler() runs, calling the kretprobe's handler.
276 */
277 void kretprobe_trampoline_holder(void)
278 {
279 asm volatile ( ".global kretprobe_trampoline\n"
280 "kretprobe_trampoline: \n"
281 "nop\n");
282 }
283
284/*
285 * Called when we hit the probe point at kretprobe_trampoline
286 */
287int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
288{
289 struct task_struct *tsk;
290 struct kretprobe_instance *ri;
291 struct hlist_head *head;
292 struct hlist_node *node;
293 unsigned long *sara = ((unsigned long *) &regs->esp) - 1;
294
295 tsk = arch_get_kprobe_task(sara);
296 head = kretprobe_inst_table_head(tsk);
297
298 hlist_for_each_entry(ri, node, head, hlist) {
299 if (ri->stack_addr == sara && ri->rp) {
300 if (ri->rp->handler)
301 ri->rp->handler(ri, regs);
302 }
303 }
304 return 0;
305}
306
307void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs,
308 unsigned long flags)
309{
310 struct kretprobe_instance *ri;
311 /* RA already popped */
312 unsigned long *sara = ((unsigned long *)&regs->esp) - 1;
313
314 while ((ri = get_rp_inst(sara))) {
315 regs->eip = (unsigned long)ri->ret_addr;
316 recycle_rp_inst(ri);
317 }
318 regs->eflags &= ~TF_MASK;
319}
320
321/*
187 * Called after single-stepping. p->addr is the address of the 322 * Called after single-stepping. p->addr is the address of the
188 * instruction whose first byte has been replaced by the "int 3" 323 * instruction whose first byte has been replaced by the "int 3"
189 * instruction. To avoid the SMP problems that can occur when we 324 * instruction. To avoid the SMP problems that can occur when we
@@ -263,13 +398,22 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
263 if (!kprobe_running()) 398 if (!kprobe_running())
264 return 0; 399 return 0;
265 400
266 if (current_kprobe->post_handler) 401 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
402 kprobe_status = KPROBE_HIT_SSDONE;
267 current_kprobe->post_handler(current_kprobe, regs, 0); 403 current_kprobe->post_handler(current_kprobe, regs, 0);
404 }
268 405
269 resume_execution(current_kprobe, regs); 406 if (current_kprobe->post_handler != trampoline_post_handler)
407 resume_execution(current_kprobe, regs);
270 regs->eflags |= kprobe_saved_eflags; 408 regs->eflags |= kprobe_saved_eflags;
271 409
410 /*Restore back the original saved kprobes variables and continue. */
411 if (kprobe_status == KPROBE_REENTER) {
412 restore_previous_kprobe();
413 goto out;
414 }
272 unlock_kprobes(); 415 unlock_kprobes();
416out:
273 preempt_enable_no_resched(); 417 preempt_enable_no_resched();
274 418
275 /* 419 /*
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 1347ab4939e7..383a11600d2c 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -914,7 +914,10 @@ void __init mp_register_ioapic (
914 mp_ioapics[idx].mpc_apicaddr = address; 914 mp_ioapics[idx].mpc_apicaddr = address;
915 915
916 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 916 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
917 mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); 917 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
918 mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
919 else
920 mp_ioapics[idx].mpc_apicid = id;
918 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); 921 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
919 922
920 /* 923 /*
@@ -1055,11 +1058,20 @@ void __init mp_config_acpi_legacy_irqs (void)
1055 } 1058 }
1056} 1059}
1057 1060
1061#define MAX_GSI_NUM 4096
1062
1058int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) 1063int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
1059{ 1064{
1060 int ioapic = -1; 1065 int ioapic = -1;
1061 int ioapic_pin = 0; 1066 int ioapic_pin = 0;
1062 int idx, bit = 0; 1067 int idx, bit = 0;
1068 static int pci_irq = 16;
1069 /*
1070 * Mapping between Global System Interrups, which
1071 * represent all possible interrupts, and IRQs
1072 * assigned to actual devices.
1073 */
1074 static int gsi_to_irq[MAX_GSI_NUM];
1063 1075
1064#ifdef CONFIG_ACPI_BUS 1076#ifdef CONFIG_ACPI_BUS
1065 /* Don't set up the ACPI SCI because it's already set up */ 1077 /* Don't set up the ACPI SCI because it's already set up */
@@ -1094,11 +1106,26 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
1094 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 1106 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
1095 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 1107 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
1096 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 1108 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
1097 return gsi; 1109 return gsi_to_irq[gsi];
1098 } 1110 }
1099 1111
1100 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 1112 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
1101 1113
1114 if (edge_level) {
1115 /*
1116 * For PCI devices assign IRQs in order, avoiding gaps
1117 * due to unused I/O APIC pins.
1118 */
1119 int irq = gsi;
1120 if (gsi < MAX_GSI_NUM) {
1121 gsi = pci_irq++;
1122 gsi_to_irq[irq] = gsi;
1123 } else {
1124 printk(KERN_ERR "GSI %u is too high\n", gsi);
1125 return gsi;
1126 }
1127 }
1128
1102 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 1129 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
1103 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, 1130 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
1104 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); 1131 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 2c0ee9c2d020..da6c46d667cb 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -28,8 +28,7 @@
28#include <linux/sysctl.h> 28#include <linux/sysctl.h>
29 29
30#include <asm/smp.h> 30#include <asm/smp.h>
31#include <asm/mtrr.h> 31#include <asm/div64.h>
32#include <asm/mpspec.h>
33#include <asm/nmi.h> 32#include <asm/nmi.h>
34 33
35#include "mach_traps.h" 34#include "mach_traps.h"
@@ -324,6 +323,16 @@ static void clear_msr_range(unsigned int base, unsigned int n)
324 wrmsr(base+i, 0, 0); 323 wrmsr(base+i, 0, 0);
325} 324}
326 325
326static inline void write_watchdog_counter(const char *descr)
327{
328 u64 count = (u64)cpu_khz * 1000;
329
330 do_div(count, nmi_hz);
331 if(descr)
332 Dprintk("setting %s to -0x%08Lx\n", descr, count);
333 wrmsrl(nmi_perfctr_msr, 0 - count);
334}
335
327static void setup_k7_watchdog(void) 336static void setup_k7_watchdog(void)
328{ 337{
329 unsigned int evntsel; 338 unsigned int evntsel;
@@ -339,8 +348,7 @@ static void setup_k7_watchdog(void)
339 | K7_NMI_EVENT; 348 | K7_NMI_EVENT;
340 349
341 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 350 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
342 Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); 351 write_watchdog_counter("K7_PERFCTR0");
343 wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
344 apic_write(APIC_LVTPC, APIC_DM_NMI); 352 apic_write(APIC_LVTPC, APIC_DM_NMI);
345 evntsel |= K7_EVNTSEL_ENABLE; 353 evntsel |= K7_EVNTSEL_ENABLE;
346 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 354 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
@@ -361,8 +369,7 @@ static void setup_p6_watchdog(void)
361 | P6_NMI_EVENT; 369 | P6_NMI_EVENT;
362 370
363 wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); 371 wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
364 Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000)); 372 write_watchdog_counter("P6_PERFCTR0");
365 wrmsr(MSR_P6_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0);
366 apic_write(APIC_LVTPC, APIC_DM_NMI); 373 apic_write(APIC_LVTPC, APIC_DM_NMI);
367 evntsel |= P6_EVNTSEL0_ENABLE; 374 evntsel |= P6_EVNTSEL0_ENABLE;
368 wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); 375 wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
@@ -402,8 +409,7 @@ static int setup_p4_watchdog(void)
402 409
403 wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); 410 wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
404 wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); 411 wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
405 Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000)); 412 write_watchdog_counter("P4_IQ_COUNTER0");
406 wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
407 apic_write(APIC_LVTPC, APIC_DM_NMI); 413 apic_write(APIC_LVTPC, APIC_DM_NMI);
408 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); 414 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
409 return 1; 415 return 1;
@@ -518,7 +524,7 @@ void nmi_watchdog_tick (struct pt_regs * regs)
518 * other P6 variant */ 524 * other P6 variant */
519 apic_write(APIC_LVTPC, APIC_DM_NMI); 525 apic_write(APIC_LVTPC, APIC_DM_NMI);
520 } 526 }
521 wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); 527 write_watchdog_counter(NULL);
522 } 528 }
523} 529}
524 530
diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
index 4de2e03c7b45..1e51427cc9eb 100644
--- a/arch/i386/kernel/pci-dma.c
+++ b/arch/i386/kernel/pci-dma.c
@@ -11,6 +11,7 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/pci.h> 13#include <linux/pci.h>
14#include <linux/module.h>
14#include <asm/io.h> 15#include <asm/io.h>
15 16
16struct dma_coherent_mem { 17struct dma_coherent_mem {
@@ -54,6 +55,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
54 } 55 }
55 return ret; 56 return ret;
56} 57}
58EXPORT_SYMBOL(dma_alloc_coherent);
57 59
58void dma_free_coherent(struct device *dev, size_t size, 60void dma_free_coherent(struct device *dev, size_t size,
59 void *vaddr, dma_addr_t dma_handle) 61 void *vaddr, dma_addr_t dma_handle)
@@ -68,6 +70,7 @@ void dma_free_coherent(struct device *dev, size_t size,
68 } else 70 } else
69 free_pages((unsigned long)vaddr, order); 71 free_pages((unsigned long)vaddr, order);
70} 72}
73EXPORT_SYMBOL(dma_free_coherent);
71 74
72int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, 75int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
73 dma_addr_t device_addr, size_t size, int flags) 76 dma_addr_t device_addr, size_t size, int flags)
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 96e3ea6b17c7..aea2ce1145df 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -37,6 +37,7 @@
37#include <linux/kallsyms.h> 37#include <linux/kallsyms.h>
38#include <linux/ptrace.h> 38#include <linux/ptrace.h>
39#include <linux/random.h> 39#include <linux/random.h>
40#include <linux/kprobes.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
@@ -73,6 +74,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
73 * Powermanagement idle function, if any.. 74 * Powermanagement idle function, if any..
74 */ 75 */
75void (*pm_idle)(void); 76void (*pm_idle)(void);
77EXPORT_SYMBOL(pm_idle);
76static DEFINE_PER_CPU(unsigned int, cpu_idle_state); 78static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
77 79
78void disable_hlt(void) 80void disable_hlt(void)
@@ -105,6 +107,9 @@ void default_idle(void)
105 cpu_relax(); 107 cpu_relax();
106 } 108 }
107} 109}
110#ifdef CONFIG_APM_MODULE
111EXPORT_SYMBOL(default_idle);
112#endif
108 113
109/* 114/*
110 * On SMP it's slightly faster (but much more power-consuming!) 115 * On SMP it's slightly faster (but much more power-consuming!)
@@ -262,7 +267,7 @@ void show_regs(struct pt_regs * regs)
262 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); 267 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
263 print_symbol("EIP is at %s\n", regs->eip); 268 print_symbol("EIP is at %s\n", regs->eip);
264 269
265 if (regs->xcs & 3) 270 if (user_mode(regs))
266 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); 271 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
267 printk(" EFLAGS: %08lx %s (%s)\n", 272 printk(" EFLAGS: %08lx %s (%s)\n",
268 regs->eflags, print_tainted(), system_utsname.release); 273 regs->eflags, print_tainted(), system_utsname.release);
@@ -325,6 +330,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
325 /* Ok, create the new process.. */ 330 /* Ok, create the new process.. */
326 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 331 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
327} 332}
333EXPORT_SYMBOL(kernel_thread);
328 334
329/* 335/*
330 * Free current thread data structures etc.. 336 * Free current thread data structures etc..
@@ -334,6 +340,13 @@ void exit_thread(void)
334 struct task_struct *tsk = current; 340 struct task_struct *tsk = current;
335 struct thread_struct *t = &tsk->thread; 341 struct thread_struct *t = &tsk->thread;
336 342
343 /*
344 * Remove function-return probe instances associated with this task
345 * and put them back on the free list. Do not insert an exit probe for
346 * this function, it will be disabled by kprobe_flush_task if you do.
347 */
348 kprobe_flush_task(tsk);
349
337 /* The process may have allocated an io port bitmap... nuke it. */ 350 /* The process may have allocated an io port bitmap... nuke it. */
338 if (unlikely(NULL != t->io_bitmap_ptr)) { 351 if (unlikely(NULL != t->io_bitmap_ptr)) {
339 int cpu = get_cpu(); 352 int cpu = get_cpu();
@@ -357,6 +370,13 @@ void flush_thread(void)
357{ 370{
358 struct task_struct *tsk = current; 371 struct task_struct *tsk = current;
359 372
373 /*
374 * Remove function-return probe instances associated with this task
375 * and put them back on the free list. Do not insert an exit probe for
376 * this function, it will be disabled by kprobe_flush_task if you do.
377 */
378 kprobe_flush_task(tsk);
379
360 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); 380 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
361 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 381 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
362 /* 382 /*
@@ -508,6 +528,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
508 528
509 dump->u_fpvalid = dump_fpu (regs, &dump->i387); 529 dump->u_fpvalid = dump_fpu (regs, &dump->i387);
510} 530}
531EXPORT_SYMBOL(dump_thread);
511 532
512/* 533/*
513 * Capture the user space registers if the task is not running (in user space) 534 * Capture the user space registers if the task is not running (in user space)
@@ -627,13 +648,13 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
627 * Now maybe reload the debug registers 648 * Now maybe reload the debug registers
628 */ 649 */
629 if (unlikely(next->debugreg[7])) { 650 if (unlikely(next->debugreg[7])) {
630 loaddebug(next, 0); 651 set_debugreg(current->thread.debugreg[0], 0);
631 loaddebug(next, 1); 652 set_debugreg(current->thread.debugreg[1], 1);
632 loaddebug(next, 2); 653 set_debugreg(current->thread.debugreg[2], 2);
633 loaddebug(next, 3); 654 set_debugreg(current->thread.debugreg[3], 3);
634 /* no 4 and 5 */ 655 /* no 4 and 5 */
635 loaddebug(next, 6); 656 set_debugreg(current->thread.debugreg[6], 6);
636 loaddebug(next, 7); 657 set_debugreg(current->thread.debugreg[7], 7);
637 } 658 }
638 659
639 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) 660 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
@@ -731,6 +752,7 @@ unsigned long get_wchan(struct task_struct *p)
731 } while (count++ < 16); 752 } while (count++ < 16);
732 return 0; 753 return 0;
733} 754}
755EXPORT_SYMBOL(get_wchan);
734 756
735/* 757/*
736 * sys_alloc_thread_area: get a yet unused TLS descriptor index. 758 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index e34f651fa13c..0da59b42843c 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -668,7 +668,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
668 info.si_code = TRAP_BRKPT; 668 info.si_code = TRAP_BRKPT;
669 669
670 /* User-mode eip? */ 670 /* User-mode eip? */
671 info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL; 671 info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
672 672
673 /* Send us the fakey SIGTRAP */ 673 /* Send us the fakey SIGTRAP */
674 force_sig_info(SIGTRAP, &info, tsk); 674 force_sig_info(SIGTRAP, &info, tsk);
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 6dc27eb70ee7..db912209a8d3 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -2,6 +2,7 @@
2 * linux/arch/i386/kernel/reboot.c 2 * linux/arch/i386/kernel/reboot.c
3 */ 3 */
4 4
5#include <linux/config.h>
5#include <linux/mm.h> 6#include <linux/mm.h>
6#include <linux/module.h> 7#include <linux/module.h>
7#include <linux/delay.h> 8#include <linux/delay.h>
@@ -19,6 +20,7 @@
19 * Power off function, if any 20 * Power off function, if any
20 */ 21 */
21void (*pm_power_off)(void); 22void (*pm_power_off)(void);
23EXPORT_SYMBOL(pm_power_off);
22 24
23static int reboot_mode; 25static int reboot_mode;
24static int reboot_thru_bios; 26static int reboot_thru_bios;
@@ -295,6 +297,9 @@ void machine_real_restart(unsigned char *code, int length)
295 : 297 :
296 : "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100))); 298 : "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
297} 299}
300#ifdef CONFIG_APM_MODULE
301EXPORT_SYMBOL(machine_real_restart);
302#endif
298 303
299void machine_restart(char * __unused) 304void machine_restart(char * __unused)
300{ 305{
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 2bfbddebdbf8..30406fd0b64c 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -23,8 +23,10 @@
23 * This file handles the architecture-dependent parts of initialization 23 * This file handles the architecture-dependent parts of initialization
24 */ 24 */
25 25
26#include <linux/config.h>
26#include <linux/sched.h> 27#include <linux/sched.h>
27#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/mmzone.h>
28#include <linux/tty.h> 30#include <linux/tty.h>
29#include <linux/ioport.h> 31#include <linux/ioport.h>
30#include <linux/acpi.h> 32#include <linux/acpi.h>
@@ -73,6 +75,7 @@ EXPORT_SYMBOL(efi_enabled);
73struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; 75struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
74/* common cpu data for all cpus */ 76/* common cpu data for all cpus */
75struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; 77struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
78EXPORT_SYMBOL(boot_cpu_data);
76 79
77unsigned long mmu_cr4_features; 80unsigned long mmu_cr4_features;
78 81
@@ -90,12 +93,18 @@ extern acpi_interrupt_flags acpi_sci_flags;
90 93
91/* for MCA, but anyone else can use it if they want */ 94/* for MCA, but anyone else can use it if they want */
92unsigned int machine_id; 95unsigned int machine_id;
96#ifdef CONFIG_MCA
97EXPORT_SYMBOL(machine_id);
98#endif
93unsigned int machine_submodel_id; 99unsigned int machine_submodel_id;
94unsigned int BIOS_revision; 100unsigned int BIOS_revision;
95unsigned int mca_pentium_flag; 101unsigned int mca_pentium_flag;
96 102
97/* For PCI or other memory-mapped resources */ 103/* For PCI or other memory-mapped resources */
98unsigned long pci_mem_start = 0x10000000; 104unsigned long pci_mem_start = 0x10000000;
105#ifdef CONFIG_PCI
106EXPORT_SYMBOL(pci_mem_start);
107#endif
99 108
100/* Boot loader ID as an integer, for the benefit of proc_dointvec */ 109/* Boot loader ID as an integer, for the benefit of proc_dointvec */
101int bootloader_type; 110int bootloader_type;
@@ -107,14 +116,26 @@ static unsigned int highmem_pages = -1;
107 * Setup options 116 * Setup options
108 */ 117 */
109struct drive_info_struct { char dummy[32]; } drive_info; 118struct drive_info_struct { char dummy[32]; } drive_info;
119#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
120 defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
121EXPORT_SYMBOL(drive_info);
122#endif
110struct screen_info screen_info; 123struct screen_info screen_info;
124#ifdef CONFIG_VT
125EXPORT_SYMBOL(screen_info);
126#endif
111struct apm_info apm_info; 127struct apm_info apm_info;
128EXPORT_SYMBOL(apm_info);
112struct sys_desc_table_struct { 129struct sys_desc_table_struct {
113 unsigned short length; 130 unsigned short length;
114 unsigned char table[0]; 131 unsigned char table[0];
115}; 132};
116struct edid_info edid_info; 133struct edid_info edid_info;
117struct ist_info ist_info; 134struct ist_info ist_info;
135#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
136 defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
137EXPORT_SYMBOL(ist_info);
138#endif
118struct e820map e820; 139struct e820map e820;
119 140
120extern void early_cpu_init(void); 141extern void early_cpu_init(void);
@@ -1022,7 +1043,7 @@ static void __init reserve_ebda_region(void)
1022 reserve_bootmem(addr, PAGE_SIZE); 1043 reserve_bootmem(addr, PAGE_SIZE);
1023} 1044}
1024 1045
1025#ifndef CONFIG_DISCONTIGMEM 1046#ifndef CONFIG_NEED_MULTIPLE_NODES
1026void __init setup_bootmem_allocator(void); 1047void __init setup_bootmem_allocator(void);
1027static unsigned long __init setup_memory(void) 1048static unsigned long __init setup_memory(void)
1028{ 1049{
@@ -1072,9 +1093,9 @@ void __init zone_sizes_init(void)
1072 free_area_init(zones_size); 1093 free_area_init(zones_size);
1073} 1094}
1074#else 1095#else
1075extern unsigned long setup_memory(void); 1096extern unsigned long __init setup_memory(void);
1076extern void zone_sizes_init(void); 1097extern void zone_sizes_init(void);
1077#endif /* !CONFIG_DISCONTIGMEM */ 1098#endif /* !CONFIG_NEED_MULTIPLE_NODES */
1078 1099
1079void __init setup_bootmem_allocator(void) 1100void __init setup_bootmem_allocator(void)
1080{ 1101{
@@ -1475,6 +1496,7 @@ void __init setup_arch(char **cmdline_p)
1475#endif 1496#endif
1476 paging_init(); 1497 paging_init();
1477 remapped_pgdat_init(); 1498 remapped_pgdat_init();
1499 sparse_init();
1478 zone_sizes_init(); 1500 zone_sizes_init();
1479 1501
1480 /* 1502 /*
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index ea46d028af08..b9b8f4e20fad 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -346,8 +346,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
346extern void __user __kernel_sigreturn; 346extern void __user __kernel_sigreturn;
347extern void __user __kernel_rt_sigreturn; 347extern void __user __kernel_rt_sigreturn;
348 348
349static void setup_frame(int sig, struct k_sigaction *ka, 349static int setup_frame(int sig, struct k_sigaction *ka,
350 sigset_t *set, struct pt_regs * regs) 350 sigset_t *set, struct pt_regs * regs)
351{ 351{
352 void __user *restorer; 352 void __user *restorer;
353 struct sigframe __user *frame; 353 struct sigframe __user *frame;
@@ -429,13 +429,14 @@ static void setup_frame(int sig, struct k_sigaction *ka,
429 current->comm, current->pid, frame, regs->eip, frame->pretcode); 429 current->comm, current->pid, frame, regs->eip, frame->pretcode);
430#endif 430#endif
431 431
432 return; 432 return 1;
433 433
434give_sigsegv: 434give_sigsegv:
435 force_sigsegv(sig, current); 435 force_sigsegv(sig, current);
436 return 0;
436} 437}
437 438
438static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 439static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
439 sigset_t *set, struct pt_regs * regs) 440 sigset_t *set, struct pt_regs * regs)
440{ 441{
441 void __user *restorer; 442 void __user *restorer;
@@ -522,20 +523,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
522 current->comm, current->pid, frame, regs->eip, frame->pretcode); 523 current->comm, current->pid, frame, regs->eip, frame->pretcode);
523#endif 524#endif
524 525
525 return; 526 return 1;
526 527
527give_sigsegv: 528give_sigsegv:
528 force_sigsegv(sig, current); 529 force_sigsegv(sig, current);
530 return 0;
529} 531}
530 532
531/* 533/*
532 * OK, we're invoking a handler 534 * OK, we're invoking a handler
533 */ 535 */
534 536
535static void 537static int
536handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 538handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
537 sigset_t *oldset, struct pt_regs * regs) 539 sigset_t *oldset, struct pt_regs * regs)
538{ 540{
541 int ret;
542
539 /* Are we from a system call? */ 543 /* Are we from a system call? */
540 if (regs->orig_eax >= 0) { 544 if (regs->orig_eax >= 0) {
541 /* If so, check system call restarting.. */ 545 /* If so, check system call restarting.. */
@@ -569,17 +573,19 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
569 573
570 /* Set up the stack frame */ 574 /* Set up the stack frame */
571 if (ka->sa.sa_flags & SA_SIGINFO) 575 if (ka->sa.sa_flags & SA_SIGINFO)
572 setup_rt_frame(sig, ka, info, oldset, regs); 576 ret = setup_rt_frame(sig, ka, info, oldset, regs);
573 else 577 else
574 setup_frame(sig, ka, oldset, regs); 578 ret = setup_frame(sig, ka, oldset, regs);
575 579
576 if (!(ka->sa.sa_flags & SA_NODEFER)) { 580 if (ret && !(ka->sa.sa_flags & SA_NODEFER)) {
577 spin_lock_irq(&current->sighand->siglock); 581 spin_lock_irq(&current->sighand->siglock);
578 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 582 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
579 sigaddset(&current->blocked,sig); 583 sigaddset(&current->blocked,sig);
580 recalc_sigpending(); 584 recalc_sigpending();
581 spin_unlock_irq(&current->sighand->siglock); 585 spin_unlock_irq(&current->sighand->siglock);
582 } 586 }
587
588 return ret;
583} 589}
584 590
585/* 591/*
@@ -599,7 +605,7 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
599 * kernel mode. Just return without doing anything 605 * kernel mode. Just return without doing anything
600 * if so. 606 * if so.
601 */ 607 */
602 if ((regs->xcs & 3) != 3) 608 if (!user_mode(regs))
603 return 1; 609 return 1;
604 610
605 if (current->flags & PF_FREEZE) { 611 if (current->flags & PF_FREEZE) {
@@ -618,12 +624,11 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
618 * inside the kernel. 624 * inside the kernel.
619 */ 625 */
620 if (unlikely(current->thread.debugreg[7])) { 626 if (unlikely(current->thread.debugreg[7])) {
621 loaddebug(&current->thread, 7); 627 set_debugreg(current->thread.debugreg[7], 7);
622 } 628 }
623 629
624 /* Whee! Actually deliver the signal. */ 630 /* Whee! Actually deliver the signal. */
625 handle_signal(signr, &info, &ka, oldset, regs); 631 return handle_signal(signr, &info, &ka, oldset, regs);
626 return 1;
627 } 632 }
628 633
629 no_signal: 634 no_signal:
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 6223c33ac91c..68be7d0c7238 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -19,6 +19,7 @@
19#include <linux/mc146818rtc.h> 19#include <linux/mc146818rtc.h>
20#include <linux/cache.h> 20#include <linux/cache.h>
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/module.h>
22 23
23#include <asm/mtrr.h> 24#include <asm/mtrr.h>
24#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
@@ -452,6 +453,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
452 453
453 preempt_enable(); 454 preempt_enable();
454} 455}
456EXPORT_SYMBOL(flush_tlb_page);
455 457
456static void do_flush_tlb_all(void* info) 458static void do_flush_tlb_all(void* info)
457{ 459{
@@ -547,6 +549,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
547 549
548 return 0; 550 return 0;
549} 551}
552EXPORT_SYMBOL(smp_call_function);
550 553
551static void stop_this_cpu (void * dummy) 554static void stop_this_cpu (void * dummy)
552{ 555{
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index bc1bb6919e6a..c20d96d5c15c 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -60,6 +60,9 @@ static int __initdata smp_b_stepping;
60 60
61/* Number of siblings per CPU package */ 61/* Number of siblings per CPU package */
62int smp_num_siblings = 1; 62int smp_num_siblings = 1;
63#ifdef CONFIG_X86_HT
64EXPORT_SYMBOL(smp_num_siblings);
65#endif
63int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ 66int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
64EXPORT_SYMBOL(phys_proc_id); 67EXPORT_SYMBOL(phys_proc_id);
65int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ 68int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
@@ -67,13 +70,16 @@ EXPORT_SYMBOL(cpu_core_id);
67 70
68/* bitmap of online cpus */ 71/* bitmap of online cpus */
69cpumask_t cpu_online_map; 72cpumask_t cpu_online_map;
73EXPORT_SYMBOL(cpu_online_map);
70 74
71cpumask_t cpu_callin_map; 75cpumask_t cpu_callin_map;
72cpumask_t cpu_callout_map; 76cpumask_t cpu_callout_map;
77EXPORT_SYMBOL(cpu_callout_map);
73static cpumask_t smp_commenced_mask; 78static cpumask_t smp_commenced_mask;
74 79
75/* Per CPU bogomips and other parameters */ 80/* Per CPU bogomips and other parameters */
76struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 81struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
82EXPORT_SYMBOL(cpu_data);
77 83
78u8 x86_cpu_to_apicid[NR_CPUS] = 84u8 x86_cpu_to_apicid[NR_CPUS] =
79 { [0 ... NR_CPUS-1] = 0xff }; 85 { [0 ... NR_CPUS-1] = 0xff };
@@ -199,7 +205,7 @@ static void __init synchronize_tsc_bp (void)
199 unsigned long long t0; 205 unsigned long long t0;
200 unsigned long long sum, avg; 206 unsigned long long sum, avg;
201 long long delta; 207 long long delta;
202 unsigned long one_usec; 208 unsigned int one_usec;
203 int buggy = 0; 209 int buggy = 0;
204 210
205 printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus()); 211 printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus());
@@ -885,8 +891,14 @@ static void smp_tune_scheduling (void)
885static int boot_cpu_logical_apicid; 891static int boot_cpu_logical_apicid;
886/* Where the IO area was mapped on multiquad, always 0 otherwise */ 892/* Where the IO area was mapped on multiquad, always 0 otherwise */
887void *xquad_portio; 893void *xquad_portio;
894#ifdef CONFIG_X86_NUMAQ
895EXPORT_SYMBOL(xquad_portio);
896#endif
888 897
889cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 898cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
899#ifdef CONFIG_X86_HT
900EXPORT_SYMBOL(cpu_sibling_map);
901#endif
890cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; 902cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
891EXPORT_SYMBOL(cpu_core_map); 903EXPORT_SYMBOL(cpu_core_map);
892 904
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index a0dcb7c87c30..e68d9fdb0759 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -77,11 +77,13 @@ u64 jiffies_64 = INITIAL_JIFFIES;
77 77
78EXPORT_SYMBOL(jiffies_64); 78EXPORT_SYMBOL(jiffies_64);
79 79
80unsigned long cpu_khz; /* Detected as we calibrate the TSC */ 80unsigned int cpu_khz; /* Detected as we calibrate the TSC */
81EXPORT_SYMBOL(cpu_khz);
81 82
82extern unsigned long wall_jiffies; 83extern unsigned long wall_jiffies;
83 84
84DEFINE_SPINLOCK(rtc_lock); 85DEFINE_SPINLOCK(rtc_lock);
86EXPORT_SYMBOL(rtc_lock);
85 87
86DEFINE_SPINLOCK(i8253_lock); 88DEFINE_SPINLOCK(i8253_lock);
87EXPORT_SYMBOL(i8253_lock); 89EXPORT_SYMBOL(i8253_lock);
@@ -324,6 +326,8 @@ unsigned long get_cmos_time(void)
324 326
325 return retval; 327 return retval;
326} 328}
329EXPORT_SYMBOL(get_cmos_time);
330
327static void sync_cmos_clock(unsigned long dummy); 331static void sync_cmos_clock(unsigned long dummy);
328 332
329static struct timer_list sync_cmos_timer = 333static struct timer_list sync_cmos_timer =
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c
index 8e201219f525..37353bd31803 100644
--- a/arch/i386/kernel/timers/common.c
+++ b/arch/i386/kernel/timers/common.c
@@ -139,6 +139,15 @@ bad_calibration:
139} 139}
140#endif 140#endif
141 141
142
143unsigned long read_timer_tsc(void)
144{
145 unsigned long retval;
146 rdtscl(retval);
147 return retval;
148}
149
150
142/* calculate cpu_khz */ 151/* calculate cpu_khz */
143void init_cpu_khz(void) 152void init_cpu_khz(void)
144{ 153{
@@ -154,7 +163,8 @@ void init_cpu_khz(void)
154 :"=a" (cpu_khz), "=d" (edx) 163 :"=a" (cpu_khz), "=d" (edx)
155 :"r" (tsc_quotient), 164 :"r" (tsc_quotient),
156 "0" (eax), "1" (edx)); 165 "0" (eax), "1" (edx));
157 printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); 166 printk("Detected %u.%03u MHz processor.\n",
167 cpu_khz / 1000, cpu_khz % 1000);
158 } 168 }
159 } 169 }
160 } 170 }
diff --git a/arch/i386/kernel/timers/timer.c b/arch/i386/kernel/timers/timer.c
index a3d6a288088b..7e39ed8e33f8 100644
--- a/arch/i386/kernel/timers/timer.c
+++ b/arch/i386/kernel/timers/timer.c
@@ -64,3 +64,12 @@ struct timer_opts* __init select_timer(void)
64 panic("select_timer: Cannot find a suitable timer\n"); 64 panic("select_timer: Cannot find a suitable timer\n");
65 return NULL; 65 return NULL;
66} 66}
67
68int read_current_timer(unsigned long *timer_val)
69{
70 if (cur_timer->read_timer) {
71 *timer_val = cur_timer->read_timer();
72 return 0;
73 }
74 return -1;
75}
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
index f778f471a09a..d766e0963ac1 100644
--- a/arch/i386/kernel/timers/timer_hpet.c
+++ b/arch/i386/kernel/timers/timer_hpet.c
@@ -158,7 +158,7 @@ static int __init init_hpet(char* override)
158 { unsigned long eax=0, edx=1000; 158 { unsigned long eax=0, edx=1000;
159 ASM_DIV64_REG(cpu_khz, edx, tsc_quotient, 159 ASM_DIV64_REG(cpu_khz, edx, tsc_quotient,
160 eax, edx); 160 eax, edx);
161 printk("Detected %lu.%03lu MHz processor.\n", 161 printk("Detected %u.%03u MHz processor.\n",
162 cpu_khz / 1000, cpu_khz % 1000); 162 cpu_khz / 1000, cpu_khz % 1000);
163 } 163 }
164 set_cyc2ns_scale(cpu_khz/1000); 164 set_cyc2ns_scale(cpu_khz/1000);
@@ -186,6 +186,7 @@ static struct timer_opts timer_hpet = {
186 .get_offset = get_offset_hpet, 186 .get_offset = get_offset_hpet,
187 .monotonic_clock = monotonic_clock_hpet, 187 .monotonic_clock = monotonic_clock_hpet,
188 .delay = delay_hpet, 188 .delay = delay_hpet,
189 .read_timer = read_timer_tsc,
189}; 190};
190 191
191struct init_timer_opts __initdata timer_hpet_init = { 192struct init_timer_opts __initdata timer_hpet_init = {
diff --git a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c
index d77f22030fe6..4ef20e663498 100644
--- a/arch/i386/kernel/timers/timer_pm.c
+++ b/arch/i386/kernel/timers/timer_pm.c
@@ -246,6 +246,7 @@ static struct timer_opts timer_pmtmr = {
246 .get_offset = get_offset_pmtmr, 246 .get_offset = get_offset_pmtmr,
247 .monotonic_clock = monotonic_clock_pmtmr, 247 .monotonic_clock = monotonic_clock_pmtmr,
248 .delay = delay_pmtmr, 248 .delay = delay_pmtmr,
249 .read_timer = read_timer_tsc,
249}; 250};
250 251
251struct init_timer_opts __initdata timer_pmtmr_init = { 252struct init_timer_opts __initdata timer_pmtmr_init = {
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 180444d87824..54c36b182021 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -256,7 +256,7 @@ static unsigned long loops_per_jiffy_ref = 0;
256 256
257#ifndef CONFIG_SMP 257#ifndef CONFIG_SMP
258static unsigned long fast_gettimeoffset_ref = 0; 258static unsigned long fast_gettimeoffset_ref = 0;
259static unsigned long cpu_khz_ref = 0; 259static unsigned int cpu_khz_ref = 0;
260#endif 260#endif
261 261
262static int 262static int
@@ -323,7 +323,7 @@ static inline void cpufreq_delayed_get(void) { return; }
323int recalibrate_cpu_khz(void) 323int recalibrate_cpu_khz(void)
324{ 324{
325#ifndef CONFIG_SMP 325#ifndef CONFIG_SMP
326 unsigned long cpu_khz_old = cpu_khz; 326 unsigned int cpu_khz_old = cpu_khz;
327 327
328 if (cpu_has_tsc) { 328 if (cpu_has_tsc) {
329 init_cpu_khz(); 329 init_cpu_khz();
@@ -534,7 +534,8 @@ static int __init init_tsc(char* override)
534 :"=a" (cpu_khz), "=d" (edx) 534 :"=a" (cpu_khz), "=d" (edx)
535 :"r" (tsc_quotient), 535 :"r" (tsc_quotient),
536 "0" (eax), "1" (edx)); 536 "0" (eax), "1" (edx));
537 printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); 537 printk("Detected %u.%03u MHz processor.\n",
538 cpu_khz / 1000, cpu_khz % 1000);
538 } 539 }
539 set_cyc2ns_scale(cpu_khz/1000); 540 set_cyc2ns_scale(cpu_khz/1000);
540 return 0; 541 return 0;
@@ -572,6 +573,7 @@ static struct timer_opts timer_tsc = {
572 .get_offset = get_offset_tsc, 573 .get_offset = get_offset_tsc,
573 .monotonic_clock = monotonic_clock_tsc, 574 .monotonic_clock = monotonic_clock_tsc,
574 .delay = delay_tsc, 575 .delay = delay_tsc,
576 .read_timer = read_timer_tsc,
575}; 577};
576 578
577struct init_timer_opts __initdata timer_tsc_init = { 579struct init_timer_opts __initdata timer_tsc_init = {
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 83c579e82a81..e4d4e2162c7a 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -104,6 +104,7 @@ int register_die_notifier(struct notifier_block *nb)
104 spin_unlock_irqrestore(&die_notifier_lock, flags); 104 spin_unlock_irqrestore(&die_notifier_lock, flags);
105 return err; 105 return err;
106} 106}
107EXPORT_SYMBOL(register_die_notifier);
107 108
108static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) 109static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
109{ 110{
@@ -209,7 +210,7 @@ void show_registers(struct pt_regs *regs)
209 210
210 esp = (unsigned long) (&regs->esp); 211 esp = (unsigned long) (&regs->esp);
211 ss = __KERNEL_DS; 212 ss = __KERNEL_DS;
212 if (regs->xcs & 3) { 213 if (user_mode(regs)) {
213 in_kernel = 0; 214 in_kernel = 0;
214 esp = regs->esp; 215 esp = regs->esp;
215 ss = regs->xss & 0xffff; 216 ss = regs->xss & 0xffff;
@@ -265,7 +266,7 @@ static void handle_BUG(struct pt_regs *regs)
265 char c; 266 char c;
266 unsigned long eip; 267 unsigned long eip;
267 268
268 if (regs->xcs & 3) 269 if (user_mode(regs))
269 goto no_bug; /* Not in kernel */ 270 goto no_bug; /* Not in kernel */
270 271
271 eip = regs->eip; 272 eip = regs->eip;
@@ -353,7 +354,7 @@ void die(const char * str, struct pt_regs * regs, long err)
353 354
354static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) 355static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
355{ 356{
356 if (!(regs->eflags & VM_MASK) && !(3 & regs->xcs)) 357 if (!user_mode_vm(regs))
357 die(str, regs, err); 358 die(str, regs, err);
358} 359}
359 360
@@ -366,7 +367,7 @@ static void do_trap(int trapnr, int signr, char *str, int vm86,
366 goto trap_signal; 367 goto trap_signal;
367 } 368 }
368 369
369 if (!(regs->xcs & 3)) 370 if (!user_mode(regs))
370 goto kernel_trap; 371 goto kernel_trap;
371 372
372 trap_signal: { 373 trap_signal: {
@@ -488,7 +489,7 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
488 if (regs->eflags & VM_MASK) 489 if (regs->eflags & VM_MASK)
489 goto gp_in_vm86; 490 goto gp_in_vm86;
490 491
491 if (!(regs->xcs & 3)) 492 if (!user_mode(regs))
492 goto gp_in_kernel; 493 goto gp_in_kernel;
493 494
494 current->thread.error_code = error_code; 495 current->thread.error_code = error_code;
@@ -636,11 +637,13 @@ void set_nmi_callback(nmi_callback_t callback)
636{ 637{
637 nmi_callback = callback; 638 nmi_callback = callback;
638} 639}
640EXPORT_SYMBOL_GPL(set_nmi_callback);
639 641
640void unset_nmi_callback(void) 642void unset_nmi_callback(void)
641{ 643{
642 nmi_callback = dummy_nmi_callback; 644 nmi_callback = dummy_nmi_callback;
643} 645}
646EXPORT_SYMBOL_GPL(unset_nmi_callback);
644 647
645#ifdef CONFIG_KPROBES 648#ifdef CONFIG_KPROBES
646fastcall void do_int3(struct pt_regs *regs, long error_code) 649fastcall void do_int3(struct pt_regs *regs, long error_code)
@@ -682,7 +685,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
682 unsigned int condition; 685 unsigned int condition;
683 struct task_struct *tsk = current; 686 struct task_struct *tsk = current;
684 687
685 __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); 688 get_debugreg(condition, 6);
686 689
687 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, 690 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
688 SIGTRAP) == NOTIFY_STOP) 691 SIGTRAP) == NOTIFY_STOP)
@@ -713,7 +716,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
713 * check for kernel mode by just checking the CPL 716 * check for kernel mode by just checking the CPL
714 * of CS. 717 * of CS.
715 */ 718 */
716 if ((regs->xcs & 3) == 0) 719 if (!user_mode(regs))
717 goto clear_TF_reenable; 720 goto clear_TF_reenable;
718 } 721 }
719 722
@@ -724,9 +727,7 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
724 * the signal is delivered. 727 * the signal is delivered.
725 */ 728 */
726clear_dr7: 729clear_dr7:
727 __asm__("movl %0,%%db7" 730 set_debugreg(0, 7);
728 : /* no output */
729 : "r" (0));
730 return; 731 return;
731 732
732debug_vm86: 733debug_vm86:
diff --git a/arch/i386/lib/dec_and_lock.c b/arch/i386/lib/dec_and_lock.c
index ab43394dc775..8b81b2524fa6 100644
--- a/arch/i386/lib/dec_and_lock.c
+++ b/arch/i386/lib/dec_and_lock.c
@@ -8,6 +8,7 @@
8 */ 8 */
9 9
10#include <linux/spinlock.h> 10#include <linux/spinlock.h>
11#include <linux/module.h>
11#include <asm/atomic.h> 12#include <asm/atomic.h>
12 13
13int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) 14int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
@@ -38,3 +39,4 @@ slow_path:
38 spin_unlock(lock); 39 spin_unlock(lock);
39 return 0; 40 return 0;
40} 41}
42EXPORT_SYMBOL(_atomic_dec_and_lock);
diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
index eb0cdfe9280f..c49a6acbee56 100644
--- a/arch/i386/lib/delay.c
+++ b/arch/i386/lib/delay.c
@@ -13,6 +13,7 @@
13#include <linux/config.h> 13#include <linux/config.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/module.h>
16#include <asm/processor.h> 17#include <asm/processor.h>
17#include <asm/delay.h> 18#include <asm/delay.h>
18#include <asm/timer.h> 19#include <asm/timer.h>
@@ -47,3 +48,8 @@ void __ndelay(unsigned long nsecs)
47{ 48{
48 __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ 49 __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
49} 50}
51
52EXPORT_SYMBOL(__delay);
53EXPORT_SYMBOL(__const_udelay);
54EXPORT_SYMBOL(__udelay);
55EXPORT_SYMBOL(__ndelay);
diff --git a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c
index 01f8b1a2cc84..2afda94dffd3 100644
--- a/arch/i386/lib/mmx.c
+++ b/arch/i386/lib/mmx.c
@@ -3,6 +3,7 @@
3#include <linux/string.h> 3#include <linux/string.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/hardirq.h> 5#include <linux/hardirq.h>
6#include <linux/module.h>
6 7
7#include <asm/i387.h> 8#include <asm/i387.h>
8 9
@@ -397,3 +398,7 @@ void mmx_copy_page(void *to, void *from)
397 else 398 else
398 fast_copy_page(to, from); 399 fast_copy_page(to, from);
399} 400}
401
402EXPORT_SYMBOL(_mmx_memcpy);
403EXPORT_SYMBOL(mmx_clear_page);
404EXPORT_SYMBOL(mmx_copy_page);
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index 51aa2bbb0269..4cf981d70f45 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -84,6 +84,7 @@ __strncpy_from_user(char *dst, const char __user *src, long count)
84 __do_strncpy_from_user(dst, src, count, res); 84 __do_strncpy_from_user(dst, src, count, res);
85 return res; 85 return res;
86} 86}
87EXPORT_SYMBOL(__strncpy_from_user);
87 88
88/** 89/**
89 * strncpy_from_user: - Copy a NUL terminated string from userspace. 90 * strncpy_from_user: - Copy a NUL terminated string from userspace.
@@ -111,7 +112,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
111 __do_strncpy_from_user(dst, src, count, res); 112 __do_strncpy_from_user(dst, src, count, res);
112 return res; 113 return res;
113} 114}
114 115EXPORT_SYMBOL(strncpy_from_user);
115 116
116/* 117/*
117 * Zero Userspace 118 * Zero Userspace
@@ -157,6 +158,7 @@ clear_user(void __user *to, unsigned long n)
157 __do_clear_user(to, n); 158 __do_clear_user(to, n);
158 return n; 159 return n;
159} 160}
161EXPORT_SYMBOL(clear_user);
160 162
161/** 163/**
162 * __clear_user: - Zero a block of memory in user space, with less checking. 164 * __clear_user: - Zero a block of memory in user space, with less checking.
@@ -175,6 +177,7 @@ __clear_user(void __user *to, unsigned long n)
175 __do_clear_user(to, n); 177 __do_clear_user(to, n);
176 return n; 178 return n;
177} 179}
180EXPORT_SYMBOL(__clear_user);
178 181
179/** 182/**
180 * strlen_user: - Get the size of a string in user space. 183 * strlen_user: - Get the size of a string in user space.
@@ -218,6 +221,7 @@ long strnlen_user(const char __user *s, long n)
218 :"cc"); 221 :"cc");
219 return res & mask; 222 return res & mask;
220} 223}
224EXPORT_SYMBOL(strnlen_user);
221 225
222#ifdef CONFIG_X86_INTEL_USERCOPY 226#ifdef CONFIG_X86_INTEL_USERCOPY
223static unsigned long 227static unsigned long
@@ -570,6 +574,7 @@ survive:
570 n = __copy_user_intel(to, from, n); 574 n = __copy_user_intel(to, from, n);
571 return n; 575 return n;
572} 576}
577EXPORT_SYMBOL(__copy_to_user_ll);
573 578
574unsigned long 579unsigned long
575__copy_from_user_ll(void *to, const void __user *from, unsigned long n) 580__copy_from_user_ll(void *to, const void __user *from, unsigned long n)
@@ -581,6 +586,7 @@ __copy_from_user_ll(void *to, const void __user *from, unsigned long n)
581 n = __copy_user_zeroing_intel(to, from, n); 586 n = __copy_user_zeroing_intel(to, from, n);
582 return n; 587 return n;
583} 588}
589EXPORT_SYMBOL(__copy_from_user_ll);
584 590
585/** 591/**
586 * copy_to_user: - Copy a block of data into user space. 592 * copy_to_user: - Copy a block of data into user space.
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index a6e0ddd65bd0..8c8527593da0 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -1288,7 +1288,7 @@ smp_local_timer_interrupt(struct pt_regs * regs)
1288 per_cpu(prof_counter, cpu); 1288 per_cpu(prof_counter, cpu);
1289 } 1289 }
1290 1290
1291 update_process_times(user_mode(regs)); 1291 update_process_times(user_mode_vm(regs));
1292 } 1292 }
1293 1293
1294 if( ((1<<cpu) & voyager_extended_vic_processors) == 0) 1294 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile
index fc3272506846..80908b5aa60f 100644
--- a/arch/i386/mm/Makefile
+++ b/arch/i386/mm/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o 5obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o
6 6
7obj-$(CONFIG_DISCONTIGMEM) += discontig.o 7obj-$(CONFIG_NUMA) += discontig.o
8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
9obj-$(CONFIG_HIGHMEM) += highmem.o 9obj-$(CONFIG_HIGHMEM) += highmem.o
10obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o 10obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 1726b4096b10..f429c871e845 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -29,12 +29,14 @@
29#include <linux/highmem.h> 29#include <linux/highmem.h>
30#include <linux/initrd.h> 30#include <linux/initrd.h>
31#include <linux/nodemask.h> 31#include <linux/nodemask.h>
32#include <linux/module.h>
32#include <asm/e820.h> 33#include <asm/e820.h>
33#include <asm/setup.h> 34#include <asm/setup.h>
34#include <asm/mmzone.h> 35#include <asm/mmzone.h>
35#include <bios_ebda.h> 36#include <bios_ebda.h>
36 37
37struct pglist_data *node_data[MAX_NUMNODES]; 38struct pglist_data *node_data[MAX_NUMNODES];
39EXPORT_SYMBOL(node_data);
38bootmem_data_t node0_bdata; 40bootmem_data_t node0_bdata;
39 41
40/* 42/*
@@ -42,12 +44,16 @@ bootmem_data_t node0_bdata;
42 * populated the following initialisation. 44 * populated the following initialisation.
43 * 45 *
44 * 1) node_online_map - the map of all nodes configured (online) in the system 46 * 1) node_online_map - the map of all nodes configured (online) in the system
45 * 2) physnode_map - the mapping between a pfn and owning node 47 * 2) node_start_pfn - the starting page frame number for a node
46 * 3) node_start_pfn - the starting page frame number for a node
47 * 3) node_end_pfn - the ending page fram number for a node 48 * 3) node_end_pfn - the ending page fram number for a node
48 */ 49 */
50unsigned long node_start_pfn[MAX_NUMNODES];
51unsigned long node_end_pfn[MAX_NUMNODES];
52
49 53
54#ifdef CONFIG_DISCONTIGMEM
50/* 55/*
56 * 4) physnode_map - the mapping between a pfn and owning node
51 * physnode_map keeps track of the physical memory layout of a generic 57 * physnode_map keeps track of the physical memory layout of a generic
52 * numa node on a 256Mb break (each element of the array will 58 * numa node on a 256Mb break (each element of the array will
53 * represent 256Mb of memory and will be marked by the node id. so, 59 * represent 256Mb of memory and will be marked by the node id. so,
@@ -59,6 +65,7 @@ bootmem_data_t node0_bdata;
59 * physnode_map[8- ] = -1; 65 * physnode_map[8- ] = -1;
60 */ 66 */
61s8 physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1}; 67s8 physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1};
68EXPORT_SYMBOL(physnode_map);
62 69
63void memory_present(int nid, unsigned long start, unsigned long end) 70void memory_present(int nid, unsigned long start, unsigned long end)
64{ 71{
@@ -85,9 +92,7 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn,
85 92
86 return (nr_pages + 1) * sizeof(struct page); 93 return (nr_pages + 1) * sizeof(struct page);
87} 94}
88 95#endif
89unsigned long node_start_pfn[MAX_NUMNODES];
90unsigned long node_end_pfn[MAX_NUMNODES];
91 96
92extern unsigned long find_max_low_pfn(void); 97extern unsigned long find_max_low_pfn(void);
93extern void find_max_pfn(void); 98extern void find_max_pfn(void);
@@ -108,6 +113,9 @@ unsigned long node_remap_offset[MAX_NUMNODES];
108void *node_remap_start_vaddr[MAX_NUMNODES]; 113void *node_remap_start_vaddr[MAX_NUMNODES];
109void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); 114void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
110 115
116void *node_remap_end_vaddr[MAX_NUMNODES];
117void *node_remap_alloc_vaddr[MAX_NUMNODES];
118
111/* 119/*
112 * FLAT - support for basic PC memory model with discontig enabled, essentially 120 * FLAT - support for basic PC memory model with discontig enabled, essentially
113 * a single node with all available processors in it with a flat 121 * a single node with all available processors in it with a flat
@@ -146,6 +154,21 @@ static void __init find_max_pfn_node(int nid)
146 BUG(); 154 BUG();
147} 155}
148 156
157/* Find the owning node for a pfn. */
158int early_pfn_to_nid(unsigned long pfn)
159{
160 int nid;
161
162 for_each_node(nid) {
163 if (node_end_pfn[nid] == 0)
164 break;
165 if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn)
166 return nid;
167 }
168
169 return 0;
170}
171
149/* 172/*
150 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem 173 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem
151 * method. For node zero take this from the bottom of memory, for 174 * method. For node zero take this from the bottom of memory, for
@@ -163,6 +186,21 @@ static void __init allocate_pgdat(int nid)
163 } 186 }
164} 187}
165 188
189void *alloc_remap(int nid, unsigned long size)
190{
191 void *allocation = node_remap_alloc_vaddr[nid];
192
193 size = ALIGN(size, L1_CACHE_BYTES);
194
195 if (!allocation || (allocation + size) >= node_remap_end_vaddr[nid])
196 return 0;
197
198 node_remap_alloc_vaddr[nid] += size;
199 memset(allocation, 0, size);
200
201 return allocation;
202}
203
166void __init remap_numa_kva(void) 204void __init remap_numa_kva(void)
167{ 205{
168 void *vaddr; 206 void *vaddr;
@@ -170,8 +208,6 @@ void __init remap_numa_kva(void)
170 int node; 208 int node;
171 209
172 for_each_online_node(node) { 210 for_each_online_node(node) {
173 if (node == 0)
174 continue;
175 for (pfn=0; pfn < node_remap_size[node]; pfn += PTRS_PER_PTE) { 211 for (pfn=0; pfn < node_remap_size[node]; pfn += PTRS_PER_PTE) {
176 vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT); 212 vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT);
177 set_pmd_pfn((ulong) vaddr, 213 set_pmd_pfn((ulong) vaddr,
@@ -185,13 +221,9 @@ static unsigned long calculate_numa_remap_pages(void)
185{ 221{
186 int nid; 222 int nid;
187 unsigned long size, reserve_pages = 0; 223 unsigned long size, reserve_pages = 0;
224 unsigned long pfn;
188 225
189 for_each_online_node(nid) { 226 for_each_online_node(nid) {
190 if (nid == 0)
191 continue;
192 if (!node_remap_size[nid])
193 continue;
194
195 /* 227 /*
196 * The acpi/srat node info can show hot-add memroy zones 228 * The acpi/srat node info can show hot-add memroy zones
197 * where memory could be added but not currently present. 229 * where memory could be added but not currently present.
@@ -208,11 +240,24 @@ static unsigned long calculate_numa_remap_pages(void)
208 size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES; 240 size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES;
209 /* now the roundup is correct, convert to PAGE_SIZE pages */ 241 /* now the roundup is correct, convert to PAGE_SIZE pages */
210 size = size * PTRS_PER_PTE; 242 size = size * PTRS_PER_PTE;
243
244 /*
245 * Validate the region we are allocating only contains valid
246 * pages.
247 */
248 for (pfn = node_end_pfn[nid] - size;
249 pfn < node_end_pfn[nid]; pfn++)
250 if (!page_is_ram(pfn))
251 break;
252
253 if (pfn != node_end_pfn[nid])
254 size = 0;
255
211 printk("Reserving %ld pages of KVA for lmem_map of node %d\n", 256 printk("Reserving %ld pages of KVA for lmem_map of node %d\n",
212 size, nid); 257 size, nid);
213 node_remap_size[nid] = size; 258 node_remap_size[nid] = size;
214 reserve_pages += size;
215 node_remap_offset[nid] = reserve_pages; 259 node_remap_offset[nid] = reserve_pages;
260 reserve_pages += size;
216 printk("Shrinking node %d from %ld pages to %ld pages\n", 261 printk("Shrinking node %d from %ld pages to %ld pages\n",
217 nid, node_end_pfn[nid], node_end_pfn[nid] - size); 262 nid, node_end_pfn[nid], node_end_pfn[nid] - size);
218 node_end_pfn[nid] -= size; 263 node_end_pfn[nid] -= size;
@@ -265,12 +310,18 @@ unsigned long __init setup_memory(void)
265 (ulong) pfn_to_kaddr(max_low_pfn)); 310 (ulong) pfn_to_kaddr(max_low_pfn));
266 for_each_online_node(nid) { 311 for_each_online_node(nid) {
267 node_remap_start_vaddr[nid] = pfn_to_kaddr( 312 node_remap_start_vaddr[nid] = pfn_to_kaddr(
268 (highstart_pfn + reserve_pages) - node_remap_offset[nid]); 313 highstart_pfn + node_remap_offset[nid]);
314 /* Init the node remap allocator */
315 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
316 (node_remap_size[nid] * PAGE_SIZE);
317 node_remap_alloc_vaddr[nid] = node_remap_start_vaddr[nid] +
318 ALIGN(sizeof(pg_data_t), PAGE_SIZE);
319
269 allocate_pgdat(nid); 320 allocate_pgdat(nid);
270 printk ("node %d will remap to vaddr %08lx - %08lx\n", nid, 321 printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
271 (ulong) node_remap_start_vaddr[nid], 322 (ulong) node_remap_start_vaddr[nid],
272 (ulong) pfn_to_kaddr(highstart_pfn + reserve_pages 323 (ulong) pfn_to_kaddr(highstart_pfn
273 - node_remap_offset[nid] + node_remap_size[nid])); 324 + node_remap_offset[nid] + node_remap_size[nid]));
274 } 325 }
275 printk("High memory starts at vaddr %08lx\n", 326 printk("High memory starts at vaddr %08lx\n",
276 (ulong) pfn_to_kaddr(highstart_pfn)); 327 (ulong) pfn_to_kaddr(highstart_pfn));
@@ -333,23 +384,9 @@ void __init zone_sizes_init(void)
333 } 384 }
334 385
335 zholes_size = get_zholes_size(nid); 386 zholes_size = get_zholes_size(nid);
336 /* 387
337 * We let the lmem_map for node 0 be allocated from the 388 free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
338 * normal bootmem allocator, but other nodes come from the 389 zholes_size);
339 * remapped KVA area - mbligh
340 */
341 if (!nid)
342 free_area_init_node(nid, NODE_DATA(nid),
343 zones_size, start, zholes_size);
344 else {
345 unsigned long lmem_map;
346 lmem_map = (unsigned long)node_remap_start_vaddr[nid];
347 lmem_map += sizeof(pg_data_t) + PAGE_SIZE - 1;
348 lmem_map &= PAGE_MASK;
349 NODE_DATA(nid)->node_mem_map = (struct page *)lmem_map;
350 free_area_init_node(nid, NODE_DATA(nid), zones_size,
351 start, zholes_size);
352 }
353 } 390 }
354 return; 391 return;
355} 392}
@@ -358,24 +395,26 @@ void __init set_highmem_pages_init(int bad_ppro)
358{ 395{
359#ifdef CONFIG_HIGHMEM 396#ifdef CONFIG_HIGHMEM
360 struct zone *zone; 397 struct zone *zone;
398 struct page *page;
361 399
362 for_each_zone(zone) { 400 for_each_zone(zone) {
363 unsigned long node_pfn, node_high_size, zone_start_pfn; 401 unsigned long node_pfn, zone_start_pfn, zone_end_pfn;
364 struct page * zone_mem_map; 402
365
366 if (!is_highmem(zone)) 403 if (!is_highmem(zone))
367 continue; 404 continue;
368 405
369 printk("Initializing %s for node %d\n", zone->name,
370 zone->zone_pgdat->node_id);
371
372 node_high_size = zone->spanned_pages;
373 zone_mem_map = zone->zone_mem_map;
374 zone_start_pfn = zone->zone_start_pfn; 406 zone_start_pfn = zone->zone_start_pfn;
407 zone_end_pfn = zone_start_pfn + zone->spanned_pages;
408
409 printk("Initializing %s for node %d (%08lx:%08lx)\n",
410 zone->name, zone->zone_pgdat->node_id,
411 zone_start_pfn, zone_end_pfn);
375 412
376 for (node_pfn = 0; node_pfn < node_high_size; node_pfn++) { 413 for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) {
377 one_highpage_init((struct page *)(zone_mem_map + node_pfn), 414 if (!pfn_valid(node_pfn))
378 zone_start_pfn + node_pfn, bad_ppro); 415 continue;
416 page = pfn_to_page(node_pfn);
417 one_highpage_init(page, node_pfn, bad_ppro);
379 } 418 }
380 } 419 }
381 totalram_pages += totalhigh_pages; 420 totalram_pages += totalhigh_pages;
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
index fc4c4cad4e98..4b7aaf99d7ea 100644
--- a/arch/i386/mm/highmem.c
+++ b/arch/i386/mm/highmem.c
@@ -1,4 +1,5 @@
1#include <linux/highmem.h> 1#include <linux/highmem.h>
2#include <linux/module.h>
2 3
3void *kmap(struct page *page) 4void *kmap(struct page *page)
4{ 5{
@@ -87,3 +88,8 @@ struct page *kmap_atomic_to_page(void *ptr)
87 return pte_page(*pte); 88 return pte_page(*pte);
88} 89}
89 90
91EXPORT_SYMBOL(kmap);
92EXPORT_SYMBOL(kunmap);
93EXPORT_SYMBOL(kmap_atomic);
94EXPORT_SYMBOL(kunmap_atomic);
95EXPORT_SYMBOL(kmap_atomic_to_page);
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 8766c771bb45..3672e2ef51ae 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -191,7 +191,7 @@ static inline int page_kills_ppro(unsigned long pagenr)
191 191
192extern int is_available_memory(efi_memory_desc_t *); 192extern int is_available_memory(efi_memory_desc_t *);
193 193
194static inline int page_is_ram(unsigned long pagenr) 194int page_is_ram(unsigned long pagenr)
195{ 195{
196 int i; 196 int i;
197 unsigned long addr, end; 197 unsigned long addr, end;
@@ -276,7 +276,9 @@ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
276 SetPageReserved(page); 276 SetPageReserved(page);
277} 277}
278 278
279#ifndef CONFIG_DISCONTIGMEM 279#ifdef CONFIG_NUMA
280extern void set_highmem_pages_init(int);
281#else
280static void __init set_highmem_pages_init(int bad_ppro) 282static void __init set_highmem_pages_init(int bad_ppro)
281{ 283{
282 int pfn; 284 int pfn;
@@ -284,9 +286,7 @@ static void __init set_highmem_pages_init(int bad_ppro)
284 one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); 286 one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
285 totalram_pages += totalhigh_pages; 287 totalram_pages += totalhigh_pages;
286} 288}
287#else 289#endif /* CONFIG_FLATMEM */
288extern void set_highmem_pages_init(int);
289#endif /* !CONFIG_DISCONTIGMEM */
290 290
291#else 291#else
292#define kmap_init() do { } while (0) 292#define kmap_init() do { } while (0)
@@ -295,12 +295,13 @@ extern void set_highmem_pages_init(int);
295#endif /* CONFIG_HIGHMEM */ 295#endif /* CONFIG_HIGHMEM */
296 296
297unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; 297unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
298EXPORT_SYMBOL(__PAGE_KERNEL);
298unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; 299unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
299 300
300#ifndef CONFIG_DISCONTIGMEM 301#ifdef CONFIG_NUMA
301#define remap_numa_kva() do {} while (0)
302#else
303extern void __init remap_numa_kva(void); 302extern void __init remap_numa_kva(void);
303#else
304#define remap_numa_kva() do {} while (0)
304#endif 305#endif
305 306
306static void __init pagetable_init (void) 307static void __init pagetable_init (void)
@@ -525,7 +526,7 @@ static void __init set_max_mapnr_init(void)
525#else 526#else
526 num_physpages = max_low_pfn; 527 num_physpages = max_low_pfn;
527#endif 528#endif
528#ifndef CONFIG_DISCONTIGMEM 529#ifdef CONFIG_FLATMEM
529 max_mapnr = num_physpages; 530 max_mapnr = num_physpages;
530#endif 531#endif
531} 532}
@@ -539,7 +540,7 @@ void __init mem_init(void)
539 int tmp; 540 int tmp;
540 int bad_ppro; 541 int bad_ppro;
541 542
542#ifndef CONFIG_DISCONTIGMEM 543#ifdef CONFIG_FLATMEM
543 if (!mem_map) 544 if (!mem_map)
544 BUG(); 545 BUG();
545#endif 546#endif
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index ab542792b27b..d393eefc7052 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -11,6 +11,7 @@
11#include <linux/vmalloc.h> 11#include <linux/vmalloc.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/module.h>
14#include <asm/io.h> 15#include <asm/io.h>
15#include <asm/fixmap.h> 16#include <asm/fixmap.h>
16#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
@@ -165,7 +166,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
165 } 166 }
166 return (void __iomem *) (offset + (char __iomem *)addr); 167 return (void __iomem *) (offset + (char __iomem *)addr);
167} 168}
168 169EXPORT_SYMBOL(__ioremap);
169 170
170/** 171/**
171 * ioremap_nocache - map bus memory into CPU space 172 * ioremap_nocache - map bus memory into CPU space
@@ -222,6 +223,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
222 223
223 return p; 224 return p;
224} 225}
226EXPORT_SYMBOL(ioremap_nocache);
225 227
226void iounmap(volatile void __iomem *addr) 228void iounmap(volatile void __iomem *addr)
227{ 229{
@@ -255,6 +257,7 @@ out_unlock:
255 write_unlock(&vmlist_lock); 257 write_unlock(&vmlist_lock);
256 kfree(p); 258 kfree(p);
257} 259}
260EXPORT_SYMBOL(iounmap);
258 261
259void __init *bt_ioremap(unsigned long phys_addr, unsigned long size) 262void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
260{ 263{
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index dd81479ff88a..270c59f099a4 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -30,13 +30,14 @@ void show_mem(void)
30 struct page *page; 30 struct page *page;
31 pg_data_t *pgdat; 31 pg_data_t *pgdat;
32 unsigned long i; 32 unsigned long i;
33 struct page_state ps;
33 34
34 printk("Mem-info:\n"); 35 printk("Mem-info:\n");
35 show_free_areas(); 36 show_free_areas();
36 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 37 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
37 for_each_pgdat(pgdat) { 38 for_each_pgdat(pgdat) {
38 for (i = 0; i < pgdat->node_spanned_pages; ++i) { 39 for (i = 0; i < pgdat->node_spanned_pages; ++i) {
39 page = pgdat->node_mem_map + i; 40 page = pgdat_page_nr(pgdat, i);
40 total++; 41 total++;
41 if (PageHighMem(page)) 42 if (PageHighMem(page))
42 highmem++; 43 highmem++;
@@ -53,6 +54,13 @@ void show_mem(void)
53 printk("%d reserved pages\n",reserved); 54 printk("%d reserved pages\n",reserved);
54 printk("%d pages shared\n",shared); 55 printk("%d pages shared\n",shared);
55 printk("%d pages swap cached\n",cached); 56 printk("%d pages swap cached\n",cached);
57
58 get_page_state(&ps);
59 printk("%lu pages dirty\n", ps.nr_dirty);
60 printk("%lu pages writeback\n", ps.nr_writeback);
61 printk("%lu pages mapped\n", ps.nr_mapped);
62 printk("%lu pages slab\n", ps.nr_slab);
63 printk("%lu pages pagetables\n", ps.nr_page_table_pages);
56} 64}
57 65
58/* 66/*
diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c
index 52d72e074f7f..65dfd2edb671 100644
--- a/arch/i386/oprofile/backtrace.c
+++ b/arch/i386/oprofile/backtrace.c
@@ -91,7 +91,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
91 head = (struct frame_head *)regs->ebp; 91 head = (struct frame_head *)regs->ebp;
92#endif 92#endif
93 93
94 if (!user_mode(regs)) { 94 if (!user_mode_vm(regs)) {
95 while (depth-- && valid_kernel_stack(head, regs)) 95 while (depth-- && valid_kernel_stack(head, regs))
96 head = dump_backtrace(head); 96 head = dump_backtrace(head);
97 return; 97 return;
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index da21b1d07c15..83458f81e661 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -227,6 +227,24 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i
227} 227}
228 228
229/* 229/*
230 * The VIA pirq rules are nibble-based, like ALI,
231 * but without the ugly irq number munging.
232 * However, for 82C586, nibble map is different .
233 */
234static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
235{
236 static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
237 return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
238}
239
240static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
241{
242 static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
243 write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
244 return 1;
245}
246
247/*
230 * ITE 8330G pirq rules are nibble-based 248 * ITE 8330G pirq rules are nibble-based
231 * FIXME: pirqmap may be { 1, 0, 3, 2 }, 249 * FIXME: pirqmap may be { 1, 0, 3, 2 },
232 * 2+3 are both mapped to irq 9 on my system 250 * 2+3 are both mapped to irq 9 on my system
@@ -512,6 +530,10 @@ static __init int via_router_probe(struct irq_router *r, struct pci_dev *router,
512 switch(device) 530 switch(device)
513 { 531 {
514 case PCI_DEVICE_ID_VIA_82C586_0: 532 case PCI_DEVICE_ID_VIA_82C586_0:
533 r->name = "VIA";
534 r->get = pirq_via586_get;
535 r->set = pirq_via586_set;
536 return 1;
515 case PCI_DEVICE_ID_VIA_82C596: 537 case PCI_DEVICE_ID_VIA_82C596:
516 case PCI_DEVICE_ID_VIA_82C686: 538 case PCI_DEVICE_ID_VIA_82C686:
517 case PCI_DEVICE_ID_VIA_8231: 539 case PCI_DEVICE_ID_VIA_8231:
diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
index 141421b673b0..b9d65f0bc2d1 100644
--- a/arch/i386/pci/pcbios.c
+++ b/arch/i386/pci/pcbios.c
@@ -4,6 +4,7 @@
4 4
5#include <linux/pci.h> 5#include <linux/pci.h>
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/module.h>
7#include "pci.h" 8#include "pci.h"
8#include "pci-functions.h" 9#include "pci-functions.h"
9 10
@@ -456,7 +457,7 @@ struct irq_routing_table * __devinit pcibios_get_irq_routing_table(void)
456 free_page(page); 457 free_page(page);
457 return rt; 458 return rt;
458} 459}
459 460EXPORT_SYMBOL(pcibios_get_irq_routing_table);
460 461
461int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq) 462int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
462{ 463{
@@ -473,6 +474,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
473 "S" (&pci_indirect)); 474 "S" (&pci_indirect));
474 return !(ret & 0xff00); 475 return !(ret & 0xff00);
475} 476}
477EXPORT_SYMBOL(pcibios_set_irq_routing);
476 478
477static int __init pci_pcbios_init(void) 479static int __init pci_pcbios_init(void)
478{ 480{
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index cf337c673d92..6f521cf19a13 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -94,13 +94,13 @@ static void fix_processor_context(void)
94 * Now maybe reload the debug registers 94 * Now maybe reload the debug registers
95 */ 95 */
96 if (current->thread.debugreg[7]){ 96 if (current->thread.debugreg[7]){
97 loaddebug(&current->thread, 0); 97 set_debugreg(current->thread.debugreg[0], 0);
98 loaddebug(&current->thread, 1); 98 set_debugreg(current->thread.debugreg[1], 1);
99 loaddebug(&current->thread, 2); 99 set_debugreg(current->thread.debugreg[2], 2);
100 loaddebug(&current->thread, 3); 100 set_debugreg(current->thread.debugreg[3], 3);
101 /* no 4 and 5 */ 101 /* no 4 and 5 */
102 loaddebug(&current->thread, 6); 102 set_debugreg(current->thread.debugreg[6], 6);
103 loaddebug(&current->thread, 7); 103 set_debugreg(current->thread.debugreg[7], 7);
104 } 104 }
105 105
106} 106}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index ce4dfa8b834d..01b78e7f992e 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -161,6 +161,8 @@ config IA64_PAGE_SIZE_64KB
161 161
162endchoice 162endchoice
163 163
164source kernel/Kconfig.hz
165
164config IA64_BRL_EMU 166config IA64_BRL_EMU
165 bool 167 bool
166 depends on ITANIUM 168 depends on ITANIUM
@@ -197,7 +199,7 @@ config HOLES_IN_ZONE
197 bool 199 bool
198 default y if VIRTUAL_MEM_MAP 200 default y if VIRTUAL_MEM_MAP
199 201
200config DISCONTIGMEM 202config ARCH_DISCONTIGMEM_ENABLE
201 bool "Discontiguous memory support" 203 bool "Discontiguous memory support"
202 depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP 204 depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
203 default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA 205 default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
@@ -300,6 +302,8 @@ config PREEMPT
300 Say Y here if you are building a kernel for a desktop, embedded 302 Say Y here if you are building a kernel for a desktop, embedded
301 or real-time system. Say N if you are unsure. 303 or real-time system. Say N if you are unsure.
302 304
305source "mm/Kconfig"
306
303config HAVE_DEC_LOCK 307config HAVE_DEC_LOCK
304 bool 308 bool
305 depends on (SMP || PREEMPT) 309 depends on (SMP || PREEMPT)
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
index de9d507ba0fd..fda67ac993d7 100644
--- a/arch/ia64/Kconfig.debug
+++ b/arch/ia64/Kconfig.debug
@@ -2,6 +2,17 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config KPROBES
6 bool "Kprobes"
7 depends on DEBUG_KERNEL
8 help
9 Kprobes allows you to trap at almost any kernel address and
10 execute a callback function. register_kprobe() establishes
11 a probepoint and specifies the callback. Kprobes is useful
12 for kernel debugging, non-intrusive instrumentation and testing.
13 If in doubt, say "N".
14
15
5choice 16choice
6 prompt "Physical memory granularity" 17 prompt "Physical memory granularity"
7 default IA64_GRANULE_64MB 18 default IA64_GRANULE_64MB
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index a01bb02d074d..487d2e36b0a6 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -78,7 +78,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7
78CONFIG_NUMA=y 78CONFIG_NUMA=y
79CONFIG_VIRTUAL_MEM_MAP=y 79CONFIG_VIRTUAL_MEM_MAP=y
80CONFIG_HOLES_IN_ZONE=y 80CONFIG_HOLES_IN_ZONE=y
81CONFIG_DISCONTIGMEM=y 81CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
82# CONFIG_IA64_CYCLONE is not set 82# CONFIG_IA64_CYCLONE is not set
83CONFIG_IOSAPIC=y 83CONFIG_IOSAPIC=y
84CONFIG_IA64_SGI_SN_SIM=y 84CONFIG_IA64_SGI_SN_SIM=y
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 7be8096e0561..8444add76380 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -84,7 +84,7 @@ CONFIG_IA64_L1_CACHE_SHIFT=7
84CONFIG_NUMA=y 84CONFIG_NUMA=y
85CONFIG_VIRTUAL_MEM_MAP=y 85CONFIG_VIRTUAL_MEM_MAP=y
86CONFIG_HOLES_IN_ZONE=y 86CONFIG_HOLES_IN_ZONE=y
87CONFIG_DISCONTIGMEM=y 87CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
88CONFIG_IA64_CYCLONE=y 88CONFIG_IA64_CYCLONE=y
89CONFIG_IOSAPIC=y 89CONFIG_IOSAPIC=y
90CONFIG_FORCE_MAX_ZONEORDER=18 90CONFIG_FORCE_MAX_ZONEORDER=18
diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
index b2de948bdaea..e3e9290e3ff2 100644
--- a/arch/ia64/ia32/ia32priv.h
+++ b/arch/ia64/ia32/ia32priv.h
@@ -241,7 +241,7 @@ typedef struct compat_siginfo {
241 241
242 /* POSIX.1b timers */ 242 /* POSIX.1b timers */
243 struct { 243 struct {
244 timer_t _tid; /* timer id */ 244 compat_timer_t _tid; /* timer id */
245 int _overrun; /* overrun count */ 245 int _overrun; /* overrun count */
246 char _pad[sizeof(unsigned int) - sizeof(int)]; 246 char _pad[sizeof(unsigned int) - sizeof(int)];
247 compat_sigval_t _sigval; /* same as below */ 247 compat_sigval_t _sigval; /* same as below */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 4c73d8ba2e3d..b2e2f6509eb0 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o
20obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o 20obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
21obj-$(CONFIG_IA64_CYCLONE) += cyclone.o 21obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
22obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o 22obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
23obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
23obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o 24obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
24mca_recovery-y += mca_drv.o mca_drv_asm.o 25mca_recovery-y += mca_drv.o mca_drv_asm.o
25 26
diff --git a/arch/ia64/kernel/jprobes.S b/arch/ia64/kernel/jprobes.S
new file mode 100644
index 000000000000..b7fa3ccd2b0f
--- /dev/null
+++ b/arch/ia64/kernel/jprobes.S
@@ -0,0 +1,61 @@
1/*
2 * Jprobe specific operations
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) Intel Corporation, 2005
19 *
20 * 2005-May Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
21 * <anil.s.keshavamurthy@intel.com> initial implementation
22 *
23 * Jprobes (a.k.a. "jump probes" which is built on-top of kprobes) allow a
24 * probe to be inserted into the beginning of a function call. The fundamental
25 * difference between a jprobe and a kprobe is the jprobe handler is executed
26 * in the same context as the target function, while the kprobe handlers
27 * are executed in interrupt context.
28 *
29 * For jprobes we initially gain control by placing a break point in the
30 * first instruction of the targeted function. When we catch that specific
31 * break, we:
32 * * set the return address to our jprobe_inst_return() function
33 * * jump to the jprobe handler function
34 *
35 * Since we fixed up the return address, the jprobe handler will return to our
36 * jprobe_inst_return() function, giving us control again. At this point we
37 * are back in the parents frame marker, so we do yet another call to our
38 * jprobe_break() function to fix up the frame marker as it would normally
39 * exist in the target function.
40 *
41 * Our jprobe_return function then transfers control back to kprobes.c by
42 * executing a break instruction using one of our reserved numbers. When we
43 * catch that break in kprobes.c, we continue like we do for a normal kprobe
44 * by single stepping the emulated instruction, and then returning execution
45 * to the correct location.
46 */
47#include <asm/asmmacro.h>
48
49 /*
50 * void jprobe_break(void)
51 */
52ENTRY(jprobe_break)
53 break.m 0x80300
54END(jprobe_break)
55
56 /*
57 * void jprobe_inst_return(void)
58 */
59GLOBAL_ENTRY(jprobe_inst_return)
60 br.call.sptk.many b0=jprobe_break
61END(jprobe_inst_return)
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
new file mode 100644
index 000000000000..5978823d5c63
--- /dev/null
+++ b/arch/ia64/kernel/kprobes.c
@@ -0,0 +1,601 @@
1/*
2 * Kernel Probes (KProbes)
3 * arch/ia64/kernel/kprobes.c
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 * Copyright (C) IBM Corporation, 2002, 2004
20 * Copyright (C) Intel Corporation, 2005
21 *
22 * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
23 * <anil.s.keshavamurthy@intel.com> adapted from i386
24 */
25
26#include <linux/config.h>
27#include <linux/kprobes.h>
28#include <linux/ptrace.h>
29#include <linux/spinlock.h>
30#include <linux/string.h>
31#include <linux/slab.h>
32#include <linux/preempt.h>
33#include <linux/moduleloader.h>
34
35#include <asm/pgtable.h>
36#include <asm/kdebug.h>
37
38extern void jprobe_inst_return(void);
39
40/* kprobe_status settings */
41#define KPROBE_HIT_ACTIVE 0x00000001
42#define KPROBE_HIT_SS 0x00000002
43
44static struct kprobe *current_kprobe, *kprobe_prev;
45static unsigned long kprobe_status, kprobe_status_prev;
46static struct pt_regs jprobe_saved_regs;
47
48enum instruction_type {A, I, M, F, B, L, X, u};
49static enum instruction_type bundle_encoding[32][3] = {
50 { M, I, I }, /* 00 */
51 { M, I, I }, /* 01 */
52 { M, I, I }, /* 02 */
53 { M, I, I }, /* 03 */
54 { M, L, X }, /* 04 */
55 { M, L, X }, /* 05 */
56 { u, u, u }, /* 06 */
57 { u, u, u }, /* 07 */
58 { M, M, I }, /* 08 */
59 { M, M, I }, /* 09 */
60 { M, M, I }, /* 0A */
61 { M, M, I }, /* 0B */
62 { M, F, I }, /* 0C */
63 { M, F, I }, /* 0D */
64 { M, M, F }, /* 0E */
65 { M, M, F }, /* 0F */
66 { M, I, B }, /* 10 */
67 { M, I, B }, /* 11 */
68 { M, B, B }, /* 12 */
69 { M, B, B }, /* 13 */
70 { u, u, u }, /* 14 */
71 { u, u, u }, /* 15 */
72 { B, B, B }, /* 16 */
73 { B, B, B }, /* 17 */
74 { M, M, B }, /* 18 */
75 { M, M, B }, /* 19 */
76 { u, u, u }, /* 1A */
77 { u, u, u }, /* 1B */
78 { M, F, B }, /* 1C */
79 { M, F, B }, /* 1D */
80 { u, u, u }, /* 1E */
81 { u, u, u }, /* 1F */
82};
83
84/*
85 * In this function we check to see if the instruction
86 * is IP relative instruction and update the kprobe
87 * inst flag accordingly
88 */
89static void update_kprobe_inst_flag(uint template, uint slot, uint major_opcode,
90 unsigned long kprobe_inst, struct kprobe *p)
91{
92 p->ainsn.inst_flag = 0;
93 p->ainsn.target_br_reg = 0;
94
95 if (bundle_encoding[template][slot] == B) {
96 switch (major_opcode) {
97 case INDIRECT_CALL_OPCODE:
98 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
99 p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
100 break;
101 case IP_RELATIVE_PREDICT_OPCODE:
102 case IP_RELATIVE_BRANCH_OPCODE:
103 p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
104 break;
105 case IP_RELATIVE_CALL_OPCODE:
106 p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
107 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
108 p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
109 break;
110 }
111 } else if (bundle_encoding[template][slot] == X) {
112 switch (major_opcode) {
113 case LONG_CALL_OPCODE:
114 p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
115 p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
116 break;
117 }
118 }
119 return;
120}
121
122/*
123 * In this function we check to see if the instruction
124 * on which we are inserting kprobe is supported.
125 * Returns 0 if supported
126 * Returns -EINVAL if unsupported
127 */
128static int unsupported_inst(uint template, uint slot, uint major_opcode,
129 unsigned long kprobe_inst, struct kprobe *p)
130{
131 unsigned long addr = (unsigned long)p->addr;
132
133 if (bundle_encoding[template][slot] == I) {
134 switch (major_opcode) {
135 case 0x0: //I_UNIT_MISC_OPCODE:
136 /*
137 * Check for Integer speculation instruction
138 * - Bit 33-35 to be equal to 0x1
139 */
140 if (((kprobe_inst >> 33) & 0x7) == 1) {
141 printk(KERN_WARNING
142 "Kprobes on speculation inst at <0x%lx> not supported\n",
143 addr);
144 return -EINVAL;
145 }
146
147 /*
148 * IP relative mov instruction
149 * - Bit 27-35 to be equal to 0x30
150 */
151 if (((kprobe_inst >> 27) & 0x1FF) == 0x30) {
152 printk(KERN_WARNING
153 "Kprobes on \"mov r1=ip\" at <0x%lx> not supported\n",
154 addr);
155 return -EINVAL;
156
157 }
158 }
159 }
160 return 0;
161}
162
163
164/*
165 * In this function we check to see if the instruction
166 * (qp) cmpx.crel.ctype p1,p2=r2,r3
167 * on which we are inserting kprobe is cmp instruction
168 * with ctype as unc.
169 */
170static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode,
171unsigned long kprobe_inst)
172{
173 cmp_inst_t cmp_inst;
174 uint ctype_unc = 0;
175
176 if (!((bundle_encoding[template][slot] == I) ||
177 (bundle_encoding[template][slot] == M)))
178 goto out;
179
180 if (!((major_opcode == 0xC) || (major_opcode == 0xD) ||
181 (major_opcode == 0xE)))
182 goto out;
183
184 cmp_inst.l = kprobe_inst;
185 if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
186 /* Integere compare - Register Register (A6 type)*/
187 if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
188 &&(cmp_inst.f.c == 1))
189 ctype_unc = 1;
190 } else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
191 /* Integere compare - Immediate Register (A8 type)*/
192 if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
193 ctype_unc = 1;
194 }
195out:
196 return ctype_unc;
197}
198
199/*
200 * In this function we override the bundle with
201 * the break instruction at the given slot.
202 */
203static void prepare_break_inst(uint template, uint slot, uint major_opcode,
204 unsigned long kprobe_inst, struct kprobe *p)
205{
206 unsigned long break_inst = BREAK_INST;
207 bundle_t *bundle = &p->ainsn.insn.bundle;
208
209 /*
210 * Copy the original kprobe_inst qualifying predicate(qp)
211 * to the break instruction iff !is_cmp_ctype_unc_inst
212 * because for cmp instruction with ctype equal to unc,
213 * which is a special instruction always needs to be
214 * executed regradless of qp
215 */
216 if (!is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst))
217 break_inst |= (0x3f & kprobe_inst);
218
219 switch (slot) {
220 case 0:
221 bundle->quad0.slot0 = break_inst;
222 break;
223 case 1:
224 bundle->quad0.slot1_p0 = break_inst;
225 bundle->quad1.slot1_p1 = break_inst >> (64-46);
226 break;
227 case 2:
228 bundle->quad1.slot2 = break_inst;
229 break;
230 }
231
232 /*
233 * Update the instruction flag, so that we can
234 * emulate the instruction properly after we
235 * single step on original instruction
236 */
237 update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
238}
239
240static inline void get_kprobe_inst(bundle_t *bundle, uint slot,
241 unsigned long *kprobe_inst, uint *major_opcode)
242{
243 unsigned long kprobe_inst_p0, kprobe_inst_p1;
244 unsigned int template;
245
246 template = bundle->quad0.template;
247
248 switch (slot) {
249 case 0:
250 *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
251 *kprobe_inst = bundle->quad0.slot0;
252 break;
253 case 1:
254 *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
255 kprobe_inst_p0 = bundle->quad0.slot1_p0;
256 kprobe_inst_p1 = bundle->quad1.slot1_p1;
257 *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
258 break;
259 case 2:
260 *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
261 *kprobe_inst = bundle->quad1.slot2;
262 break;
263 }
264}
265
266static int valid_kprobe_addr(int template, int slot, unsigned long addr)
267{
268 if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
269 printk(KERN_WARNING "Attempting to insert unaligned kprobe at 0x%lx\n",
270 addr);
271 return -EINVAL;
272 }
273 return 0;
274}
275
276static inline void save_previous_kprobe(void)
277{
278 kprobe_prev = current_kprobe;
279 kprobe_status_prev = kprobe_status;
280}
281
282static inline void restore_previous_kprobe(void)
283{
284 current_kprobe = kprobe_prev;
285 kprobe_status = kprobe_status_prev;
286}
287
288static inline void set_current_kprobe(struct kprobe *p)
289{
290 current_kprobe = p;
291}
292
293int arch_prepare_kprobe(struct kprobe *p)
294{
295 unsigned long addr = (unsigned long) p->addr;
296 unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
297 unsigned long kprobe_inst=0;
298 unsigned int slot = addr & 0xf, template, major_opcode = 0;
299 bundle_t *bundle = &p->ainsn.insn.bundle;
300
301 memcpy(&p->opcode.bundle, kprobe_addr, sizeof(bundle_t));
302 memcpy(&p->ainsn.insn.bundle, kprobe_addr, sizeof(bundle_t));
303
304 template = bundle->quad0.template;
305
306 if(valid_kprobe_addr(template, slot, addr))
307 return -EINVAL;
308
309 /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
310 if (slot == 1 && bundle_encoding[template][1] == L)
311 slot++;
312
313 /* Get kprobe_inst and major_opcode from the bundle */
314 get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
315
316 if (unsupported_inst(template, slot, major_opcode, kprobe_inst, p))
317 return -EINVAL;
318
319 prepare_break_inst(template, slot, major_opcode, kprobe_inst, p);
320
321 return 0;
322}
323
324void arch_arm_kprobe(struct kprobe *p)
325{
326 unsigned long addr = (unsigned long)p->addr;
327 unsigned long arm_addr = addr & ~0xFULL;
328
329 memcpy((char *)arm_addr, &p->ainsn.insn.bundle, sizeof(bundle_t));
330 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
331}
332
333void arch_disarm_kprobe(struct kprobe *p)
334{
335 unsigned long addr = (unsigned long)p->addr;
336 unsigned long arm_addr = addr & ~0xFULL;
337
338 /* p->opcode contains the original unaltered bundle */
339 memcpy((char *) arm_addr, (char *) &p->opcode.bundle, sizeof(bundle_t));
340 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
341}
342
343void arch_remove_kprobe(struct kprobe *p)
344{
345}
346
347/*
348 * We are resuming execution after a single step fault, so the pt_regs
349 * structure reflects the register state after we executed the instruction
350 * located in the kprobe (p->ainsn.insn.bundle). We still need to adjust
351 * the ip to point back to the original stack address. To set the IP address
352 * to original stack address, handle the case where we need to fixup the
353 * relative IP address and/or fixup branch register.
354 */
355static void resume_execution(struct kprobe *p, struct pt_regs *regs)
356{
357 unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL;
358 unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
359 unsigned long template;
360 int slot = ((unsigned long)p->addr & 0xf);
361
362 template = p->opcode.bundle.quad0.template;
363
364 if (slot == 1 && bundle_encoding[template][1] == L)
365 slot = 2;
366
367 if (p->ainsn.inst_flag) {
368
369 if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
370 /* Fix relative IP address */
371 regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr;
372 }
373
374 if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
375 /*
376 * Fix target branch register, software convention is
377 * to use either b0 or b6 or b7, so just checking
378 * only those registers
379 */
380 switch (p->ainsn.target_br_reg) {
381 case 0:
382 if ((regs->b0 == bundle_addr) ||
383 (regs->b0 == bundle_addr + 0x10)) {
384 regs->b0 = (regs->b0 - bundle_addr) +
385 resume_addr;
386 }
387 break;
388 case 6:
389 if ((regs->b6 == bundle_addr) ||
390 (regs->b6 == bundle_addr + 0x10)) {
391 regs->b6 = (regs->b6 - bundle_addr) +
392 resume_addr;
393 }
394 break;
395 case 7:
396 if ((regs->b7 == bundle_addr) ||
397 (regs->b7 == bundle_addr + 0x10)) {
398 regs->b7 = (regs->b7 - bundle_addr) +
399 resume_addr;
400 }
401 break;
402 } /* end switch */
403 }
404 goto turn_ss_off;
405 }
406
407 if (slot == 2) {
408 if (regs->cr_iip == bundle_addr + 0x10) {
409 regs->cr_iip = resume_addr + 0x10;
410 }
411 } else {
412 if (regs->cr_iip == bundle_addr) {
413 regs->cr_iip = resume_addr;
414 }
415 }
416
417turn_ss_off:
418 /* Turn off Single Step bit */
419 ia64_psr(regs)->ss = 0;
420}
421
422static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
423{
424 unsigned long bundle_addr = (unsigned long) &p->opcode.bundle;
425 unsigned long slot = (unsigned long)p->addr & 0xf;
426
427 /* Update instruction pointer (IIP) and slot number (IPSR.ri) */
428 regs->cr_iip = bundle_addr & ~0xFULL;
429
430 if (slot > 2)
431 slot = 0;
432
433 ia64_psr(regs)->ri = slot;
434
435 /* turn on single stepping */
436 ia64_psr(regs)->ss = 1;
437}
438
439static int pre_kprobes_handler(struct die_args *args)
440{
441 struct kprobe *p;
442 int ret = 0;
443 struct pt_regs *regs = args->regs;
444 kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
445
446 preempt_disable();
447
448 /* Handle recursion cases */
449 if (kprobe_running()) {
450 p = get_kprobe(addr);
451 if (p) {
452 if (kprobe_status == KPROBE_HIT_SS) {
453 unlock_kprobes();
454 goto no_kprobe;
455 }
456 /* We have reentered the pre_kprobe_handler(), since
457 * another probe was hit while within the handler.
458 * We here save the original kprobes variables and
459 * just single step on the instruction of the new probe
460 * without calling any user handlers.
461 */
462 save_previous_kprobe();
463 set_current_kprobe(p);
464 p->nmissed++;
465 prepare_ss(p, regs);
466 kprobe_status = KPROBE_REENTER;
467 return 1;
468 } else if (args->err == __IA64_BREAK_JPROBE) {
469 /*
470 * jprobe instrumented function just completed
471 */
472 p = current_kprobe;
473 if (p->break_handler && p->break_handler(p, regs)) {
474 goto ss_probe;
475 }
476 } else {
477 /* Not our break */
478 goto no_kprobe;
479 }
480 }
481
482 lock_kprobes();
483 p = get_kprobe(addr);
484 if (!p) {
485 unlock_kprobes();
486 goto no_kprobe;
487 }
488
489 kprobe_status = KPROBE_HIT_ACTIVE;
490 set_current_kprobe(p);
491
492 if (p->pre_handler && p->pre_handler(p, regs))
493 /*
494 * Our pre-handler is specifically requesting that we just
495 * do a return. This is handling the case where the
496 * pre-handler is really our special jprobe pre-handler.
497 */
498 return 1;
499
500ss_probe:
501 prepare_ss(p, regs);
502 kprobe_status = KPROBE_HIT_SS;
503 return 1;
504
505no_kprobe:
506 preempt_enable_no_resched();
507 return ret;
508}
509
510static int post_kprobes_handler(struct pt_regs *regs)
511{
512 if (!kprobe_running())
513 return 0;
514
515 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
516 kprobe_status = KPROBE_HIT_SSDONE;
517 current_kprobe->post_handler(current_kprobe, regs, 0);
518 }
519
520 resume_execution(current_kprobe, regs);
521
522 /*Restore back the original saved kprobes variables and continue. */
523 if (kprobe_status == KPROBE_REENTER) {
524 restore_previous_kprobe();
525 goto out;
526 }
527
528 unlock_kprobes();
529
530out:
531 preempt_enable_no_resched();
532 return 1;
533}
534
535static int kprobes_fault_handler(struct pt_regs *regs, int trapnr)
536{
537 if (!kprobe_running())
538 return 0;
539
540 if (current_kprobe->fault_handler &&
541 current_kprobe->fault_handler(current_kprobe, regs, trapnr))
542 return 1;
543
544 if (kprobe_status & KPROBE_HIT_SS) {
545 resume_execution(current_kprobe, regs);
546 unlock_kprobes();
547 preempt_enable_no_resched();
548 }
549
550 return 0;
551}
552
553int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
554 void *data)
555{
556 struct die_args *args = (struct die_args *)data;
557 switch(val) {
558 case DIE_BREAK:
559 if (pre_kprobes_handler(args))
560 return NOTIFY_STOP;
561 break;
562 case DIE_SS:
563 if (post_kprobes_handler(args->regs))
564 return NOTIFY_STOP;
565 break;
566 case DIE_PAGE_FAULT:
567 if (kprobes_fault_handler(args->regs, args->trapnr))
568 return NOTIFY_STOP;
569 default:
570 break;
571 }
572 return NOTIFY_DONE;
573}
574
575int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
576{
577 struct jprobe *jp = container_of(p, struct jprobe, kp);
578 unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
579
580 /* save architectural state */
581 jprobe_saved_regs = *regs;
582
583 /* after rfi, execute the jprobe instrumented function */
584 regs->cr_iip = addr & ~0xFULL;
585 ia64_psr(regs)->ri = addr & 0xf;
586 regs->r1 = ((struct fnptr *)(jp->entry))->gp;
587
588 /*
589 * fix the return address to our jprobe_inst_return() function
590 * in the jprobes.S file
591 */
592 regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
593
594 return 1;
595}
596
597int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
598{
599 *regs = jprobe_saved_regs;
600 return 1;
601}
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 1861173bd4f6..e7e520d90f03 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -21,12 +21,26 @@
21#include <asm/intrinsics.h> 21#include <asm/intrinsics.h>
22#include <asm/processor.h> 22#include <asm/processor.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/kdebug.h>
24 25
25extern spinlock_t timerlist_lock; 26extern spinlock_t timerlist_lock;
26 27
27fpswa_interface_t *fpswa_interface; 28fpswa_interface_t *fpswa_interface;
28EXPORT_SYMBOL(fpswa_interface); 29EXPORT_SYMBOL(fpswa_interface);
29 30
31struct notifier_block *ia64die_chain;
32static DEFINE_SPINLOCK(die_notifier_lock);
33
34int register_die_notifier(struct notifier_block *nb)
35{
36 int err = 0;
37 unsigned long flags;
38 spin_lock_irqsave(&die_notifier_lock, flags);
39 err = notifier_chain_register(&ia64die_chain, nb);
40 spin_unlock_irqrestore(&die_notifier_lock, flags);
41 return err;
42}
43
30void __init 44void __init
31trap_init (void) 45trap_init (void)
32{ 46{
@@ -137,6 +151,10 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
137 151
138 switch (break_num) { 152 switch (break_num) {
139 case 0: /* unknown error (used by GCC for __builtin_abort()) */ 153 case 0: /* unknown error (used by GCC for __builtin_abort()) */
154 if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
155 == NOTIFY_STOP) {
156 return;
157 }
140 die_if_kernel("bugcheck!", regs, break_num); 158 die_if_kernel("bugcheck!", regs, break_num);
141 sig = SIGILL; code = ILL_ILLOPC; 159 sig = SIGILL; code = ILL_ILLOPC;
142 break; 160 break;
@@ -189,6 +207,15 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
189 sig = SIGILL; code = __ILL_BNDMOD; 207 sig = SIGILL; code = __ILL_BNDMOD;
190 break; 208 break;
191 209
210 case 0x80200:
211 case 0x80300:
212 if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
213 == NOTIFY_STOP) {
214 return;
215 }
216 sig = SIGTRAP; code = TRAP_BRKPT;
217 break;
218
192 default: 219 default:
193 if (break_num < 0x40000 || break_num > 0x100000) 220 if (break_num < 0x40000 || break_num > 0x100000)
194 die_if_kernel("Bad break", regs, break_num); 221 die_if_kernel("Bad break", regs, break_num);
@@ -548,7 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
548#endif 575#endif
549 break; 576 break;
550 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; 577 case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
551 case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; 578 case 36:
579 if (notify_die(DIE_SS, "ss", &regs, vector,
580 vector, SIGTRAP) == NOTIFY_STOP)
581 return;
582 siginfo.si_code = TRAP_TRACE; ifa = 0; break;
552 } 583 }
553 siginfo.si_signo = SIGTRAP; 584 siginfo.si_signo = SIGTRAP;
554 siginfo.si_errno = 0; 585 siginfo.si_errno = 0;
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index c00710929390..f3fd528ead3b 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -560,14 +560,15 @@ void show_mem(void)
560 int shared = 0, cached = 0, reserved = 0; 560 int shared = 0, cached = 0, reserved = 0;
561 printk("Node ID: %d\n", pgdat->node_id); 561 printk("Node ID: %d\n", pgdat->node_id);
562 for(i = 0; i < pgdat->node_spanned_pages; i++) { 562 for(i = 0; i < pgdat->node_spanned_pages; i++) {
563 struct page *page = pgdat_page_nr(pgdat, i);
563 if (!ia64_pfn_valid(pgdat->node_start_pfn+i)) 564 if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
564 continue; 565 continue;
565 if (PageReserved(pgdat->node_mem_map+i)) 566 if (PageReserved(page))
566 reserved++; 567 reserved++;
567 else if (PageSwapCache(pgdat->node_mem_map+i)) 568 else if (PageSwapCache(page))
568 cached++; 569 cached++;
569 else if (page_count(pgdat->node_mem_map+i)) 570 else if (page_count(page))
570 shared += page_count(pgdat->node_mem_map+i)-1; 571 shared += page_count(page)-1;
571 } 572 }
572 total_present += present; 573 total_present += present;
573 total_reserved += reserved; 574 total_reserved += reserved;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 4174ec999dde..ff62551eb3a1 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -14,6 +14,7 @@
14#include <asm/processor.h> 14#include <asm/processor.h>
15#include <asm/system.h> 15#include <asm/system.h>
16#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17#include <asm/kdebug.h>
17 18
18extern void die (char *, struct pt_regs *, long); 19extern void die (char *, struct pt_regs *, long);
19 20
@@ -102,6 +103,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
102 goto bad_area_no_up; 103 goto bad_area_no_up;
103#endif 104#endif
104 105
106 /*
107 * This is to handle the kprobes on user space access instructions
108 */
109 if (notify_die(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT,
110 SIGSEGV) == NOTIFY_STOP)
111 return;
112
105 down_read(&mm->mmap_sem); 113 down_read(&mm->mmap_sem);
106 114
107 vma = find_vma_prev(mm, address, &prev_vma); 115 vma = find_vma_prev(mm, address, &prev_vma);
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 64c133344afe..42ca8a39798d 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -172,11 +172,13 @@ config NOHIGHMEM
172 bool 172 bool
173 default y 173 default y
174 174
175config DISCONTIGMEM 175config ARCH_DISCONTIGMEM_ENABLE
176 bool "Internal RAM Support" 176 bool "Internal RAM Support"
177 depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP 177 depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP
178 default y 178 default y
179 179
180source "mm/Kconfig"
181
180config IRAM_START 182config IRAM_START
181 hex "Internal memory start address (hex)" 183 hex "Internal memory start address (hex)"
182 default "00f00000" 184 default "00f00000"
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index bc423d838fb8..d9a40b1fe8ba 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -49,7 +49,7 @@ void show_mem(void)
49 printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); 49 printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
50 for_each_pgdat(pgdat) { 50 for_each_pgdat(pgdat) {
51 for (i = 0; i < pgdat->node_spanned_pages; ++i) { 51 for (i = 0; i < pgdat->node_spanned_pages; ++i) {
52 page = pgdat->node_mem_map + i; 52 page = pgdat_page_nr(pgdat, i);
53 total++; 53 total++;
54 if (PageHighMem(page)) 54 if (PageHighMem(page))
55 highmem++; 55 highmem++;
@@ -152,7 +152,7 @@ int __init reservedpages_count(void)
152 reservedpages = 0; 152 reservedpages = 0;
153 for_each_online_node(nid) 153 for_each_online_node(nid)
154 for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++) 154 for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++)
155 if (PageReserved(NODE_DATA(nid)->node_mem_map + i)) 155 if (PageReserved(nid_page_nr(nid, i)))
156 reservedpages++; 156 reservedpages++;
157 157
158 return reservedpages; 158 return reservedpages;
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index d0713c7d9f0a..691a2469ff36 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -357,6 +357,8 @@ config 060_WRITETHROUGH
357 is hardwired on. The 53c710 SCSI driver is known to suffer from 357 is hardwired on. The 53c710 SCSI driver is known to suffer from
358 this problem. 358 this problem.
359 359
360source "mm/Kconfig"
361
360endmenu 362endmenu
361 363
362menu "General setup" 364menu "General setup"
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index e729bd280623..dbfcdc8e6087 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -532,6 +532,8 @@ config ROMKERNEL
532 532
533endchoice 533endchoice
534 534
535source "mm/Kconfig"
536
535endmenu 537endmenu
536 538
537config ISA_DMA_API 539config ISA_DMA_API
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ab9944693f1f..94f5a8eb2c22 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -492,7 +492,7 @@ config SGI_SN0_N_MODE
492 which allows for more memory. Your system is most probably 492 which allows for more memory. Your system is most probably
493 running in M-Mode, so you should say N here. 493 running in M-Mode, so you should say N here.
494 494
495config DISCONTIGMEM 495config ARCH_DISCONTIGMEM_ENABLE
496 bool 496 bool
497 default y if SGI_IP27 497 default y if SGI_IP27
498 help 498 help
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 13472292d0ec..b5bab3a42fc4 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -82,7 +82,7 @@ CONFIG_STOP_MACHINE=y
82# CONFIG_SGI_IP22 is not set 82# CONFIG_SGI_IP22 is not set
83CONFIG_SGI_IP27=y 83CONFIG_SGI_IP27=y
84# CONFIG_SGI_SN0_N_MODE is not set 84# CONFIG_SGI_SN0_N_MODE is not set
85CONFIG_DISCONTIGMEM=y 85CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
86CONFIG_NUMA=y 86CONFIG_NUMA=y
87# CONFIG_MAPPED_KERNEL is not set 87# CONFIG_MAPPED_KERNEL is not set
88# CONFIG_REPLICATE_KTEXT is not set 88# CONFIG_REPLICATE_KTEXT is not set
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index 0a44a98d7adc..a160d04f7dbe 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -549,9 +549,8 @@ void __init mem_init(void)
549 */ 549 */
550 numslots = node_getlastslot(node); 550 numslots = node_getlastslot(node);
551 for (slot = 1; slot <= numslots; slot++) { 551 for (slot = 1; slot <= numslots; slot++) {
552 p = NODE_DATA(node)->node_mem_map + 552 p = nid_page_nr(node, slot_getbasepfn(node, slot) -
553 (slot_getbasepfn(node, slot) - 553 slot_getbasepfn(node, 0));
554 slot_getbasepfn(node, 0));
555 554
556 /* 555 /*
557 * Free valid memory in current slot. 556 * Free valid memory in current slot.
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index e7e7c56fc212..ce327c799b44 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -148,7 +148,7 @@ config HOTPLUG_CPU
148 default y if SMP 148 default y if SMP
149 select HOTPLUG 149 select HOTPLUG
150 150
151config DISCONTIGMEM 151config ARCH_DISCONTIGMEM_ENABLE
152 bool "Discontiguous memory support (EXPERIMENTAL)" 152 bool "Discontiguous memory support (EXPERIMENTAL)"
153 depends on EXPERIMENTAL 153 depends on EXPERIMENTAL
154 help 154 help
@@ -157,6 +157,8 @@ config DISCONTIGMEM
157 or have huge holes in the physical address space for other reasons. 157 or have huge holes in the physical address space for other reasons.
158 See <file:Documentation/vm/numa> for more. 158 See <file:Documentation/vm/numa> for more.
159 159
160source "mm/Kconfig"
161
160config PREEMPT 162config PREEMPT
161 bool 163 bool
162# bool "Preemptible Kernel" 164# bool "Preemptible Kernel"
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index cac37589e35c..2886ad70db48 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -506,7 +506,7 @@ void show_mem(void)
506 for (j = node_start_pfn(i); j < node_end_pfn(i); j++) { 506 for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
507 struct page *p; 507 struct page *p;
508 508
509 p = node_mem_map(i) + j - node_start_pfn(i); 509 p = nid_page_nr(i, j) - node_start_pfn(i);
510 510
511 total++; 511 total++;
512 if (PageReserved(p)) 512 if (PageReserved(p))
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 10162b187bcf..848f43970a4b 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -905,6 +905,8 @@ config PREEMPT
905config HIGHMEM 905config HIGHMEM
906 bool "High memory support" 906 bool "High memory support"
907 907
908source "mm/Kconfig"
909
908source "fs/Kconfig.binfmt" 910source "fs/Kconfig.binfmt"
909 911
910config PROC_DEVICETREE 912config PROC_DEVICETREE
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
index ab0f9902cb67..e02de5b467a4 100644
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -222,7 +222,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
222 puts("\n"); 222 puts("\n");
223 223
224 puts("Uncompressing Linux..."); 224 puts("Uncompressing Linux...");
225 gunzip(0x0, 0x400000, zimage_start, &zimage_size); 225 gunzip(NULL, 0x400000, zimage_start, &zimage_size);
226 puts("done.\n"); 226 puts("done.\n");
227 227
228 /* get the bi_rec address */ 228 /* get the bi_rec address */
diff --git a/arch/ppc/boot/simple/mpc10x_memory.c b/arch/ppc/boot/simple/mpc10x_memory.c
index 977daedc14c0..20d92a34ceb8 100644
--- a/arch/ppc/boot/simple/mpc10x_memory.c
+++ b/arch/ppc/boot/simple/mpc10x_memory.c
@@ -33,7 +33,7 @@
33 33
34#define MPC10X_PCI_OP(rw, size, type, op, mask) \ 34#define MPC10X_PCI_OP(rw, size, type, op, mask) \
35static void \ 35static void \
36mpc10x_##rw##_config_##size(unsigned int *cfg_addr, \ 36mpc10x_##rw##_config_##size(unsigned int __iomem *cfg_addr, \
37 unsigned int *cfg_data, int devfn, int offset, \ 37 unsigned int *cfg_data, int devfn, int offset, \
38 type val) \ 38 type val) \
39{ \ 39{ \
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
index 0f1fa289744e..cb27068bfcd4 100644
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -77,6 +77,10 @@ config PPC_PSERIES
77 bool " IBM pSeries & new iSeries" 77 bool " IBM pSeries & new iSeries"
78 default y 78 default y
79 79
80config PPC_BPA
81 bool " Broadband Processor Architecture"
82 depends on PPC_MULTIPLATFORM
83
80config PPC_PMAC 84config PPC_PMAC
81 depends on PPC_MULTIPLATFORM 85 depends on PPC_MULTIPLATFORM
82 bool " Apple G5 based machines" 86 bool " Apple G5 based machines"
@@ -106,6 +110,21 @@ config PPC_OF
106 bool 110 bool
107 default y 111 default y
108 112
113config XICS
114 depends on PPC_PSERIES
115 bool
116 default y
117
118config MPIC
119 depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
120 bool
121 default y
122
123config BPA_IIC
124 depends on PPC_BPA
125 bool
126 default y
127
109# VMX is pSeries only for now until somebody writes the iSeries 128# VMX is pSeries only for now until somebody writes the iSeries
110# exception vectors for it 129# exception vectors for it
111config ALTIVEC 130config ALTIVEC
@@ -198,13 +217,49 @@ config HMT
198 This option enables hardware multithreading on RS64 cpus. 217 This option enables hardware multithreading on RS64 cpus.
199 pSeries systems p620 and p660 have such a cpu type. 218 pSeries systems p620 and p660 have such a cpu type.
200 219
201config DISCONTIGMEM 220config ARCH_SELECT_MEMORY_MODEL
202 bool "Discontiguous Memory Support" 221 def_bool y
222
223config ARCH_FLATMEM_ENABLE
224 def_bool y
225 depends on !NUMA
226
227config ARCH_DISCONTIGMEM_ENABLE
228 def_bool y
203 depends on SMP && PPC_PSERIES 229 depends on SMP && PPC_PSERIES
204 230
231config ARCH_DISCONTIGMEM_DEFAULT
232 def_bool y
233 depends on ARCH_DISCONTIGMEM_ENABLE
234
235config ARCH_FLATMEM_ENABLE
236 def_bool y
237
238config ARCH_SPARSEMEM_ENABLE
239 def_bool y
240 depends on ARCH_DISCONTIGMEM_ENABLE
241
242source "mm/Kconfig"
243
244config HAVE_ARCH_EARLY_PFN_TO_NID
245 def_bool y
246 depends on NEED_MULTIPLE_NODES
247
248# Some NUMA nodes have memory ranges that span
249# other nodes. Even though a pfn is valid and
250# between a node's start and end pfns, it may not
251# reside on that node.
252#
253# This is a relatively temporary hack that should
254# be able to go away when sparsemem is fully in
255# place
256config NODES_SPAN_OTHER_NODES
257 def_bool y
258 depends on NEED_MULTIPLE_NODES
259
205config NUMA 260config NUMA
206 bool "NUMA support" 261 bool "NUMA support"
207 depends on DISCONTIGMEM 262 default y if DISCONTIGMEM || SPARSEMEM
208 263
209config SCHED_SMT 264config SCHED_SMT
210 bool "SMT (Hyperthreading) scheduler support" 265 bool "SMT (Hyperthreading) scheduler support"
@@ -256,7 +311,7 @@ config MSCHUNKS
256 311
257config PPC_RTAS 312config PPC_RTAS
258 bool 313 bool
259 depends on PPC_PSERIES 314 depends on PPC_PSERIES || PPC_BPA
260 default y 315 default y
261 316
262config RTAS_PROC 317config RTAS_PROC
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
index 33c752ceca4b..731b84758331 100644
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -90,12 +90,14 @@ boot := arch/ppc64/boot
90boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd 90boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
91boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd 91boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
92boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm 92boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm
93boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd
93$(boottarget-y): vmlinux 94$(boottarget-y): vmlinux
94 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ 95 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
95 96
96bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage 97bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
97bootimage-$(CONFIG_PPC_PMAC) := vmlinux 98bootimage-$(CONFIG_PPC_PMAC) := vmlinux
98bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage 99bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
100bootimage-$(CONFIG_PPC_BPA) := zImage
99bootimage-$(CONFIG_PPC_ISERIES) := vmlinux 101bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
100BOOTIMAGE := $(bootimage-y) 102BOOTIMAGE := $(bootimage-y)
101install: vmlinux 103install: vmlinux
diff --git a/arch/ppc64/boot/install.sh b/arch/ppc64/boot/install.sh
index 955c5681db6c..cb2d6626b555 100644
--- a/arch/ppc64/boot/install.sh
+++ b/arch/ppc64/boot/install.sh
@@ -22,8 +22,8 @@
22 22
23# User may have a custom install script 23# User may have a custom install script
24 24
25if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi 25if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
26if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi 26if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
27 27
28# Default install 28# Default install
29 29
diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
index 3eb5ef25d3a3..d0db8b5966c0 100644
--- a/arch/ppc64/configs/pSeries_defconfig
+++ b/arch/ppc64/configs/pSeries_defconfig
@@ -88,7 +88,7 @@ CONFIG_IBMVIO=y
88CONFIG_IOMMU_VMERGE=y 88CONFIG_IOMMU_VMERGE=y
89CONFIG_SMP=y 89CONFIG_SMP=y
90CONFIG_NR_CPUS=128 90CONFIG_NR_CPUS=128
91CONFIG_DISCONTIGMEM=y 91CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
92CONFIG_NUMA=y 92CONFIG_NUMA=y
93CONFIG_SCHED_SMT=y 93CONFIG_SCHED_SMT=y
94# CONFIG_PREEMPT is not set 94# CONFIG_PREEMPT is not set
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
index 2f31bf3046f9..b8e2066dde77 100644
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -89,7 +89,7 @@ CONFIG_BOOTX_TEXT=y
89CONFIG_IOMMU_VMERGE=y 89CONFIG_IOMMU_VMERGE=y
90CONFIG_SMP=y 90CONFIG_SMP=y
91CONFIG_NR_CPUS=32 91CONFIG_NR_CPUS=32
92CONFIG_DISCONTIGMEM=y 92CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
93# CONFIG_NUMA is not set 93# CONFIG_NUMA is not set
94# CONFIG_SCHED_SMT is not set 94# CONFIG_SCHED_SMT is not set
95# CONFIG_PREEMPT is not set 95# CONFIG_PREEMPT is not set
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index b5e167cf1a05..dffbfb7ac8d5 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -27,17 +27,21 @@ obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
27 mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ 27 mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
28 iSeries_iommu.o 28 iSeries_iommu.o
29 29
30obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o mpic.o 30obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o
31 31
32obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ 32obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
33 pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \ 33 pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
34 xics.o rtas.o pSeries_setup.o pSeries_iommu.o 34 pSeries_setup.o pSeries_iommu.o
35
36obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
37 bpa_iic.o spider-pic.o
35 38
36obj-$(CONFIG_EEH) += eeh.o 39obj-$(CONFIG_EEH) += eeh.o
37obj-$(CONFIG_PROC_FS) += proc_ppc64.o 40obj-$(CONFIG_PROC_FS) += proc_ppc64.o
38obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 41obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
39obj-$(CONFIG_SMP) += smp.o 42obj-$(CONFIG_SMP) += smp.o
40obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o 43obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
44obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o
41obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 45obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
42obj-$(CONFIG_SCANLOG) += scanlog.o 46obj-$(CONFIG_SCANLOG) += scanlog.o
43obj-$(CONFIG_VIOPATH) += viopath.o 47obj-$(CONFIG_VIOPATH) += viopath.o
@@ -46,6 +50,8 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
46obj-$(CONFIG_BOOTX_TEXT) += btext.o 50obj-$(CONFIG_BOOTX_TEXT) += btext.o
47obj-$(CONFIG_HVCS) += hvcserver.o 51obj-$(CONFIG_HVCS) += hvcserver.o
48obj-$(CONFIG_IBMVIO) += vio.o 52obj-$(CONFIG_IBMVIO) += vio.o
53obj-$(CONFIG_XICS) += xics.o
54obj-$(CONFIG_MPIC) += mpic.o
49 55
50obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ 56obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \
51 pmac_time.o pmac_nvram.o pmac_low_i2c.o 57 pmac_time.o pmac_nvram.o pmac_low_i2c.o
@@ -58,6 +64,7 @@ ifdef CONFIG_SMP
58obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o 64obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o
59obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o 65obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o
60obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o 66obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o
67obj-$(CONFIG_PPC_BPA) += pSeries_smp.o
61obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o 68obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o
62endif 69endif
63 70
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
new file mode 100644
index 000000000000..c8f3dc3fad70
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iic.c
@@ -0,0 +1,270 @@
1/*
2 * BPA Internal Interrupt Controller
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/config.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/percpu.h>
27#include <linux/types.h>
28
29#include <asm/io.h>
30#include <asm/pgtable.h>
31#include <asm/prom.h>
32#include <asm/ptrace.h>
33
34#include "bpa_iic.h"
35
36struct iic_pending_bits {
37 u32 data;
38 u8 flags;
39 u8 class;
40 u8 source;
41 u8 prio;
42};
43
44enum iic_pending_flags {
45 IIC_VALID = 0x80,
46 IIC_IPI = 0x40,
47};
48
49struct iic_regs {
50 struct iic_pending_bits pending;
51 struct iic_pending_bits pending_destr;
52 u64 generate;
53 u64 prio;
54};
55
56struct iic {
57 struct iic_regs __iomem *regs;
58};
59
60static DEFINE_PER_CPU(struct iic, iic);
61
62void iic_local_enable(void)
63{
64 out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
65}
66
67void iic_local_disable(void)
68{
69 out_be64(&__get_cpu_var(iic).regs->prio, 0x0);
70}
71
72static unsigned int iic_startup(unsigned int irq)
73{
74 return 0;
75}
76
77static void iic_enable(unsigned int irq)
78{
79 iic_local_enable();
80}
81
82static void iic_disable(unsigned int irq)
83{
84}
85
86static void iic_end(unsigned int irq)
87{
88 iic_local_enable();
89}
90
91static struct hw_interrupt_type iic_pic = {
92 .typename = " BPA-IIC ",
93 .startup = iic_startup,
94 .enable = iic_enable,
95 .disable = iic_disable,
96 .end = iic_end,
97};
98
99static int iic_external_get_irq(struct iic_pending_bits pending)
100{
101 int irq;
102 unsigned char node, unit;
103
104 node = pending.source >> 4;
105 unit = pending.source & 0xf;
106 irq = -1;
107
108 /*
109 * This mapping is specific to the Broadband
110 * Engine. We might need to get the numbers
111 * from the device tree to support future CPUs.
112 */
113 switch (unit) {
114 case 0x00:
115 case 0x0b:
116 /*
117 * One of these units can be connected
118 * to an external interrupt controller.
119 */
120 if (pending.prio > 0x3f ||
121 pending.class != 2)
122 break;
123 irq = IIC_EXT_OFFSET
124 + spider_get_irq(pending.prio + node * IIC_NODE_STRIDE)
125 + node * IIC_NODE_STRIDE;
126 break;
127 case 0x01 ... 0x04:
128 case 0x07 ... 0x0a:
129 /*
130 * These units are connected to the SPEs
131 */
132 if (pending.class > 2)
133 break;
134 irq = IIC_SPE_OFFSET
135 + pending.class * IIC_CLASS_STRIDE
136 + node * IIC_NODE_STRIDE
137 + unit;
138 break;
139 }
140 if (irq == -1)
141 printk(KERN_WARNING "Unexpected interrupt class %02x, "
142 "source %02x, prio %02x, cpu %02x\n", pending.class,
143 pending.source, pending.prio, smp_processor_id());
144 return irq;
145}
146
147/* Get an IRQ number from the pending state register of the IIC */
148int iic_get_irq(struct pt_regs *regs)
149{
150 struct iic *iic;
151 int irq;
152 struct iic_pending_bits pending;
153
154 iic = &__get_cpu_var(iic);
155 *(unsigned long *) &pending =
156 in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
157
158 irq = -1;
159 if (pending.flags & IIC_VALID) {
160 if (pending.flags & IIC_IPI) {
161 irq = IIC_IPI_OFFSET + (pending.prio >> 4);
162/*
163 if (irq > 0x80)
164 printk(KERN_WARNING "Unexpected IPI prio %02x"
165 "on CPU %02x\n", pending.prio,
166 smp_processor_id());
167*/
168 } else {
169 irq = iic_external_get_irq(pending);
170 }
171 }
172 return irq;
173}
174
175static struct iic_regs __iomem *find_iic(int cpu)
176{
177 struct device_node *np;
178 int nodeid = cpu / 2;
179 unsigned long regs;
180 struct iic_regs __iomem *iic_regs;
181
182 for (np = of_find_node_by_type(NULL, "cpu");
183 np;
184 np = of_find_node_by_type(np, "cpu")) {
185 if (nodeid == *(int *)get_property(np, "node-id", NULL))
186 break;
187 }
188
189 if (!np) {
190 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu);
191 iic_regs = NULL;
192 } else {
193 regs = *(long *)get_property(np, "iic", NULL);
194
195 /* hack until we have decided on the devtree info */
196 regs += 0x400;
197 if (cpu & 1)
198 regs += 0x20;
199
200 printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs);
201 iic_regs = __ioremap(regs, sizeof(struct iic_regs),
202 _PAGE_NO_CACHE);
203 }
204 return iic_regs;
205}
206
207#ifdef CONFIG_SMP
208void iic_setup_cpu(void)
209{
210 out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
211}
212
213void iic_cause_IPI(int cpu, int mesg)
214{
215 out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
216}
217
218static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
219{
220
221 smp_message_recv(irq - IIC_IPI_OFFSET, regs);
222 return IRQ_HANDLED;
223}
224
225static void iic_request_ipi(int irq, const char *name)
226{
227 /* IPIs are marked SA_INTERRUPT as they must run with irqs
228 * disabled */
229 get_irq_desc(irq)->handler = &iic_pic;
230 get_irq_desc(irq)->status |= IRQ_PER_CPU;
231 request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL);
232}
233
234void iic_request_IPIs(void)
235{
236 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
237 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
238#ifdef CONFIG_DEBUGGER
239 iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
240#endif /* CONFIG_DEBUGGER */
241}
242#endif /* CONFIG_SMP */
243
244static void iic_setup_spe_handlers(void)
245{
246 int be, isrc;
247
248 /* Assume two threads per BE are present */
249 for (be=0; be < num_present_cpus() / 2; be++) {
250 for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) {
251 int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc;
252 get_irq_desc(irq)->handler = &iic_pic;
253 }
254 }
255}
256
257void iic_init_IRQ(void)
258{
259 int cpu, irq_offset;
260 struct iic *iic;
261
262 irq_offset = 0;
263 for_each_cpu(cpu) {
264 iic = &per_cpu(iic, cpu);
265 iic->regs = find_iic(cpu);
266 if (iic->regs)
267 out_be64(&iic->regs->prio, 0xff);
268 }
269 iic_setup_spe_handlers();
270}
diff --git a/arch/ppc64/kernel/bpa_iic.h b/arch/ppc64/kernel/bpa_iic.h
new file mode 100644
index 000000000000..6833c3022166
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iic.h
@@ -0,0 +1,62 @@
1#ifndef ASM_BPA_IIC_H
2#define ASM_BPA_IIC_H
3#ifdef __KERNEL__
4/*
5 * Mapping of IIC pending bits into per-node
6 * interrupt numbers.
7 *
8 * IRQ FF CC SS PP FF CC SS PP Description
9 *
10 * 00-3f 80 02 +0 00 - 80 02 +0 3f South Bridge
11 * 00-3f 80 02 +b 00 - 80 02 +b 3f South Bridge
12 * 41-4a 80 00 +1 ** - 80 00 +a ** SPU Class 0
13 * 51-5a 80 01 +1 ** - 80 01 +a ** SPU Class 1
14 * 61-6a 80 02 +1 ** - 80 02 +a ** SPU Class 2
15 * 70-7f C0 ** ** 00 - C0 ** ** 0f IPI
16 *
17 * F flags
18 * C class
19 * S source
20 * P Priority
21 * + node number
22 * * don't care
23 *
24 * A node consists of a Broadband Engine and an optional
25 * south bridge device providing a maximum of 64 IRQs.
26 * The south bridge may be connected to either IOIF0
27 * or IOIF1.
28 * Each SPE is represented as three IRQ lines, one per
29 * interrupt class.
30 * 16 IRQ numbers are reserved for inter processor
31 * interruptions, although these are only used in the
32 * range of the first node.
33 *
34 * This scheme needs 128 IRQ numbers per BIF node ID,
35 * which means that with the total of 512 lines
36 * available, we can have a maximum of four nodes.
37 */
38
39enum {
40 IIC_EXT_OFFSET = 0x00, /* Start of south bridge IRQs */
41 IIC_NUM_EXT = 0x40, /* Number of south bridge IRQs */
42 IIC_SPE_OFFSET = 0x40, /* Start of SPE interrupts */
43 IIC_CLASS_STRIDE = 0x10, /* SPE IRQs per class */
44 IIC_IPI_OFFSET = 0x70, /* Start of IPI IRQs */
45 IIC_NUM_IPIS = 0x10, /* IRQs reserved for IPI */
46 IIC_NODE_STRIDE = 0x80, /* Total IRQs per node */
47};
48
49extern void iic_init_IRQ(void);
50extern int iic_get_irq(struct pt_regs *regs);
51extern void iic_cause_IPI(int cpu, int mesg);
52extern void iic_request_IPIs(void);
53extern void iic_setup_cpu(void);
54extern void iic_local_enable(void);
55extern void iic_local_disable(void);
56
57
58extern void spider_init_IRQ(void);
59extern int spider_get_irq(unsigned long int_pending);
60
61#endif
62#endif /* ASM_BPA_IIC_H */
diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c
new file mode 100644
index 000000000000..f33a7bccb0d7
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iommu.c
@@ -0,0 +1,377 @@
1/*
2 * IOMMU implementation for Broadband Processor Architecture
3 * We just establish a linear mapping at boot by setting all the
4 * IOPT cache entries in the CPU.
5 * The mapping functions should be identical to pci_direct_iommu,
6 * except for the handling of the high order bit that is required
7 * by the Spider bridge. These should be split into a separate
8 * file at the point where we get a different bridge chip.
9 *
10 * Copyright (C) 2005 IBM Deutschland Entwicklung GmbH,
11 * Arnd Bergmann <arndb@de.ibm.com>
12 *
13 * Based on linear mapping
14 * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version
19 * 2 of the License, or (at your option) any later version.
20 */
21
22#undef DEBUG
23
24#include <linux/kernel.h>
25#include <linux/pci.h>
26#include <linux/delay.h>
27#include <linux/string.h>
28#include <linux/init.h>
29#include <linux/bootmem.h>
30#include <linux/mm.h>
31#include <linux/dma-mapping.h>
32
33#include <asm/sections.h>
34#include <asm/iommu.h>
35#include <asm/io.h>
36#include <asm/prom.h>
37#include <asm/pci-bridge.h>
38#include <asm/machdep.h>
39#include <asm/pmac_feature.h>
40#include <asm/abs_addr.h>
41#include <asm/system.h>
42
43#include "pci.h"
44#include "bpa_iommu.h"
45
46static inline unsigned long
47get_iopt_entry(unsigned long real_address, unsigned long ioid,
48 unsigned long prot)
49{
50 return (prot & IOPT_PROT_MASK)
51 | (IOPT_COHERENT)
52 | (IOPT_ORDER_VC)
53 | (real_address & IOPT_RPN_MASK)
54 | (ioid & IOPT_IOID_MASK);
55}
56
57typedef struct {
58 unsigned long val;
59} ioste;
60
61static inline ioste
62mk_ioste(unsigned long val)
63{
64 ioste ioste = { .val = val, };
65 return ioste;
66}
67
68static inline ioste
69get_iost_entry(unsigned long iopt_base, unsigned long io_address, unsigned page_size)
70{
71 unsigned long ps;
72 unsigned long iostep;
73 unsigned long nnpt;
74 unsigned long shift;
75
76 switch (page_size) {
77 case 0x1000000:
78 ps = IOST_PS_16M;
79 nnpt = 0; /* one page per segment */
80 shift = 5; /* segment has 16 iopt entries */
81 break;
82
83 case 0x100000:
84 ps = IOST_PS_1M;
85 nnpt = 0; /* one page per segment */
86 shift = 1; /* segment has 256 iopt entries */
87 break;
88
89 case 0x10000:
90 ps = IOST_PS_64K;
91 nnpt = 0x07; /* 8 pages per io page table */
92 shift = 0; /* all entries are used */
93 break;
94
95 case 0x1000:
96 ps = IOST_PS_4K;
97 nnpt = 0x7f; /* 128 pages per io page table */
98 shift = 0; /* all entries are used */
99 break;
100
101 default: /* not a known compile time constant */
102 BUILD_BUG_ON(1);
103 break;
104 }
105
106 iostep = iopt_base +
107 /* need 8 bytes per iopte */
108 (((io_address / page_size * 8)
109 /* align io page tables on 4k page boundaries */
110 << shift)
111 /* nnpt+1 pages go into each iopt */
112 & ~(nnpt << 12));
113
114 nnpt++; /* this seems to work, but the documentation is not clear
115 about wether we put nnpt or nnpt-1 into the ioste bits.
116 In theory, this can't work for 4k pages. */
117 return mk_ioste(IOST_VALID_MASK
118 | (iostep & IOST_PT_BASE_MASK)
119 | ((nnpt << 5) & IOST_NNPT_MASK)
120 | (ps & IOST_PS_MASK));
121}
122
123/* compute the address of an io pte */
124static inline unsigned long
125get_ioptep(ioste iost_entry, unsigned long io_address)
126{
127 unsigned long iopt_base;
128 unsigned long page_size;
129 unsigned long page_number;
130 unsigned long iopt_offset;
131
132 iopt_base = iost_entry.val & IOST_PT_BASE_MASK;
133 page_size = iost_entry.val & IOST_PS_MASK;
134
135 /* decode page size to compute page number */
136 page_number = (io_address & 0x0fffffff) >> (10 + 2 * page_size);
137 /* page number is an offset into the io page table */
138 iopt_offset = (page_number << 3) & 0x7fff8ul;
139 return iopt_base + iopt_offset;
140}
141
142/* compute the tag field of the iopt cache entry */
143static inline unsigned long
144get_ioc_tag(ioste iost_entry, unsigned long io_address)
145{
146 unsigned long iopte = get_ioptep(iost_entry, io_address);
147
148 return IOPT_VALID_MASK
149 | ((iopte & 0x00000000000000ff8ul) >> 3)
150 | ((iopte & 0x0000003fffffc0000ul) >> 9);
151}
152
153/* compute the hashed 6 bit index for the 4-way associative pte cache */
154static inline unsigned long
155get_ioc_hash(ioste iost_entry, unsigned long io_address)
156{
157 unsigned long iopte = get_ioptep(iost_entry, io_address);
158
159 return ((iopte & 0x000000000000001f8ul) >> 3)
160 ^ ((iopte & 0x00000000000020000ul) >> 17)
161 ^ ((iopte & 0x00000000000010000ul) >> 15)
162 ^ ((iopte & 0x00000000000008000ul) >> 13)
163 ^ ((iopte & 0x00000000000004000ul) >> 11)
164 ^ ((iopte & 0x00000000000002000ul) >> 9)
165 ^ ((iopte & 0x00000000000001000ul) >> 7);
166}
167
168/* same as above, but pretend that we have a simpler 1-way associative
169 pte cache with an 8 bit index */
170static inline unsigned long
171get_ioc_hash_1way(ioste iost_entry, unsigned long io_address)
172{
173 unsigned long iopte = get_ioptep(iost_entry, io_address);
174
175 return ((iopte & 0x000000000000001f8ul) >> 3)
176 ^ ((iopte & 0x00000000000020000ul) >> 17)
177 ^ ((iopte & 0x00000000000010000ul) >> 15)
178 ^ ((iopte & 0x00000000000008000ul) >> 13)
179 ^ ((iopte & 0x00000000000004000ul) >> 11)
180 ^ ((iopte & 0x00000000000002000ul) >> 9)
181 ^ ((iopte & 0x00000000000001000ul) >> 7)
182 ^ ((iopte & 0x0000000000000c000ul) >> 8);
183}
184
185static inline ioste
186get_iost_cache(void __iomem *base, unsigned long index)
187{
188 unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
189 return mk_ioste(in_be64(&p[index]));
190}
191
192static inline void
193set_iost_cache(void __iomem *base, unsigned long index, ioste ste)
194{
195 unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
196 pr_debug("ioste %02lx was %016lx, store %016lx", index,
197 get_iost_cache(base, index).val, ste.val);
198 out_be64(&p[index], ste.val);
199 pr_debug(" now %016lx\n", get_iost_cache(base, index).val);
200}
201
202static inline unsigned long
203get_iopt_cache(void __iomem *base, unsigned long index, unsigned long *tag)
204{
205 unsigned long __iomem *tags = (void *)(base + IOC_PT_CACHE_DIR);
206 unsigned long __iomem *p = (void *)(base + IOC_PT_CACHE_REG);
207
208 *tag = tags[index];
209 rmb();
210 return *p;
211}
212
213static inline void
214set_iopt_cache(void __iomem *base, unsigned long index,
215 unsigned long tag, unsigned long val)
216{
217 unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR;
218 unsigned long __iomem *p = base + IOC_PT_CACHE_REG;
219 pr_debug("iopt %02lx was v%016lx/t%016lx, store v%016lx/t%016lx\n",
220 index, get_iopt_cache(base, index, &oldtag), oldtag, val, tag);
221
222 out_be64(p, val);
223 out_be64(&tags[index], tag);
224}
225
226static inline void
227set_iost_origin(void __iomem *base)
228{
229 unsigned long __iomem *p = base + IOC_ST_ORIGIN;
230 unsigned long origin = IOSTO_ENABLE | IOSTO_SW;
231
232 pr_debug("iost_origin %016lx, now %016lx\n", in_be64(p), origin);
233 out_be64(p, origin);
234}
235
236static inline void
237set_iocmd_config(void __iomem *base)
238{
239 unsigned long __iomem *p = base + 0xc00;
240 unsigned long conf;
241
242 conf = in_be64(p);
243 pr_debug("iost_conf %016lx, now %016lx\n", conf, conf | IOCMD_CONF_TE);
244 out_be64(p, conf | IOCMD_CONF_TE);
245}
246
247/* FIXME: get these from the device tree */
248#define ioc_base 0x20000511000ull
249#define ioc_mmio_base 0x20000510000ull
250#define ioid 0x48a
251#define iopt_phys_offset (- 0x20000000) /* We have a 512MB offset from the SB */
252#define io_page_size 0x1000000
253
254static unsigned long map_iopt_entry(unsigned long address)
255{
256 switch (address >> 20) {
257 case 0x600:
258 address = 0x24020000000ull; /* spider i/o */
259 break;
260 default:
261 address += iopt_phys_offset;
262 break;
263 }
264
265 return get_iopt_entry(address, ioid, IOPT_PROT_RW);
266}
267
268static void iommu_bus_setup_null(struct pci_bus *b) { }
269static void iommu_dev_setup_null(struct pci_dev *d) { }
270
271/* initialize the iommu to support a simple linear mapping
272 * for each DMA window used by any device. For now, we
273 * happen to know that there is only one DMA window in use,
274 * starting at iopt_phys_offset. */
275static void bpa_map_iommu(void)
276{
277 unsigned long address;
278 void __iomem *base;
279 ioste ioste;
280 unsigned long index;
281
282 base = __ioremap(ioc_base, 0x1000, _PAGE_NO_CACHE);
283 pr_debug("%lx mapped to %p\n", ioc_base, base);
284 set_iocmd_config(base);
285 iounmap(base);
286
287 base = __ioremap(ioc_mmio_base, 0x1000, _PAGE_NO_CACHE);
288 pr_debug("%lx mapped to %p\n", ioc_mmio_base, base);
289
290 set_iost_origin(base);
291
292 for (address = 0; address < 0x100000000ul; address += io_page_size) {
293 ioste = get_iost_entry(0x10000000000ul, address, io_page_size);
294 if ((address & 0xfffffff) == 0) /* segment start */
295 set_iost_cache(base, address >> 28, ioste);
296 index = get_ioc_hash_1way(ioste, address);
297 pr_debug("addr %08lx, index %02lx, ioste %016lx\n",
298 address, index, ioste.val);
299 set_iopt_cache(base,
300 get_ioc_hash_1way(ioste, address),
301 get_ioc_tag(ioste, address),
302 map_iopt_entry(address));
303 }
304 iounmap(base);
305}
306
307
308static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
309 dma_addr_t *dma_handle, unsigned int __nocast flag)
310{
311 void *ret;
312
313 ret = (void *)__get_free_pages(flag, get_order(size));
314 if (ret != NULL) {
315 memset(ret, 0, size);
316 *dma_handle = virt_to_abs(ret) | BPA_DMA_VALID;
317 }
318 return ret;
319}
320
321static void bpa_free_coherent(struct device *hwdev, size_t size,
322 void *vaddr, dma_addr_t dma_handle)
323{
324 free_pages((unsigned long)vaddr, get_order(size));
325}
326
327static dma_addr_t bpa_map_single(struct device *hwdev, void *ptr,
328 size_t size, enum dma_data_direction direction)
329{
330 return virt_to_abs(ptr) | BPA_DMA_VALID;
331}
332
333static void bpa_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
334 size_t size, enum dma_data_direction direction)
335{
336}
337
338static int bpa_map_sg(struct device *hwdev, struct scatterlist *sg,
339 int nents, enum dma_data_direction direction)
340{
341 int i;
342
343 for (i = 0; i < nents; i++, sg++) {
344 sg->dma_address = (page_to_phys(sg->page) + sg->offset)
345 | BPA_DMA_VALID;
346 sg->dma_length = sg->length;
347 }
348
349 return nents;
350}
351
352static void bpa_unmap_sg(struct device *hwdev, struct scatterlist *sg,
353 int nents, enum dma_data_direction direction)
354{
355}
356
357static int bpa_dma_supported(struct device *dev, u64 mask)
358{
359 return mask < 0x100000000ull;
360}
361
362void bpa_init_iommu(void)
363{
364 bpa_map_iommu();
365
366 /* Direct I/O, IOMMU off */
367 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
368 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
369
370 pci_dma_ops.alloc_coherent = bpa_alloc_coherent;
371 pci_dma_ops.free_coherent = bpa_free_coherent;
372 pci_dma_ops.map_single = bpa_map_single;
373 pci_dma_ops.unmap_single = bpa_unmap_single;
374 pci_dma_ops.map_sg = bpa_map_sg;
375 pci_dma_ops.unmap_sg = bpa_unmap_sg;
376 pci_dma_ops.dma_supported = bpa_dma_supported;
377}
diff --git a/arch/ppc64/kernel/bpa_iommu.h b/arch/ppc64/kernel/bpa_iommu.h
new file mode 100644
index 000000000000..e547d77dfa04
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iommu.h
@@ -0,0 +1,65 @@
1#ifndef BPA_IOMMU_H
2#define BPA_IOMMU_H
3
4/* some constants */
5enum {
6 /* segment table entries */
7 IOST_VALID_MASK = 0x8000000000000000ul,
8 IOST_TAG_MASK = 0x3000000000000000ul,
9 IOST_PT_BASE_MASK = 0x000003fffffff000ul,
10 IOST_NNPT_MASK = 0x0000000000000fe0ul,
11 IOST_PS_MASK = 0x000000000000000ful,
12
13 IOST_PS_4K = 0x1,
14 IOST_PS_64K = 0x3,
15 IOST_PS_1M = 0x5,
16 IOST_PS_16M = 0x7,
17
18 /* iopt tag register */
19 IOPT_VALID_MASK = 0x0000000200000000ul,
20 IOPT_TAG_MASK = 0x00000001fffffffful,
21
22 /* iopt cache register */
23 IOPT_PROT_MASK = 0xc000000000000000ul,
24 IOPT_PROT_NONE = 0x0000000000000000ul,
25 IOPT_PROT_READ = 0x4000000000000000ul,
26 IOPT_PROT_WRITE = 0x8000000000000000ul,
27 IOPT_PROT_RW = 0xc000000000000000ul,
28 IOPT_COHERENT = 0x2000000000000000ul,
29
30 IOPT_ORDER_MASK = 0x1800000000000000ul,
31 /* order access to same IOID/VC on same address */
32 IOPT_ORDER_ADDR = 0x0800000000000000ul,
33 /* similar, but only after a write access */
34 IOPT_ORDER_WRITES = 0x1000000000000000ul,
35 /* Order all accesses to same IOID/VC */
36 IOPT_ORDER_VC = 0x1800000000000000ul,
37
38 IOPT_RPN_MASK = 0x000003fffffff000ul,
39 IOPT_HINT_MASK = 0x0000000000000800ul,
40 IOPT_IOID_MASK = 0x00000000000007fful,
41
42 IOSTO_ENABLE = 0x8000000000000000ul,
43 IOSTO_ORIGIN = 0x000003fffffff000ul,
44 IOSTO_HW = 0x0000000000000800ul,
45 IOSTO_SW = 0x0000000000000400ul,
46
47 IOCMD_CONF_TE = 0x0000800000000000ul,
48
49 /* memory mapped registers */
50 IOC_PT_CACHE_DIR = 0x000,
51 IOC_ST_CACHE_DIR = 0x800,
52 IOC_PT_CACHE_REG = 0x910,
53 IOC_ST_ORIGIN = 0x918,
54 IOC_CONF = 0x930,
55
56 /* The high bit needs to be set on every DMA address,
57 only 2GB are addressable */
58 BPA_DMA_VALID = 0x80000000,
59 BPA_DMA_MASK = 0x7fffffff,
60};
61
62
63void bpa_init_iommu(void);
64
65#endif
diff --git a/arch/ppc64/kernel/bpa_nvram.c b/arch/ppc64/kernel/bpa_nvram.c
new file mode 100644
index 000000000000..06a119cfceb5
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_nvram.c
@@ -0,0 +1,118 @@
1/*
2 * NVRAM for CPBW
3 *
4 * (C) Copyright IBM Corp. 2005
5 *
6 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/fs.h>
24#include <linux/init.h>
25#include <linux/kernel.h>
26#include <linux/spinlock.h>
27#include <linux/types.h>
28
29#include <asm/machdep.h>
30#include <asm/nvram.h>
31#include <asm/prom.h>
32
33static void __iomem *bpa_nvram_start;
34static long bpa_nvram_len;
35static spinlock_t bpa_nvram_lock = SPIN_LOCK_UNLOCKED;
36
37static ssize_t bpa_nvram_read(char *buf, size_t count, loff_t *index)
38{
39 unsigned long flags;
40
41 if (*index >= bpa_nvram_len)
42 return 0;
43 if (*index + count > bpa_nvram_len)
44 count = bpa_nvram_len - *index;
45
46 spin_lock_irqsave(&bpa_nvram_lock, flags);
47
48 memcpy_fromio(buf, bpa_nvram_start + *index, count);
49
50 spin_unlock_irqrestore(&bpa_nvram_lock, flags);
51
52 *index += count;
53 return count;
54}
55
56static ssize_t bpa_nvram_write(char *buf, size_t count, loff_t *index)
57{
58 unsigned long flags;
59
60 if (*index >= bpa_nvram_len)
61 return 0;
62 if (*index + count > bpa_nvram_len)
63 count = bpa_nvram_len - *index;
64
65 spin_lock_irqsave(&bpa_nvram_lock, flags);
66
67 memcpy_toio(bpa_nvram_start + *index, buf, count);
68
69 spin_unlock_irqrestore(&bpa_nvram_lock, flags);
70
71 *index += count;
72 return count;
73}
74
75static ssize_t bpa_nvram_get_size(void)
76{
77 return bpa_nvram_len;
78}
79
80int __init bpa_nvram_init(void)
81{
82 struct device_node *nvram_node;
83 unsigned long *buffer;
84 int proplen;
85 unsigned long nvram_addr;
86 int ret;
87
88 ret = -ENODEV;
89 nvram_node = of_find_node_by_type(NULL, "nvram");
90 if (!nvram_node)
91 goto out;
92
93 ret = -EIO;
94 buffer = (unsigned long *)get_property(nvram_node, "reg", &proplen);
95 if (proplen != 2*sizeof(unsigned long))
96 goto out;
97
98 ret = -ENODEV;
99 nvram_addr = buffer[0];
100 bpa_nvram_len = buffer[1];
101 if ( (!bpa_nvram_len) || (!nvram_addr) )
102 goto out;
103
104 bpa_nvram_start = ioremap(nvram_addr, bpa_nvram_len);
105 if (!bpa_nvram_start)
106 goto out;
107
108 printk(KERN_INFO "BPA NVRAM, %luk mapped to %p\n",
109 bpa_nvram_len >> 10, bpa_nvram_start);
110
111 ppc_md.nvram_read = bpa_nvram_read;
112 ppc_md.nvram_write = bpa_nvram_write;
113 ppc_md.nvram_size = bpa_nvram_get_size;
114
115out:
116 of_node_put(nvram_node);
117 return ret;
118}
diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c
new file mode 100644
index 000000000000..57b3db66f458
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_setup.c
@@ -0,0 +1,140 @@
1/*
2 * linux/arch/ppc/kernel/bpa_setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 * Modified by PPC64 Team, IBM Corp
8 * Modified by BPA Team, IBM Deutschland Entwicklung GmbH
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#undef DEBUG
16
17#include <linux/config.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/mm.h>
21#include <linux/stddef.h>
22#include <linux/unistd.h>
23#include <linux/slab.h>
24#include <linux/user.h>
25#include <linux/reboot.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/irq.h>
29#include <linux/seq_file.h>
30#include <linux/root_dev.h>
31#include <linux/console.h>
32
33#include <asm/mmu.h>
34#include <asm/processor.h>
35#include <asm/io.h>
36#include <asm/pgtable.h>
37#include <asm/prom.h>
38#include <asm/rtas.h>
39#include <asm/pci-bridge.h>
40#include <asm/iommu.h>
41#include <asm/dma.h>
42#include <asm/machdep.h>
43#include <asm/time.h>
44#include <asm/nvram.h>
45#include <asm/cputable.h>
46
47#include "pci.h"
48#include "bpa_iic.h"
49#include "bpa_iommu.h"
50
51#ifdef DEBUG
52#define DBG(fmt...) udbg_printf(fmt)
53#else
54#define DBG(fmt...)
55#endif
56
57void bpa_get_cpuinfo(struct seq_file *m)
58{
59 struct device_node *root;
60 const char *model = "";
61
62 root = of_find_node_by_path("/");
63 if (root)
64 model = get_property(root, "model", NULL);
65 seq_printf(m, "machine\t\t: BPA %s\n", model);
66 of_node_put(root);
67}
68
69static void bpa_progress(char *s, unsigned short hex)
70{
71 printk("*** %04x : %s\n", hex, s ? s : "");
72}
73
74static void __init bpa_setup_arch(void)
75{
76 ppc_md.init_IRQ = iic_init_IRQ;
77 ppc_md.get_irq = iic_get_irq;
78
79#ifdef CONFIG_SMP
80 smp_init_pSeries();
81#endif
82
83 /* init to some ~sane value until calibrate_delay() runs */
84 loops_per_jiffy = 50000000;
85
86 if (ROOT_DEV == 0) {
87 printk("No ramdisk, default root is /dev/hda2\n");
88 ROOT_DEV = Root_HDA2;
89 }
90
91 /* Find and initialize PCI host bridges */
92 init_pci_config_tokens();
93 find_and_init_phbs();
94 spider_init_IRQ();
95#ifdef CONFIG_DUMMY_CONSOLE
96 conswitchp = &dummy_con;
97#endif
98
99 bpa_nvram_init();
100}
101
102/*
103 * Early initialization. Relocation is on but do not reference unbolted pages
104 */
105static void __init bpa_init_early(void)
106{
107 DBG(" -> bpa_init_early()\n");
108
109 hpte_init_native();
110
111 bpa_init_iommu();
112
113 ppc64_interrupt_controller = IC_BPA_IIC;
114
115 DBG(" <- bpa_init_early()\n");
116}
117
118
119static int __init bpa_probe(int platform)
120{
121 if (platform != PLATFORM_BPA)
122 return 0;
123
124 return 1;
125}
126
127struct machdep_calls __initdata bpa_md = {
128 .probe = bpa_probe,
129 .setup_arch = bpa_setup_arch,
130 .init_early = bpa_init_early,
131 .get_cpuinfo = bpa_get_cpuinfo,
132 .restart = rtas_restart,
133 .power_off = rtas_power_off,
134 .halt = rtas_halt,
135 .get_boot_time = rtas_get_boot_time,
136 .get_rtc_time = rtas_get_rtc_time,
137 .set_rtc_time = rtas_set_rtc_time,
138 .calibrate_decr = generic_calibrate_decr,
139 .progress = bpa_progress,
140};
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S
index 3bd951820850..42fc08cf87a0 100644
--- a/arch/ppc64/kernel/cpu_setup_power4.S
+++ b/arch/ppc64/kernel/cpu_setup_power4.S
@@ -73,7 +73,21 @@ _GLOBAL(__970_cpu_preinit)
73 73
74_GLOBAL(__setup_cpu_power4) 74_GLOBAL(__setup_cpu_power4)
75 blr 75 blr
76 76
77_GLOBAL(__setup_cpu_be)
78 /* Set large page sizes LP=0: 16MB, LP=1: 64KB */
79 addi r3, 0, 0
80 ori r3, r3, HID6_LB
81 sldi r3, r3, 32
82 nor r3, r3, r3
83 mfspr r4, SPRN_HID6
84 and r4, r4, r3
85 addi r3, 0, 0x02000
86 sldi r3, r3, 32
87 or r4, r4, r3
88 mtspr SPRN_HID6, r4
89 blr
90
77_GLOBAL(__setup_cpu_ppc970) 91_GLOBAL(__setup_cpu_ppc970)
78 mfspr r0,SPRN_HID0 92 mfspr r0,SPRN_HID0
79 li r11,5 /* clear DOZE and SLEEP */ 93 li r11,5 /* clear DOZE and SLEEP */
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
index 8644a8648058..1d162c7c59df 100644
--- a/arch/ppc64/kernel/cputable.c
+++ b/arch/ppc64/kernel/cputable.c
@@ -34,6 +34,7 @@ EXPORT_SYMBOL(cur_cpu_spec);
34extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec); 34extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
35extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); 35extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
36extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); 36extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
37extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
37 38
38 39
39/* We only set the altivec features if the kernel was compiled with altivec 40/* We only set the altivec features if the kernel was compiled with altivec
@@ -162,6 +163,16 @@ struct cpu_spec cpu_specs[] = {
162 __setup_cpu_power4, 163 __setup_cpu_power4,
163 COMMON_PPC64_FW 164 COMMON_PPC64_FW
164 }, 165 },
166 { /* BE DD1.x */
167 0xffff0000, 0x00700000, "Broadband Engine",
168 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
169 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
170 CPU_FTR_SMT,
171 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
172 128, 128,
173 __setup_cpu_be,
174 COMMON_PPC64_FW
175 },
165 { /* default match */ 176 { /* default match */
166 0x00000000, 0x00000000, "POWER4 (compatible)", 177 0x00000000, 0x00000000, "POWER4 (compatible)",
167 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 178 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index b31962436fe3..86966ce76b58 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -671,9 +671,6 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr)
671 } 671 }
672} 672}
673 673
674extern unsigned long ppc_proc_freq;
675extern unsigned long ppc_tb_freq;
676
677/* 674/*
678 * Document me. 675 * Document me.
679 */ 676 */
@@ -772,8 +769,6 @@ static void iSeries_halt(void)
772 mf_power_off(); 769 mf_power_off();
773} 770}
774 771
775extern void setup_default_decr(void);
776
777/* 772/*
778 * void __init iSeries_calibrate_decr() 773 * void __init iSeries_calibrate_decr()
779 * 774 *
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
index d860467b8f09..3defc8c33adf 100644
--- a/arch/ppc64/kernel/irq.c
+++ b/arch/ppc64/kernel/irq.c
@@ -395,6 +395,9 @@ int virt_irq_create_mapping(unsigned int real_irq)
395 if (ppc64_interrupt_controller == IC_OPEN_PIC) 395 if (ppc64_interrupt_controller == IC_OPEN_PIC)
396 return real_irq; /* no mapping for openpic (for now) */ 396 return real_irq; /* no mapping for openpic (for now) */
397 397
398 if (ppc64_interrupt_controller == IC_BPA_IIC)
399 return real_irq; /* no mapping for iic either */
400
398 /* don't map interrupts < MIN_VIRT_IRQ */ 401 /* don't map interrupts < MIN_VIRT_IRQ */
399 if (real_irq < MIN_VIRT_IRQ) { 402 if (real_irq < MIN_VIRT_IRQ) {
400 virt_irq_to_real_map[real_irq] = real_irq; 403 virt_irq_to_real_map[real_irq] = real_irq;
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index e950a2058a19..782ce3efa2c1 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -32,15 +32,14 @@
32#include <linux/ptrace.h> 32#include <linux/ptrace.h>
33#include <linux/spinlock.h> 33#include <linux/spinlock.h>
34#include <linux/preempt.h> 34#include <linux/preempt.h>
35#include <asm/cacheflush.h>
35#include <asm/kdebug.h> 36#include <asm/kdebug.h>
36#include <asm/sstep.h> 37#include <asm/sstep.h>
37 38
38/* kprobe_status settings */
39#define KPROBE_HIT_ACTIVE 0x00000001
40#define KPROBE_HIT_SS 0x00000002
41
42static struct kprobe *current_kprobe; 39static struct kprobe *current_kprobe;
43static unsigned long kprobe_status, kprobe_saved_msr; 40static unsigned long kprobe_status, kprobe_saved_msr;
41static struct kprobe *kprobe_prev;
42static unsigned long kprobe_status_prev, kprobe_saved_msr_prev;
44static struct pt_regs jprobe_saved_regs; 43static struct pt_regs jprobe_saved_regs;
45 44
46int arch_prepare_kprobe(struct kprobe *p) 45int arch_prepare_kprobe(struct kprobe *p)
@@ -61,16 +60,25 @@ int arch_prepare_kprobe(struct kprobe *p)
61void arch_copy_kprobe(struct kprobe *p) 60void arch_copy_kprobe(struct kprobe *p)
62{ 61{
63 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 62 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
63 p->opcode = *p->addr;
64} 64}
65 65
66void arch_remove_kprobe(struct kprobe *p) 66void arch_arm_kprobe(struct kprobe *p)
67{ 67{
68 *p->addr = BREAKPOINT_INSTRUCTION;
69 flush_icache_range((unsigned long) p->addr,
70 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
68} 71}
69 72
70static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) 73void arch_disarm_kprobe(struct kprobe *p)
71{ 74{
72 *p->addr = p->opcode; 75 *p->addr = p->opcode;
73 regs->nip = (unsigned long)p->addr; 76 flush_icache_range((unsigned long) p->addr,
77 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
78}
79
80void arch_remove_kprobe(struct kprobe *p)
81{
74} 82}
75 83
76static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 84static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -83,6 +91,20 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
83 regs->nip = (unsigned long)&p->ainsn.insn; 91 regs->nip = (unsigned long)&p->ainsn.insn;
84} 92}
85 93
94static inline void save_previous_kprobe(void)
95{
96 kprobe_prev = current_kprobe;
97 kprobe_status_prev = kprobe_status;
98 kprobe_saved_msr_prev = kprobe_saved_msr;
99}
100
101static inline void restore_previous_kprobe(void)
102{
103 current_kprobe = kprobe_prev;
104 kprobe_status = kprobe_status_prev;
105 kprobe_saved_msr = kprobe_saved_msr_prev;
106}
107
86static inline int kprobe_handler(struct pt_regs *regs) 108static inline int kprobe_handler(struct pt_regs *regs)
87{ 109{
88 struct kprobe *p; 110 struct kprobe *p;
@@ -101,8 +123,19 @@ static inline int kprobe_handler(struct pt_regs *regs)
101 unlock_kprobes(); 123 unlock_kprobes();
102 goto no_kprobe; 124 goto no_kprobe;
103 } 125 }
104 disarm_kprobe(p, regs); 126 /* We have reentered the kprobe_handler(), since
105 ret = 1; 127 * another probe was hit while within the handler.
128 * We here save the original kprobes variables and
129 * just single step on the instruction of the new probe
130 * without calling any user handlers.
131 */
132 save_previous_kprobe();
133 current_kprobe = p;
134 kprobe_saved_msr = regs->msr;
135 p->nmissed++;
136 prepare_singlestep(p, regs);
137 kprobe_status = KPROBE_REENTER;
138 return 1;
106 } else { 139 } else {
107 p = current_kprobe; 140 p = current_kprobe;
108 if (p->break_handler && p->break_handler(p, regs)) { 141 if (p->break_handler && p->break_handler(p, regs)) {
@@ -184,13 +217,21 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
184 if (!kprobe_running()) 217 if (!kprobe_running())
185 return 0; 218 return 0;
186 219
187 if (current_kprobe->post_handler) 220 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
221 kprobe_status = KPROBE_HIT_SSDONE;
188 current_kprobe->post_handler(current_kprobe, regs, 0); 222 current_kprobe->post_handler(current_kprobe, regs, 0);
223 }
189 224
190 resume_execution(current_kprobe, regs); 225 resume_execution(current_kprobe, regs);
191 regs->msr |= kprobe_saved_msr; 226 regs->msr |= kprobe_saved_msr;
192 227
228 /*Restore back the original saved kprobes variables and continue. */
229 if (kprobe_status == KPROBE_REENTER) {
230 restore_previous_kprobe();
231 goto out;
232 }
193 unlock_kprobes(); 233 unlock_kprobes();
234out:
194 preempt_enable_no_resched(); 235 preempt_enable_no_resched();
195 236
196 /* 237 /*
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
index 8cf95a27178e..da8900b51f40 100644
--- a/arch/ppc64/kernel/maple_setup.c
+++ b/arch/ppc64/kernel/maple_setup.c
@@ -78,17 +78,77 @@ extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
78extern void generic_find_legacy_serial_ports(u64 *physport, 78extern void generic_find_legacy_serial_ports(u64 *physport,
79 unsigned int *default_speed); 79 unsigned int *default_speed);
80 80
81
82static void maple_restart(char *cmd) 81static void maple_restart(char *cmd)
83{ 82{
83 unsigned int maple_nvram_base;
84 unsigned int maple_nvram_offset;
85 unsigned int maple_nvram_command;
86 struct device_node *rtcs;
87
88 /* find NVRAM device */
89 rtcs = find_compatible_devices("nvram", "AMD8111");
90 if (rtcs && rtcs->addrs) {
91 maple_nvram_base = rtcs->addrs[0].address;
92 } else {
93 printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
94 printk(KERN_EMERG "Maple: Manual Restart Required\n");
95 return;
96 }
97
98 /* find service processor device */
99 rtcs = find_devices("service-processor");
100 if (!rtcs) {
101 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
102 printk(KERN_EMERG "Maple: Manual Restart Required\n");
103 return;
104 }
105 maple_nvram_offset = *(unsigned int*) get_property(rtcs,
106 "restart-addr", NULL);
107 maple_nvram_command = *(unsigned int*) get_property(rtcs,
108 "restart-value", NULL);
109
110 /* send command */
111 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
112 for (;;) ;
84} 113}
85 114
86static void maple_power_off(void) 115static void maple_power_off(void)
87{ 116{
117 unsigned int maple_nvram_base;
118 unsigned int maple_nvram_offset;
119 unsigned int maple_nvram_command;
120 struct device_node *rtcs;
121
122 /* find NVRAM device */
123 rtcs = find_compatible_devices("nvram", "AMD8111");
124 if (rtcs && rtcs->addrs) {
125 maple_nvram_base = rtcs->addrs[0].address;
126 } else {
127 printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
128 printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
129 return;
130 }
131
132 /* find service processor device */
133 rtcs = find_devices("service-processor");
134 if (!rtcs) {
135 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
136 printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
137 return;
138 }
139 maple_nvram_offset = *(unsigned int*) get_property(rtcs,
140 "power-off-addr", NULL);
141 maple_nvram_command = *(unsigned int*) get_property(rtcs,
142 "power-off-value", NULL);
143
144 /* send command */
145 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
146 for (;;) ;
88} 147}
89 148
90static void maple_halt(void) 149static void maple_halt(void)
91{ 150{
151 maple_power_off();
92} 152}
93 153
94#ifdef CONFIG_SMP 154#ifdef CONFIG_SMP
@@ -235,6 +295,6 @@ struct machdep_calls __initdata maple_md = {
235 .get_boot_time = maple_get_boot_time, 295 .get_boot_time = maple_get_boot_time,
236 .set_rtc_time = maple_set_rtc_time, 296 .set_rtc_time = maple_set_rtc_time,
237 .get_rtc_time = maple_get_rtc_time, 297 .get_rtc_time = maple_get_rtc_time,
238 .calibrate_decr = maple_calibrate_decr, 298 .calibrate_decr = generic_calibrate_decr,
239 .progress = maple_progress, 299 .progress = maple_progress,
240}; 300};
diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c
index 07ce7895b43d..d65210abcd03 100644
--- a/arch/ppc64/kernel/maple_time.c
+++ b/arch/ppc64/kernel/maple_time.c
@@ -42,11 +42,8 @@
42#define DBG(x...) 42#define DBG(x...)
43#endif 43#endif
44 44
45extern void setup_default_decr(void);
46extern void GregorianDay(struct rtc_time * tm); 45extern void GregorianDay(struct rtc_time * tm);
47 46
48extern unsigned long ppc_tb_freq;
49extern unsigned long ppc_proc_freq;
50static int maple_rtc_addr; 47static int maple_rtc_addr;
51 48
52static int maple_clock_read(int addr) 49static int maple_clock_read(int addr)
@@ -176,51 +173,3 @@ void __init maple_get_boot_time(struct rtc_time *tm)
176 maple_get_rtc_time(tm); 173 maple_get_rtc_time(tm);
177} 174}
178 175
179/* XXX FIXME: Some sane defaults: 125 MHz timebase, 1GHz processor */
180#define DEFAULT_TB_FREQ 125000000UL
181#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
182
183void __init maple_calibrate_decr(void)
184{
185 struct device_node *cpu;
186 struct div_result divres;
187 unsigned int *fp = NULL;
188
189 /*
190 * The cpu node should have a timebase-frequency property
191 * to tell us the rate at which the decrementer counts.
192 */
193 cpu = of_find_node_by_type(NULL, "cpu");
194
195 ppc_tb_freq = DEFAULT_TB_FREQ;
196 if (cpu != 0)
197 fp = (unsigned int *)get_property(cpu, "timebase-frequency", NULL);
198 if (fp != NULL)
199 ppc_tb_freq = *fp;
200 else
201 printk(KERN_ERR "WARNING: Estimating decrementer frequency (not found)\n");
202 fp = NULL;
203 ppc_proc_freq = DEFAULT_PROC_FREQ;
204 if (cpu != 0)
205 fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL);
206 if (fp != NULL)
207 ppc_proc_freq = *fp;
208 else
209 printk(KERN_ERR "WARNING: Estimating processor frequency (not found)\n");
210
211 of_node_put(cpu);
212
213 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
214 ppc_tb_freq/1000000, ppc_tb_freq%1000000);
215 printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
216 ppc_proc_freq/1000000, ppc_proc_freq%1000000);
217
218 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
219 tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
220 tb_ticks_per_usec = ppc_tb_freq / 1000000;
221 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
222 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
223 tb_to_xs = divres.result_low;
224
225 setup_default_decr();
226}
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h
index 571b3c99e062..63e177143eac 100644
--- a/arch/ppc64/kernel/mpic.h
+++ b/arch/ppc64/kernel/mpic.h
@@ -265,3 +265,6 @@ extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
265extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs); 265extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
266/* This one gets to the primary mpic */ 266/* This one gets to the primary mpic */
267extern int mpic_get_irq(struct pt_regs *regs); 267extern int mpic_get_irq(struct pt_regs *regs);
268
269/* global mpic for pSeries */
270extern struct mpic *pSeries_mpic;
diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
index 0b1cca281408..1f5f141fb7a1 100644
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/ppc64/kernel/pSeries_pci.c
@@ -1,13 +1,11 @@
1/* 1/*
2 * pSeries_pci.c 2 * arch/ppc64/kernel/pSeries_pci.c
3 * 3 *
4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation 4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 * 6 *
7 * pSeries specific routines for PCI. 7 * pSeries specific routines for PCI.
8 * 8 *
9 * Based on code from pci.c and chrp_pci.c
10 *
11 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
@@ -23,430 +21,18 @@
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 22 */
25 23
24#include <linux/init.h>
25#include <linux/ioport.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/threads.h>
28#include <linux/pci.h> 27#include <linux/pci.h>
29#include <linux/string.h> 28#include <linux/string.h>
30#include <linux/init.h>
31#include <linux/bootmem.h>
32 29
33#include <asm/io.h>
34#include <asm/pgtable.h>
35#include <asm/irq.h>
36#include <asm/prom.h>
37#include <asm/machdep.h>
38#include <asm/pci-bridge.h> 30#include <asm/pci-bridge.h>
39#include <asm/iommu.h> 31#include <asm/prom.h>
40#include <asm/rtas.h>
41 32
42#include "mpic.h"
43#include "pci.h" 33#include "pci.h"
44 34
45/* RTAS tokens */ 35static int __initdata s7a_workaround = -1;
46static int read_pci_config;
47static int write_pci_config;
48static int ibm_read_pci_config;
49static int ibm_write_pci_config;
50
51static int s7a_workaround;
52
53extern struct mpic *pSeries_mpic;
54
55static int config_access_valid(struct device_node *dn, int where)
56{
57 if (where < 256)
58 return 1;
59 if (where < 4096 && dn->pci_ext_config_space)
60 return 1;
61
62 return 0;
63}
64
65static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
66{
67 int returnval = -1;
68 unsigned long buid, addr;
69 int ret;
70
71 if (!dn)
72 return PCIBIOS_DEVICE_NOT_FOUND;
73 if (!config_access_valid(dn, where))
74 return PCIBIOS_BAD_REGISTER_NUMBER;
75
76 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
77 (dn->devfn << 8) | (where & 0xff);
78 buid = dn->phb->buid;
79 if (buid) {
80 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
81 addr, buid >> 32, buid & 0xffffffff, size);
82 } else {
83 ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
84 }
85 *val = returnval;
86
87 if (ret)
88 return PCIBIOS_DEVICE_NOT_FOUND;
89
90 if (returnval == EEH_IO_ERROR_VALUE(size)
91 && eeh_dn_check_failure (dn, NULL))
92 return PCIBIOS_DEVICE_NOT_FOUND;
93
94 return PCIBIOS_SUCCESSFUL;
95}
96
97static int rtas_pci_read_config(struct pci_bus *bus,
98 unsigned int devfn,
99 int where, int size, u32 *val)
100{
101 struct device_node *busdn, *dn;
102
103 if (bus->self)
104 busdn = pci_device_to_OF_node(bus->self);
105 else
106 busdn = bus->sysdata; /* must be a phb */
107
108 /* Search only direct children of the bus */
109 for (dn = busdn->child; dn; dn = dn->sibling)
110 if (dn->devfn == devfn)
111 return rtas_read_config(dn, where, size, val);
112 return PCIBIOS_DEVICE_NOT_FOUND;
113}
114
115static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
116{
117 unsigned long buid, addr;
118 int ret;
119
120 if (!dn)
121 return PCIBIOS_DEVICE_NOT_FOUND;
122 if (!config_access_valid(dn, where))
123 return PCIBIOS_BAD_REGISTER_NUMBER;
124
125 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
126 (dn->devfn << 8) | (where & 0xff);
127 buid = dn->phb->buid;
128 if (buid) {
129 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
130 } else {
131 ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
132 }
133
134 if (ret)
135 return PCIBIOS_DEVICE_NOT_FOUND;
136
137 return PCIBIOS_SUCCESSFUL;
138}
139
140static int rtas_pci_write_config(struct pci_bus *bus,
141 unsigned int devfn,
142 int where, int size, u32 val)
143{
144 struct device_node *busdn, *dn;
145
146 if (bus->self)
147 busdn = pci_device_to_OF_node(bus->self);
148 else
149 busdn = bus->sysdata; /* must be a phb */
150
151 /* Search only direct children of the bus */
152 for (dn = busdn->child; dn; dn = dn->sibling)
153 if (dn->devfn == devfn)
154 return rtas_write_config(dn, where, size, val);
155 return PCIBIOS_DEVICE_NOT_FOUND;
156}
157
158struct pci_ops rtas_pci_ops = {
159 rtas_pci_read_config,
160 rtas_pci_write_config
161};
162
163int is_python(struct device_node *dev)
164{
165 char *model = (char *)get_property(dev, "model", NULL);
166
167 if (model && strstr(model, "Python"))
168 return 1;
169
170 return 0;
171}
172
173static int get_phb_reg_prop(struct device_node *dev,
174 unsigned int addr_size_words,
175 struct reg_property64 *reg)
176{
177 unsigned int *ui_ptr = NULL, len;
178
179 /* Found a PHB, now figure out where his registers are mapped. */
180 ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
181 if (ui_ptr == NULL)
182 return 1;
183
184 if (addr_size_words == 1) {
185 reg->address = ((struct reg_property32 *)ui_ptr)->address;
186 reg->size = ((struct reg_property32 *)ui_ptr)->size;
187 } else {
188 *reg = *((struct reg_property64 *)ui_ptr);
189 }
190
191 return 0;
192}
193
194static void python_countermeasures(struct device_node *dev,
195 unsigned int addr_size_words)
196{
197 struct reg_property64 reg_struct;
198 void __iomem *chip_regs;
199 volatile u32 val;
200
201 if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
202 return;
203
204 /* Python's register file is 1 MB in size. */
205 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
206
207 /*
208 * Firmware doesn't always clear this bit which is critical
209 * for good performance - Anton
210 */
211
212#define PRG_CL_RESET_VALID 0x00010000
213
214 val = in_be32(chip_regs + 0xf6030);
215 if (val & PRG_CL_RESET_VALID) {
216 printk(KERN_INFO "Python workaround: ");
217 val &= ~PRG_CL_RESET_VALID;
218 out_be32(chip_regs + 0xf6030, val);
219 /*
220 * We must read it back for changes to
221 * take effect
222 */
223 val = in_be32(chip_regs + 0xf6030);
224 printk("reg0: %x\n", val);
225 }
226
227 iounmap(chip_regs);
228}
229
230void __init init_pci_config_tokens (void)
231{
232 read_pci_config = rtas_token("read-pci-config");
233 write_pci_config = rtas_token("write-pci-config");
234 ibm_read_pci_config = rtas_token("ibm,read-pci-config");
235 ibm_write_pci_config = rtas_token("ibm,write-pci-config");
236}
237
238unsigned long __devinit get_phb_buid (struct device_node *phb)
239{
240 int addr_cells;
241 unsigned int *buid_vals;
242 unsigned int len;
243 unsigned long buid;
244
245 if (ibm_read_pci_config == -1) return 0;
246
247 /* PHB's will always be children of the root node,
248 * or so it is promised by the current firmware. */
249 if (phb->parent == NULL)
250 return 0;
251 if (phb->parent->parent)
252 return 0;
253
254 buid_vals = (unsigned int *) get_property(phb, "reg", &len);
255 if (buid_vals == NULL)
256 return 0;
257
258 addr_cells = prom_n_addr_cells(phb);
259 if (addr_cells == 1) {
260 buid = (unsigned long) buid_vals[0];
261 } else {
262 buid = (((unsigned long)buid_vals[0]) << 32UL) |
263 (((unsigned long)buid_vals[1]) & 0xffffffff);
264 }
265 return buid;
266}
267
268static int phb_set_bus_ranges(struct device_node *dev,
269 struct pci_controller *phb)
270{
271 int *bus_range;
272 unsigned int len;
273
274 bus_range = (int *) get_property(dev, "bus-range", &len);
275 if (bus_range == NULL || len < 2 * sizeof(int)) {
276 return 1;
277 }
278
279 phb->first_busno = bus_range[0];
280 phb->last_busno = bus_range[1];
281
282 return 0;
283}
284
285static int __devinit setup_phb(struct device_node *dev,
286 struct pci_controller *phb,
287 unsigned int addr_size_words)
288{
289 pci_setup_pci_controller(phb);
290
291 if (is_python(dev))
292 python_countermeasures(dev, addr_size_words);
293
294 if (phb_set_bus_ranges(dev, phb))
295 return 1;
296
297 phb->arch_data = dev;
298 phb->ops = &rtas_pci_ops;
299 phb->buid = get_phb_buid(dev);
300
301 return 0;
302}
303
304static void __devinit add_linux_pci_domain(struct device_node *dev,
305 struct pci_controller *phb,
306 struct property *of_prop)
307{
308 memset(of_prop, 0, sizeof(struct property));
309 of_prop->name = "linux,pci-domain";
310 of_prop->length = sizeof(phb->global_number);
311 of_prop->value = (unsigned char *)&of_prop[1];
312 memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
313 prom_add_property(dev, of_prop);
314}
315
316static struct pci_controller * __init alloc_phb(struct device_node *dev,
317 unsigned int addr_size_words)
318{
319 struct pci_controller *phb;
320 struct property *of_prop;
321
322 phb = alloc_bootmem(sizeof(struct pci_controller));
323 if (phb == NULL)
324 return NULL;
325
326 of_prop = alloc_bootmem(sizeof(struct property) +
327 sizeof(phb->global_number));
328 if (!of_prop)
329 return NULL;
330
331 if (setup_phb(dev, phb, addr_size_words))
332 return NULL;
333
334 add_linux_pci_domain(dev, phb, of_prop);
335
336 return phb;
337}
338
339static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
340{
341 struct pci_controller *phb;
342
343 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
344 GFP_KERNEL);
345 if (phb == NULL)
346 return NULL;
347
348 if (setup_phb(dev, phb, addr_size_words))
349 return NULL;
350
351 phb->is_dynamic = 1;
352
353 /* TODO: linux,pci-domain? */
354
355 return phb;
356}
357
358unsigned long __init find_and_init_phbs(void)
359{
360 struct device_node *node;
361 struct pci_controller *phb;
362 unsigned int root_size_cells = 0;
363 unsigned int index;
364 unsigned int *opprop = NULL;
365 struct device_node *root = of_find_node_by_path("/");
366
367 if (ppc64_interrupt_controller == IC_OPEN_PIC) {
368 opprop = (unsigned int *)get_property(root,
369 "platform-open-pic", NULL);
370 }
371
372 root_size_cells = prom_n_size_cells(root);
373
374 index = 0;
375
376 for (node = of_get_next_child(root, NULL);
377 node != NULL;
378 node = of_get_next_child(root, node)) {
379 if (node->type == NULL || strcmp(node->type, "pci") != 0)
380 continue;
381
382 phb = alloc_phb(node, root_size_cells);
383 if (!phb)
384 continue;
385
386 pci_process_bridge_OF_ranges(phb, node);
387 pci_setup_phb_io(phb, index == 0);
388
389 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
390 int addr = root_size_cells * (index + 2) - 1;
391 mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
392 }
393
394 index++;
395 }
396
397 of_node_put(root);
398 pci_devs_phb_init();
399
400 /*
401 * pci_probe_only and pci_assign_all_buses can be set via properties
402 * in chosen.
403 */
404 if (of_chosen) {
405 int *prop;
406
407 prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
408 NULL);
409 if (prop)
410 pci_probe_only = *prop;
411
412 prop = (int *)get_property(of_chosen,
413 "linux,pci-assign-all-buses", NULL);
414 if (prop)
415 pci_assign_all_buses = *prop;
416 }
417
418 return 0;
419}
420
421struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
422{
423 struct device_node *root = of_find_node_by_path("/");
424 unsigned int root_size_cells = 0;
425 struct pci_controller *phb;
426 struct pci_bus *bus;
427 int primary;
428
429 root_size_cells = prom_n_size_cells(root);
430
431 primary = list_empty(&hose_list);
432 phb = alloc_phb_dynamic(dn, root_size_cells);
433 if (!phb)
434 return NULL;
435
436 pci_process_bridge_OF_ranges(phb, dn);
437
438 pci_setup_phb_io_dynamic(phb, primary);
439 of_node_put(root);
440
441 pci_devs_phb_init_dynamic(phb);
442 phb->last_busno = 0xff;
443 bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
444 phb->bus = bus;
445 phb->last_busno = bus->subordinate;
446
447 return phb;
448}
449EXPORT_SYMBOL(init_phb_dynamic);
450 36
451#if 0 37#if 0
452void pcibios_name_device(struct pci_dev *dev) 38void pcibios_name_device(struct pci_dev *dev)
@@ -474,11 +60,12 @@ void pcibios_name_device(struct pci_dev *dev)
474DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); 60DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
475#endif 61#endif
476 62
477static void check_s7a(void) 63static void __init check_s7a(void)
478{ 64{
479 struct device_node *root; 65 struct device_node *root;
480 char *model; 66 char *model;
481 67
68 s7a_workaround = 0;
482 root = of_find_node_by_path("/"); 69 root = of_find_node_by_path("/");
483 if (root) { 70 if (root) {
484 model = get_property(root, "model", NULL); 71 model = get_property(root, "model", NULL);
@@ -488,55 +75,23 @@ static void check_s7a(void)
488 } 75 }
489} 76}
490 77
491/* RPA-specific bits for removing PHBs */ 78void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
492int pcibios_remove_root_bus(struct pci_controller *phb)
493{ 79{
494 struct pci_bus *b = phb->bus; 80 struct pci_dev *dev;
495 struct resource *res;
496 int rc, i;
497
498 res = b->resource[0];
499 if (!res->flags) {
500 printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
501 b->name);
502 return 1;
503 }
504
505 rc = unmap_bus_range(b);
506 if (rc) {
507 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
508 __FUNCTION__, b->name);
509 return 1;
510 }
511 81
512 if (release_resource(res)) { 82 if (s7a_workaround < 0)
513 printk(KERN_ERR "%s: failed to release IO on bus %s\n", 83 check_s7a();
514 __FUNCTION__, b->name); 84 list_for_each_entry(dev, &bus->devices, bus_list) {
515 return 1; 85 pci_read_irq_line(dev);
516 } 86 if (s7a_workaround) {
517 87 if (dev->irq > 16) {
518 for (i = 1; i < 3; ++i) { 88 dev->irq -= 3;
519 res = b->resource[i]; 89 pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
520 if (!res->flags && i == 0) { 90 dev->irq);
521 printk(KERN_ERR "%s: no MEM resource for PHB %s\n", 91 }
522 __FUNCTION__, b->name);
523 return 1;
524 }
525 if (res->flags && release_resource(res)) {
526 printk(KERN_ERR
527 "%s: failed to release IO %d on bus %s\n",
528 __FUNCTION__, i, b->name);
529 return 1;
530 } 92 }
531 } 93 }
532
533 list_del(&phb->list_node);
534 if (phb->is_dynamic)
535 kfree(phb);
536
537 return 0;
538} 94}
539EXPORT_SYMBOL(pcibios_remove_root_bus);
540 95
541static void __init pSeries_request_regions(void) 96static void __init pSeries_request_regions(void)
542{ 97{
@@ -553,20 +108,6 @@ static void __init pSeries_request_regions(void)
553 108
554void __init pSeries_final_fixup(void) 109void __init pSeries_final_fixup(void)
555{ 110{
556 struct pci_dev *dev = NULL;
557
558 check_s7a();
559
560 for_each_pci_dev(dev) {
561 pci_read_irq_line(dev);
562 if (s7a_workaround) {
563 if (dev->irq > 16) {
564 dev->irq -= 3;
565 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
566 }
567 }
568 }
569
570 phbs_remap_io(); 111 phbs_remap_io();
571 pSeries_request_regions(); 112 pSeries_request_regions();
572 113
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
index 6c0d1d58a552..f2b41243342c 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -71,11 +71,6 @@
71#define DBG(fmt...) 71#define DBG(fmt...)
72#endif 72#endif
73 73
74extern void pSeries_final_fixup(void);
75
76extern void pSeries_get_boot_time(struct rtc_time *rtc_time);
77extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
78extern int pSeries_set_rtc_time(struct rtc_time *rtc_time);
79extern void find_udbg_vterm(void); 74extern void find_udbg_vterm(void);
80extern void system_reset_fwnmi(void); /* from head.S */ 75extern void system_reset_fwnmi(void); /* from head.S */
81extern void machine_check_fwnmi(void); /* from head.S */ 76extern void machine_check_fwnmi(void); /* from head.S */
@@ -84,9 +79,6 @@ extern void generic_find_legacy_serial_ports(u64 *physport,
84 79
85int fwnmi_active; /* TRUE if an FWNMI handler is present */ 80int fwnmi_active; /* TRUE if an FWNMI handler is present */
86 81
87extern unsigned long ppc_proc_freq;
88extern unsigned long ppc_tb_freq;
89
90extern void pSeries_system_reset_exception(struct pt_regs *regs); 82extern void pSeries_system_reset_exception(struct pt_regs *regs);
91extern int pSeries_machine_check_exception(struct pt_regs *regs); 83extern int pSeries_machine_check_exception(struct pt_regs *regs);
92 84
@@ -381,171 +373,6 @@ static void __init pSeries_init_early(void)
381} 373}
382 374
383 375
384static void pSeries_progress(char *s, unsigned short hex)
385{
386 struct device_node *root;
387 int width, *p;
388 char *os;
389 static int display_character, set_indicator;
390 static int max_width;
391 static DEFINE_SPINLOCK(progress_lock);
392 static int pending_newline = 0; /* did last write end with unprinted newline? */
393
394 if (!rtas.base)
395 return;
396
397 if (max_width == 0) {
398 if ((root = find_path_device("/rtas")) &&
399 (p = (unsigned int *)get_property(root,
400 "ibm,display-line-length",
401 NULL)))
402 max_width = *p;
403 else
404 max_width = 0x10;
405 display_character = rtas_token("display-character");
406 set_indicator = rtas_token("set-indicator");
407 }
408
409 if (display_character == RTAS_UNKNOWN_SERVICE) {
410 /* use hex display if available */
411 if (set_indicator != RTAS_UNKNOWN_SERVICE)
412 rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
413 return;
414 }
415
416 spin_lock(&progress_lock);
417
418 /*
419 * Last write ended with newline, but we didn't print it since
420 * it would just clear the bottom line of output. Print it now
421 * instead.
422 *
423 * If no newline is pending, print a CR to start output at the
424 * beginning of the line.
425 */
426 if (pending_newline) {
427 rtas_call(display_character, 1, 1, NULL, '\r');
428 rtas_call(display_character, 1, 1, NULL, '\n');
429 pending_newline = 0;
430 } else {
431 rtas_call(display_character, 1, 1, NULL, '\r');
432 }
433
434 width = max_width;
435 os = s;
436 while (*os) {
437 if (*os == '\n' || *os == '\r') {
438 /* Blank to end of line. */
439 while (width-- > 0)
440 rtas_call(display_character, 1, 1, NULL, ' ');
441
442 /* If newline is the last character, save it
443 * until next call to avoid bumping up the
444 * display output.
445 */
446 if (*os == '\n' && !os[1]) {
447 pending_newline = 1;
448 spin_unlock(&progress_lock);
449 return;
450 }
451
452 /* RTAS wants CR-LF, not just LF */
453
454 if (*os == '\n') {
455 rtas_call(display_character, 1, 1, NULL, '\r');
456 rtas_call(display_character, 1, 1, NULL, '\n');
457 } else {
458 /* CR might be used to re-draw a line, so we'll
459 * leave it alone and not add LF.
460 */
461 rtas_call(display_character, 1, 1, NULL, *os);
462 }
463
464 width = max_width;
465 } else {
466 width--;
467 rtas_call(display_character, 1, 1, NULL, *os);
468 }
469
470 os++;
471
472 /* if we overwrite the screen length */
473 if (width <= 0)
474 while ((*os != 0) && (*os != '\n') && (*os != '\r'))
475 os++;
476 }
477
478 /* Blank to end of line. */
479 while (width-- > 0)
480 rtas_call(display_character, 1, 1, NULL, ' ');
481
482 spin_unlock(&progress_lock);
483}
484
485extern void setup_default_decr(void);
486
487/* Some sane defaults: 125 MHz timebase, 1GHz processor */
488#define DEFAULT_TB_FREQ 125000000UL
489#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
490
491static void __init pSeries_calibrate_decr(void)
492{
493 struct device_node *cpu;
494 struct div_result divres;
495 unsigned int *fp;
496 int node_found;
497
498 /*
499 * The cpu node should have a timebase-frequency property
500 * to tell us the rate at which the decrementer counts.
501 */
502 cpu = of_find_node_by_type(NULL, "cpu");
503
504 ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */
505 node_found = 0;
506 if (cpu != 0) {
507 fp = (unsigned int *)get_property(cpu, "timebase-frequency",
508 NULL);
509 if (fp != 0) {
510 node_found = 1;
511 ppc_tb_freq = *fp;
512 }
513 }
514 if (!node_found)
515 printk(KERN_ERR "WARNING: Estimating decrementer frequency "
516 "(not found)\n");
517
518 ppc_proc_freq = DEFAULT_PROC_FREQ;
519 node_found = 0;
520 if (cpu != 0) {
521 fp = (unsigned int *)get_property(cpu, "clock-frequency",
522 NULL);
523 if (fp != 0) {
524 node_found = 1;
525 ppc_proc_freq = *fp;
526 }
527 }
528 if (!node_found)
529 printk(KERN_ERR "WARNING: Estimating processor frequency "
530 "(not found)\n");
531
532 of_node_put(cpu);
533
534 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
535 ppc_tb_freq/1000000, ppc_tb_freq%1000000);
536 printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
537 ppc_proc_freq/1000000, ppc_proc_freq%1000000);
538
539 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
540 tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
541 tb_ticks_per_usec = ppc_tb_freq / 1000000;
542 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
543 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
544 tb_to_xs = divres.result_low;
545
546 setup_default_decr();
547}
548
549static int pSeries_check_legacy_ioport(unsigned int baseport) 376static int pSeries_check_legacy_ioport(unsigned int baseport)
550{ 377{
551 struct device_node *np; 378 struct device_node *np;
@@ -596,16 +423,17 @@ struct machdep_calls __initdata pSeries_md = {
596 .get_cpuinfo = pSeries_get_cpuinfo, 423 .get_cpuinfo = pSeries_get_cpuinfo,
597 .log_error = pSeries_log_error, 424 .log_error = pSeries_log_error,
598 .pcibios_fixup = pSeries_final_fixup, 425 .pcibios_fixup = pSeries_final_fixup,
426 .irq_bus_setup = pSeries_irq_bus_setup,
599 .restart = rtas_restart, 427 .restart = rtas_restart,
600 .power_off = rtas_power_off, 428 .power_off = rtas_power_off,
601 .halt = rtas_halt, 429 .halt = rtas_halt,
602 .panic = rtas_os_term, 430 .panic = rtas_os_term,
603 .cpu_die = pSeries_mach_cpu_die, 431 .cpu_die = pSeries_mach_cpu_die,
604 .get_boot_time = pSeries_get_boot_time, 432 .get_boot_time = rtas_get_boot_time,
605 .get_rtc_time = pSeries_get_rtc_time, 433 .get_rtc_time = rtas_get_rtc_time,
606 .set_rtc_time = pSeries_set_rtc_time, 434 .set_rtc_time = rtas_set_rtc_time,
607 .calibrate_decr = pSeries_calibrate_decr, 435 .calibrate_decr = generic_calibrate_decr,
608 .progress = pSeries_progress, 436 .progress = rtas_progress,
609 .check_legacy_ioport = pSeries_check_legacy_ioport, 437 .check_legacy_ioport = pSeries_check_legacy_ioport,
610 .system_reset_exception = pSeries_system_reset_exception, 438 .system_reset_exception = pSeries_system_reset_exception,
611 .machine_check_exception = pSeries_machine_check_exception, 439 .machine_check_exception = pSeries_machine_check_exception,
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index 4203bd020c82..30154140f7e2 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * SMP support for pSeries machines. 2 * SMP support for pSeries and BPA machines.
3 * 3 *
4 * Dave Engebretsen, Peter Bergner, and 4 * Dave Engebretsen, Peter Bergner, and
5 * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com 5 * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
@@ -47,6 +47,7 @@
47#include <asm/pSeries_reconfig.h> 47#include <asm/pSeries_reconfig.h>
48 48
49#include "mpic.h" 49#include "mpic.h"
50#include "bpa_iic.h"
50 51
51#ifdef DEBUG 52#ifdef DEBUG
52#define DBG(fmt...) udbg_printf(fmt) 53#define DBG(fmt...) udbg_printf(fmt)
@@ -286,6 +287,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
286 return 1; 287 return 1;
287} 288}
288 289
290#ifdef CONFIG_XICS
289static inline void smp_xics_do_message(int cpu, int msg) 291static inline void smp_xics_do_message(int cpu, int msg)
290{ 292{
291 set_bit(msg, &xics_ipi_message[cpu].value); 293 set_bit(msg, &xics_ipi_message[cpu].value);
@@ -327,6 +329,37 @@ static void __devinit smp_xics_setup_cpu(int cpu)
327 cpu_clear(cpu, of_spin_map); 329 cpu_clear(cpu, of_spin_map);
328 330
329} 331}
332#endif /* CONFIG_XICS */
333#ifdef CONFIG_BPA_IIC
334static void smp_iic_message_pass(int target, int msg)
335{
336 unsigned int i;
337
338 if (target < NR_CPUS) {
339 iic_cause_IPI(target, msg);
340 } else {
341 for_each_online_cpu(i) {
342 if (target == MSG_ALL_BUT_SELF
343 && i == smp_processor_id())
344 continue;
345 iic_cause_IPI(i, msg);
346 }
347 }
348}
349
350static int __init smp_iic_probe(void)
351{
352 iic_request_IPIs();
353
354 return cpus_weight(cpu_possible_map);
355}
356
357static void __devinit smp_iic_setup_cpu(int cpu)
358{
359 if (cpu != boot_cpuid)
360 iic_setup_cpu();
361}
362#endif /* CONFIG_BPA_IIC */
330 363
331static DEFINE_SPINLOCK(timebase_lock); 364static DEFINE_SPINLOCK(timebase_lock);
332static unsigned long timebase = 0; 365static unsigned long timebase = 0;
@@ -381,14 +414,15 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
381 414
382 return 1; 415 return 1;
383} 416}
384 417#ifdef CONFIG_MPIC
385static struct smp_ops_t pSeries_mpic_smp_ops = { 418static struct smp_ops_t pSeries_mpic_smp_ops = {
386 .message_pass = smp_mpic_message_pass, 419 .message_pass = smp_mpic_message_pass,
387 .probe = smp_mpic_probe, 420 .probe = smp_mpic_probe,
388 .kick_cpu = smp_pSeries_kick_cpu, 421 .kick_cpu = smp_pSeries_kick_cpu,
389 .setup_cpu = smp_mpic_setup_cpu, 422 .setup_cpu = smp_mpic_setup_cpu,
390}; 423};
391 424#endif
425#ifdef CONFIG_XICS
392static struct smp_ops_t pSeries_xics_smp_ops = { 426static struct smp_ops_t pSeries_xics_smp_ops = {
393 .message_pass = smp_xics_message_pass, 427 .message_pass = smp_xics_message_pass,
394 .probe = smp_xics_probe, 428 .probe = smp_xics_probe,
@@ -396,6 +430,16 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
396 .setup_cpu = smp_xics_setup_cpu, 430 .setup_cpu = smp_xics_setup_cpu,
397 .cpu_bootable = smp_pSeries_cpu_bootable, 431 .cpu_bootable = smp_pSeries_cpu_bootable,
398}; 432};
433#endif
434#ifdef CONFIG_BPA_IIC
435static struct smp_ops_t bpa_iic_smp_ops = {
436 .message_pass = smp_iic_message_pass,
437 .probe = smp_iic_probe,
438 .kick_cpu = smp_pSeries_kick_cpu,
439 .setup_cpu = smp_iic_setup_cpu,
440 .cpu_bootable = smp_pSeries_cpu_bootable,
441};
442#endif
399 443
400/* This is called very early */ 444/* This is called very early */
401void __init smp_init_pSeries(void) 445void __init smp_init_pSeries(void)
@@ -404,10 +448,25 @@ void __init smp_init_pSeries(void)
404 448
405 DBG(" -> smp_init_pSeries()\n"); 449 DBG(" -> smp_init_pSeries()\n");
406 450
407 if (ppc64_interrupt_controller == IC_OPEN_PIC) 451 switch (ppc64_interrupt_controller) {
452#ifdef CONFIG_MPIC
453 case IC_OPEN_PIC:
408 smp_ops = &pSeries_mpic_smp_ops; 454 smp_ops = &pSeries_mpic_smp_ops;
409 else 455 break;
456#endif
457#ifdef CONFIG_XICS
458 case IC_PPC_XIC:
410 smp_ops = &pSeries_xics_smp_ops; 459 smp_ops = &pSeries_xics_smp_ops;
460 break;
461#endif
462#ifdef CONFIG_BPA_IIC
463 case IC_BPA_IIC:
464 smp_ops = &bpa_iic_smp_ops;
465 break;
466#endif
467 default:
468 panic("Invalid interrupt controller");
469 }
411 470
412#ifdef CONFIG_HOTPLUG_CPU 471#ifdef CONFIG_HOTPLUG_CPU
413 smp_ops->cpu_disable = pSeries_cpu_disable; 472 smp_ops->cpu_disable = pSeries_cpu_disable;
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index 2bf0513f3eca..580676f87d23 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -902,6 +902,9 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
902 list_for_each_entry(dev, &bus->devices, bus_list) 902 list_for_each_entry(dev, &bus->devices, bus_list)
903 ppc_md.iommu_dev_setup(dev); 903 ppc_md.iommu_dev_setup(dev);
904 904
905 if (ppc_md.irq_bus_setup)
906 ppc_md.irq_bus_setup(bus);
907
905 if (!pci_probe_only) 908 if (!pci_probe_only)
906 return; 909 return;
907 910
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
index 0fd7d849aa77..26be78b13af1 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -40,10 +40,14 @@ struct device_node *fetch_dev_dn(struct pci_dev *dev);
40void pci_addr_cache_insert_device(struct pci_dev *dev); 40void pci_addr_cache_insert_device(struct pci_dev *dev);
41void pci_addr_cache_remove_device(struct pci_dev *dev); 41void pci_addr_cache_remove_device(struct pci_dev *dev);
42 42
43/* From pSeries_pci.h */ 43/* From rtas_pci.h */
44void init_pci_config_tokens (void); 44void init_pci_config_tokens (void);
45unsigned long get_phb_buid (struct device_node *); 45unsigned long get_phb_buid (struct device_node *);
46 46
47/* From pSeries_pci.h */
48extern void pSeries_final_fixup(void);
49extern void pSeries_irq_bus_setup(struct pci_bus *bus);
50
47extern unsigned long pci_probe_only; 51extern unsigned long pci_probe_only;
48extern unsigned long pci_assign_all_buses; 52extern unsigned long pci_assign_all_buses;
49extern int pci_read_irq_line(struct pci_dev *pci_dev); 53extern int pci_read_irq_line(struct pci_dev *pci_dev);
diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c
index f24827581dd7..3059edb09cc8 100644
--- a/arch/ppc64/kernel/pmac_time.c
+++ b/arch/ppc64/kernel/pmac_time.c
@@ -40,11 +40,6 @@
40#define DBG(x...) 40#define DBG(x...)
41#endif 41#endif
42 42
43extern void setup_default_decr(void);
44
45extern unsigned long ppc_tb_freq;
46extern unsigned long ppc_proc_freq;
47
48/* Apparently the RTC stores seconds since 1 Jan 1904 */ 43/* Apparently the RTC stores seconds since 1 Jan 1904 */
49#define RTC_OFFSET 2082844800 44#define RTC_OFFSET 2082844800
50 45
@@ -161,8 +156,7 @@ void __init pmac_get_boot_time(struct rtc_time *tm)
161 156
162/* 157/*
163 * Query the OF and get the decr frequency. 158 * Query the OF and get the decr frequency.
164 * This was taken from the pmac time_init() when merging the prep/pmac 159 * FIXME: merge this with generic_calibrate_decr
165 * time functions.
166 */ 160 */
167void __init pmac_calibrate_decr(void) 161void __init pmac_calibrate_decr(void)
168{ 162{
diff --git a/arch/ppc64/kernel/proc_ppc64.c b/arch/ppc64/kernel/proc_ppc64.c
index 0914b0669b05..a87c66a9652a 100644
--- a/arch/ppc64/kernel/proc_ppc64.c
+++ b/arch/ppc64/kernel/proc_ppc64.c
@@ -53,7 +53,7 @@ static int __init proc_ppc64_create(void)
53 if (!root) 53 if (!root)
54 return 1; 54 return 1;
55 55
56 if (!(systemcfg->platform & PLATFORM_PSERIES)) 56 if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_BPA)))
57 return 0; 57 return 0;
58 58
59 if (!proc_mkdir("rtas", root)) 59 if (!proc_mkdir("rtas", root))
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
index b7683abfbe6a..e248a7950aeb 100644
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -1915,9 +1915,9 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
1915 prom_send_capabilities(); 1915 prom_send_capabilities();
1916 1916
1917 /* 1917 /*
1918 * On pSeries, copy the CPU hold code 1918 * On pSeries and BPA, copy the CPU hold code
1919 */ 1919 */
1920 if (RELOC(of_platform) & PLATFORM_PSERIES) 1920 if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA))
1921 copy_and_flush(0, KERNELBASE - offset, 0x100, 0); 1921 copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
1922 1922
1923 /* 1923 /*
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 9f8c6087ae56..2993f108d96d 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -305,6 +305,8 @@ static void do_syscall_trace(void)
305 305
306void do_syscall_trace_enter(struct pt_regs *regs) 306void do_syscall_trace_enter(struct pt_regs *regs)
307{ 307{
308 secure_computing(regs->gpr[0]);
309
308 if (test_thread_flag(TIF_SYSCALL_TRACE) 310 if (test_thread_flag(TIF_SYSCALL_TRACE)
309 && (current->ptrace & PT_PTRACED)) 311 && (current->ptrace & PT_PTRACED))
310 do_syscall_trace(); 312 do_syscall_trace();
@@ -320,8 +322,6 @@ void do_syscall_trace_enter(struct pt_regs *regs)
320 322
321void do_syscall_trace_leave(struct pt_regs *regs) 323void do_syscall_trace_leave(struct pt_regs *regs)
322{ 324{
323 secure_computing(regs->gpr[0]);
324
325 if (unlikely(current->audit_context)) 325 if (unlikely(current->audit_context))
326 audit_syscall_exit(current, 326 audit_syscall_exit(current,
327 (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, 327 (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
index 28b1f1521f21..1f3ff860fdf0 100644
--- a/arch/ppc64/kernel/rtas-proc.c
+++ b/arch/ppc64/kernel/rtas-proc.c
@@ -371,11 +371,11 @@ static ssize_t ppc_rtas_progress_write(struct file *file,
371 /* Lets see if the user passed hexdigits */ 371 /* Lets see if the user passed hexdigits */
372 hex = simple_strtoul(progress_led, NULL, 10); 372 hex = simple_strtoul(progress_led, NULL, 10);
373 373
374 ppc_md.progress ((char *)progress_led, hex); 374 rtas_progress ((char *)progress_led, hex);
375 return count; 375 return count;
376 376
377 /* clear the line */ 377 /* clear the line */
378 /* ppc_md.progress(" ", 0xffff);*/ 378 /* rtas_progress(" ", 0xffff);*/
379} 379}
380/* ****************************************************************** */ 380/* ****************************************************************** */
381static int ppc_rtas_progress_show(struct seq_file *m, void *v) 381static int ppc_rtas_progress_show(struct seq_file *m, void *v)
diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
index 5575603def27..5e8eb33b8e54 100644
--- a/arch/ppc64/kernel/rtas.c
+++ b/arch/ppc64/kernel/rtas.c
@@ -91,6 +91,123 @@ call_rtas_display_status_delay(unsigned char c)
91 } 91 }
92} 92}
93 93
94void
95rtas_progress(char *s, unsigned short hex)
96{
97 struct device_node *root;
98 int width, *p;
99 char *os;
100 static int display_character, set_indicator;
101 static int display_width, display_lines, *row_width, form_feed;
102 static DEFINE_SPINLOCK(progress_lock);
103 static int current_line;
104 static int pending_newline = 0; /* did last write end with unprinted newline? */
105
106 if (!rtas.base)
107 return;
108
109 if (display_width == 0) {
110 display_width = 0x10;
111 if ((root = find_path_device("/rtas"))) {
112 if ((p = (unsigned int *)get_property(root,
113 "ibm,display-line-length", NULL)))
114 display_width = *p;
115 if ((p = (unsigned int *)get_property(root,
116 "ibm,form-feed", NULL)))
117 form_feed = *p;
118 if ((p = (unsigned int *)get_property(root,
119 "ibm,display-number-of-lines", NULL)))
120 display_lines = *p;
121 row_width = (unsigned int *)get_property(root,
122 "ibm,display-truncation-length", NULL);
123 }
124 display_character = rtas_token("display-character");
125 set_indicator = rtas_token("set-indicator");
126 }
127
128 if (display_character == RTAS_UNKNOWN_SERVICE) {
129 /* use hex display if available */
130 if (set_indicator != RTAS_UNKNOWN_SERVICE)
131 rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
132 return;
133 }
134
135 spin_lock(&progress_lock);
136
137 /*
138 * Last write ended with newline, but we didn't print it since
139 * it would just clear the bottom line of output. Print it now
140 * instead.
141 *
142 * If no newline is pending and form feed is supported, clear the
143 * display with a form feed; otherwise, print a CR to start output
144 * at the beginning of the line.
145 */
146 if (pending_newline) {
147 rtas_call(display_character, 1, 1, NULL, '\r');
148 rtas_call(display_character, 1, 1, NULL, '\n');
149 pending_newline = 0;
150 } else {
151 current_line = 0;
152 if (form_feed)
153 rtas_call(display_character, 1, 1, NULL,
154 (char)form_feed);
155 else
156 rtas_call(display_character, 1, 1, NULL, '\r');
157 }
158
159 if (row_width)
160 width = row_width[current_line];
161 else
162 width = display_width;
163 os = s;
164 while (*os) {
165 if (*os == '\n' || *os == '\r') {
166 /* If newline is the last character, save it
167 * until next call to avoid bumping up the
168 * display output.
169 */
170 if (*os == '\n' && !os[1]) {
171 pending_newline = 1;
172 current_line++;
173 if (current_line > display_lines-1)
174 current_line = display_lines-1;
175 spin_unlock(&progress_lock);
176 return;
177 }
178
179 /* RTAS wants CR-LF, not just LF */
180
181 if (*os == '\n') {
182 rtas_call(display_character, 1, 1, NULL, '\r');
183 rtas_call(display_character, 1, 1, NULL, '\n');
184 } else {
185 /* CR might be used to re-draw a line, so we'll
186 * leave it alone and not add LF.
187 */
188 rtas_call(display_character, 1, 1, NULL, *os);
189 }
190
191 if (row_width)
192 width = row_width[current_line];
193 else
194 width = display_width;
195 } else {
196 width--;
197 rtas_call(display_character, 1, 1, NULL, *os);
198 }
199
200 os++;
201
202 /* if we overwrite the screen length */
203 if (width <= 0)
204 while ((*os != 0) && (*os != '\n') && (*os != '\r'))
205 os++;
206 }
207
208 spin_unlock(&progress_lock);
209}
210
94int 211int
95rtas_token(const char *service) 212rtas_token(const char *service)
96{ 213{
@@ -425,8 +542,8 @@ rtas_flash_firmware(void)
425 542
426 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); 543 printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
427 printk(KERN_ALERT "FLASH: performing flash and reboot\n"); 544 printk(KERN_ALERT "FLASH: performing flash and reboot\n");
428 ppc_md.progress("Flashing \n", 0x0); 545 rtas_progress("Flashing \n", 0x0);
429 ppc_md.progress("Please Wait... ", 0x0); 546 rtas_progress("Please Wait... ", 0x0);
430 printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); 547 printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n");
431 status = rtas_call(update_token, 1, 1, NULL, rtas_block_list); 548 status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
432 switch (status) { /* should only get "bad" status */ 549 switch (status) { /* should only get "bad" status */
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
new file mode 100644
index 000000000000..1048817befb8
--- /dev/null
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -0,0 +1,495 @@
1/*
2 * arch/ppc64/kernel/rtas_pci.c
3 *
4 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
6 *
7 * RTAS specific routines for PCI.
8 *
9 * Based on code from pci.c, chrp_pci.c and pSeries_pci.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/threads.h>
28#include <linux/pci.h>
29#include <linux/string.h>
30#include <linux/init.h>
31#include <linux/bootmem.h>
32
33#include <asm/io.h>
34#include <asm/pgtable.h>
35#include <asm/irq.h>
36#include <asm/prom.h>
37#include <asm/machdep.h>
38#include <asm/pci-bridge.h>
39#include <asm/iommu.h>
40#include <asm/rtas.h>
41
42#include "mpic.h"
43#include "pci.h"
44
45/* RTAS tokens */
46static int read_pci_config;
47static int write_pci_config;
48static int ibm_read_pci_config;
49static int ibm_write_pci_config;
50
51static int config_access_valid(struct device_node *dn, int where)
52{
53 if (where < 256)
54 return 1;
55 if (where < 4096 && dn->pci_ext_config_space)
56 return 1;
57
58 return 0;
59}
60
61static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
62{
63 int returnval = -1;
64 unsigned long buid, addr;
65 int ret;
66
67 if (!dn)
68 return PCIBIOS_DEVICE_NOT_FOUND;
69 if (!config_access_valid(dn, where))
70 return PCIBIOS_BAD_REGISTER_NUMBER;
71
72 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
73 (dn->devfn << 8) | (where & 0xff);
74 buid = dn->phb->buid;
75 if (buid) {
76 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
77 addr, buid >> 32, buid & 0xffffffff, size);
78 } else {
79 ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
80 }
81 *val = returnval;
82
83 if (ret)
84 return PCIBIOS_DEVICE_NOT_FOUND;
85
86 if (returnval == EEH_IO_ERROR_VALUE(size)
87 && eeh_dn_check_failure (dn, NULL))
88 return PCIBIOS_DEVICE_NOT_FOUND;
89
90 return PCIBIOS_SUCCESSFUL;
91}
92
93static int rtas_pci_read_config(struct pci_bus *bus,
94 unsigned int devfn,
95 int where, int size, u32 *val)
96{
97 struct device_node *busdn, *dn;
98
99 if (bus->self)
100 busdn = pci_device_to_OF_node(bus->self);
101 else
102 busdn = bus->sysdata; /* must be a phb */
103
104 /* Search only direct children of the bus */
105 for (dn = busdn->child; dn; dn = dn->sibling)
106 if (dn->devfn == devfn)
107 return rtas_read_config(dn, where, size, val);
108 return PCIBIOS_DEVICE_NOT_FOUND;
109}
110
111static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
112{
113 unsigned long buid, addr;
114 int ret;
115
116 if (!dn)
117 return PCIBIOS_DEVICE_NOT_FOUND;
118 if (!config_access_valid(dn, where))
119 return PCIBIOS_BAD_REGISTER_NUMBER;
120
121 addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
122 (dn->devfn << 8) | (where & 0xff);
123 buid = dn->phb->buid;
124 if (buid) {
125 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
126 } else {
127 ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
128 }
129
130 if (ret)
131 return PCIBIOS_DEVICE_NOT_FOUND;
132
133 return PCIBIOS_SUCCESSFUL;
134}
135
136static int rtas_pci_write_config(struct pci_bus *bus,
137 unsigned int devfn,
138 int where, int size, u32 val)
139{
140 struct device_node *busdn, *dn;
141
142 if (bus->self)
143 busdn = pci_device_to_OF_node(bus->self);
144 else
145 busdn = bus->sysdata; /* must be a phb */
146
147 /* Search only direct children of the bus */
148 for (dn = busdn->child; dn; dn = dn->sibling)
149 if (dn->devfn == devfn)
150 return rtas_write_config(dn, where, size, val);
151 return PCIBIOS_DEVICE_NOT_FOUND;
152}
153
154struct pci_ops rtas_pci_ops = {
155 rtas_pci_read_config,
156 rtas_pci_write_config
157};
158
159int is_python(struct device_node *dev)
160{
161 char *model = (char *)get_property(dev, "model", NULL);
162
163 if (model && strstr(model, "Python"))
164 return 1;
165
166 return 0;
167}
168
169static int get_phb_reg_prop(struct device_node *dev,
170 unsigned int addr_size_words,
171 struct reg_property64 *reg)
172{
173 unsigned int *ui_ptr = NULL, len;
174
175 /* Found a PHB, now figure out where his registers are mapped. */
176 ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
177 if (ui_ptr == NULL)
178 return 1;
179
180 if (addr_size_words == 1) {
181 reg->address = ((struct reg_property32 *)ui_ptr)->address;
182 reg->size = ((struct reg_property32 *)ui_ptr)->size;
183 } else {
184 *reg = *((struct reg_property64 *)ui_ptr);
185 }
186
187 return 0;
188}
189
190static void python_countermeasures(struct device_node *dev,
191 unsigned int addr_size_words)
192{
193 struct reg_property64 reg_struct;
194 void __iomem *chip_regs;
195 volatile u32 val;
196
197 if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
198 return;
199
200 /* Python's register file is 1 MB in size. */
201 chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
202
203 /*
204 * Firmware doesn't always clear this bit which is critical
205 * for good performance - Anton
206 */
207
208#define PRG_CL_RESET_VALID 0x00010000
209
210 val = in_be32(chip_regs + 0xf6030);
211 if (val & PRG_CL_RESET_VALID) {
212 printk(KERN_INFO "Python workaround: ");
213 val &= ~PRG_CL_RESET_VALID;
214 out_be32(chip_regs + 0xf6030, val);
215 /*
216 * We must read it back for changes to
217 * take effect
218 */
219 val = in_be32(chip_regs + 0xf6030);
220 printk("reg0: %x\n", val);
221 }
222
223 iounmap(chip_regs);
224}
225
226void __init init_pci_config_tokens (void)
227{
228 read_pci_config = rtas_token("read-pci-config");
229 write_pci_config = rtas_token("write-pci-config");
230 ibm_read_pci_config = rtas_token("ibm,read-pci-config");
231 ibm_write_pci_config = rtas_token("ibm,write-pci-config");
232}
233
234unsigned long __devinit get_phb_buid (struct device_node *phb)
235{
236 int addr_cells;
237 unsigned int *buid_vals;
238 unsigned int len;
239 unsigned long buid;
240
241 if (ibm_read_pci_config == -1) return 0;
242
243 /* PHB's will always be children of the root node,
244 * or so it is promised by the current firmware. */
245 if (phb->parent == NULL)
246 return 0;
247 if (phb->parent->parent)
248 return 0;
249
250 buid_vals = (unsigned int *) get_property(phb, "reg", &len);
251 if (buid_vals == NULL)
252 return 0;
253
254 addr_cells = prom_n_addr_cells(phb);
255 if (addr_cells == 1) {
256 buid = (unsigned long) buid_vals[0];
257 } else {
258 buid = (((unsigned long)buid_vals[0]) << 32UL) |
259 (((unsigned long)buid_vals[1]) & 0xffffffff);
260 }
261 return buid;
262}
263
264static int phb_set_bus_ranges(struct device_node *dev,
265 struct pci_controller *phb)
266{
267 int *bus_range;
268 unsigned int len;
269
270 bus_range = (int *) get_property(dev, "bus-range", &len);
271 if (bus_range == NULL || len < 2 * sizeof(int)) {
272 return 1;
273 }
274
275 phb->first_busno = bus_range[0];
276 phb->last_busno = bus_range[1];
277
278 return 0;
279}
280
281static int __devinit setup_phb(struct device_node *dev,
282 struct pci_controller *phb,
283 unsigned int addr_size_words)
284{
285 pci_setup_pci_controller(phb);
286
287 if (is_python(dev))
288 python_countermeasures(dev, addr_size_words);
289
290 if (phb_set_bus_ranges(dev, phb))
291 return 1;
292
293 phb->arch_data = dev;
294 phb->ops = &rtas_pci_ops;
295 phb->buid = get_phb_buid(dev);
296
297 return 0;
298}
299
300static void __devinit add_linux_pci_domain(struct device_node *dev,
301 struct pci_controller *phb,
302 struct property *of_prop)
303{
304 memset(of_prop, 0, sizeof(struct property));
305 of_prop->name = "linux,pci-domain";
306 of_prop->length = sizeof(phb->global_number);
307 of_prop->value = (unsigned char *)&of_prop[1];
308 memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
309 prom_add_property(dev, of_prop);
310}
311
312static struct pci_controller * __init alloc_phb(struct device_node *dev,
313 unsigned int addr_size_words)
314{
315 struct pci_controller *phb;
316 struct property *of_prop;
317
318 phb = alloc_bootmem(sizeof(struct pci_controller));
319 if (phb == NULL)
320 return NULL;
321
322 of_prop = alloc_bootmem(sizeof(struct property) +
323 sizeof(phb->global_number));
324 if (!of_prop)
325 return NULL;
326
327 if (setup_phb(dev, phb, addr_size_words))
328 return NULL;
329
330 add_linux_pci_domain(dev, phb, of_prop);
331
332 return phb;
333}
334
335static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
336{
337 struct pci_controller *phb;
338
339 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
340 GFP_KERNEL);
341 if (phb == NULL)
342 return NULL;
343
344 if (setup_phb(dev, phb, addr_size_words))
345 return NULL;
346
347 phb->is_dynamic = 1;
348
349 /* TODO: linux,pci-domain? */
350
351 return phb;
352}
353
354unsigned long __init find_and_init_phbs(void)
355{
356 struct device_node *node;
357 struct pci_controller *phb;
358 unsigned int root_size_cells = 0;
359 unsigned int index;
360 unsigned int *opprop = NULL;
361 struct device_node *root = of_find_node_by_path("/");
362
363 if (ppc64_interrupt_controller == IC_OPEN_PIC) {
364 opprop = (unsigned int *)get_property(root,
365 "platform-open-pic", NULL);
366 }
367
368 root_size_cells = prom_n_size_cells(root);
369
370 index = 0;
371
372 for (node = of_get_next_child(root, NULL);
373 node != NULL;
374 node = of_get_next_child(root, node)) {
375 if (node->type == NULL || strcmp(node->type, "pci") != 0)
376 continue;
377
378 phb = alloc_phb(node, root_size_cells);
379 if (!phb)
380 continue;
381
382 pci_process_bridge_OF_ranges(phb, node);
383 pci_setup_phb_io(phb, index == 0);
384#ifdef CONFIG_PPC_PSERIES
385 if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
386 int addr = root_size_cells * (index + 2) - 1;
387 mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
388 }
389#endif
390 index++;
391 }
392
393 of_node_put(root);
394 pci_devs_phb_init();
395
396 /*
397 * pci_probe_only and pci_assign_all_buses can be set via properties
398 * in chosen.
399 */
400 if (of_chosen) {
401 int *prop;
402
403 prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
404 NULL);
405 if (prop)
406 pci_probe_only = *prop;
407
408 prop = (int *)get_property(of_chosen,
409 "linux,pci-assign-all-buses", NULL);
410 if (prop)
411 pci_assign_all_buses = *prop;
412 }
413
414 return 0;
415}
416
417struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
418{
419 struct device_node *root = of_find_node_by_path("/");
420 unsigned int root_size_cells = 0;
421 struct pci_controller *phb;
422 struct pci_bus *bus;
423 int primary;
424
425 root_size_cells = prom_n_size_cells(root);
426
427 primary = list_empty(&hose_list);
428 phb = alloc_phb_dynamic(dn, root_size_cells);
429 if (!phb)
430 return NULL;
431
432 pci_process_bridge_OF_ranges(phb, dn);
433
434 pci_setup_phb_io_dynamic(phb, primary);
435 of_node_put(root);
436
437 pci_devs_phb_init_dynamic(phb);
438 phb->last_busno = 0xff;
439 bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
440 phb->bus = bus;
441 phb->last_busno = bus->subordinate;
442
443 return phb;
444}
445EXPORT_SYMBOL(init_phb_dynamic);
446
447/* RPA-specific bits for removing PHBs */
448int pcibios_remove_root_bus(struct pci_controller *phb)
449{
450 struct pci_bus *b = phb->bus;
451 struct resource *res;
452 int rc, i;
453
454 res = b->resource[0];
455 if (!res->flags) {
456 printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
457 b->name);
458 return 1;
459 }
460
461 rc = unmap_bus_range(b);
462 if (rc) {
463 printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
464 __FUNCTION__, b->name);
465 return 1;
466 }
467
468 if (release_resource(res)) {
469 printk(KERN_ERR "%s: failed to release IO on bus %s\n",
470 __FUNCTION__, b->name);
471 return 1;
472 }
473
474 for (i = 1; i < 3; ++i) {
475 res = b->resource[i];
476 if (!res->flags && i == 0) {
477 printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
478 __FUNCTION__, b->name);
479 return 1;
480 }
481 if (res->flags && release_resource(res)) {
482 printk(KERN_ERR
483 "%s: failed to release IO %d on bus %s\n",
484 __FUNCTION__, i, b->name);
485 return 1;
486 }
487 }
488
489 list_del(&phb->list_node);
490 if (phb->is_dynamic)
491 kfree(phb);
492
493 return 0;
494}
495EXPORT_SYMBOL(pcibios_remove_root_bus);
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
index de02aedbe080..d729fefa0df5 100644
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -301,7 +301,7 @@ void iSeries_get_boot_time(struct rtc_time *tm)
301#ifdef CONFIG_PPC_RTAS 301#ifdef CONFIG_PPC_RTAS
302#define MAX_RTC_WAIT 5000 /* 5 sec */ 302#define MAX_RTC_WAIT 5000 /* 5 sec */
303#define RTAS_CLOCK_BUSY (-2) 303#define RTAS_CLOCK_BUSY (-2)
304void pSeries_get_boot_time(struct rtc_time *rtc_tm) 304void rtas_get_boot_time(struct rtc_time *rtc_tm)
305{ 305{
306 int ret[8]; 306 int ret[8];
307 int error, wait_time; 307 int error, wait_time;
@@ -336,7 +336,7 @@ void pSeries_get_boot_time(struct rtc_time *rtc_tm)
336 * and if a delay is needed to read the clock. In this case we just 336 * and if a delay is needed to read the clock. In this case we just
337 * silently return without updating rtc_tm. 337 * silently return without updating rtc_tm.
338 */ 338 */
339void pSeries_get_rtc_time(struct rtc_time *rtc_tm) 339void rtas_get_rtc_time(struct rtc_time *rtc_tm)
340{ 340{
341 int ret[8]; 341 int ret[8];
342 int error, wait_time; 342 int error, wait_time;
@@ -371,7 +371,7 @@ void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
371 rtc_tm->tm_year = ret[0] - 1900; 371 rtc_tm->tm_year = ret[0] - 1900;
372} 372}
373 373
374int pSeries_set_rtc_time(struct rtc_time *tm) 374int rtas_set_rtc_time(struct rtc_time *tm)
375{ 375{
376 int error, wait_time; 376 int error, wait_time;
377 unsigned long max_wait_tb; 377 unsigned long max_wait_tb;
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index 8e439a817642..0a47a5ef428d 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -344,6 +344,7 @@ static void __init setup_cpu_maps(void)
344extern struct machdep_calls pSeries_md; 344extern struct machdep_calls pSeries_md;
345extern struct machdep_calls pmac_md; 345extern struct machdep_calls pmac_md;
346extern struct machdep_calls maple_md; 346extern struct machdep_calls maple_md;
347extern struct machdep_calls bpa_md;
347 348
348/* Ultimately, stuff them in an elf section like initcalls... */ 349/* Ultimately, stuff them in an elf section like initcalls... */
349static struct machdep_calls __initdata *machines[] = { 350static struct machdep_calls __initdata *machines[] = {
@@ -356,6 +357,9 @@ static struct machdep_calls __initdata *machines[] = {
356#ifdef CONFIG_PPC_MAPLE 357#ifdef CONFIG_PPC_MAPLE
357 &maple_md, 358 &maple_md,
358#endif /* CONFIG_PPC_MAPLE */ 359#endif /* CONFIG_PPC_MAPLE */
360#ifdef CONFIG_PPC_BPA
361 &bpa_md,
362#endif
359 NULL 363 NULL
360}; 364};
361 365
@@ -679,6 +683,12 @@ void machine_restart(char *cmd)
679 if (ppc_md.nvram_sync) 683 if (ppc_md.nvram_sync)
680 ppc_md.nvram_sync(); 684 ppc_md.nvram_sync();
681 ppc_md.restart(cmd); 685 ppc_md.restart(cmd);
686#ifdef CONFIG_SMP
687 smp_send_stop();
688#endif
689 printk(KERN_EMERG "System Halted, OK to turn off power\n");
690 local_irq_disable();
691 while (1) ;
682} 692}
683 693
684EXPORT_SYMBOL(machine_restart); 694EXPORT_SYMBOL(machine_restart);
@@ -688,6 +698,12 @@ void machine_power_off(void)
688 if (ppc_md.nvram_sync) 698 if (ppc_md.nvram_sync)
689 ppc_md.nvram_sync(); 699 ppc_md.nvram_sync();
690 ppc_md.power_off(); 700 ppc_md.power_off();
701#ifdef CONFIG_SMP
702 smp_send_stop();
703#endif
704 printk(KERN_EMERG "System Halted, OK to turn off power\n");
705 local_irq_disable();
706 while (1) ;
691} 707}
692 708
693EXPORT_SYMBOL(machine_power_off); 709EXPORT_SYMBOL(machine_power_off);
@@ -697,13 +713,16 @@ void machine_halt(void)
697 if (ppc_md.nvram_sync) 713 if (ppc_md.nvram_sync)
698 ppc_md.nvram_sync(); 714 ppc_md.nvram_sync();
699 ppc_md.halt(); 715 ppc_md.halt();
716#ifdef CONFIG_SMP
717 smp_send_stop();
718#endif
719 printk(KERN_EMERG "System Halted, OK to turn off power\n");
720 local_irq_disable();
721 while (1) ;
700} 722}
701 723
702EXPORT_SYMBOL(machine_halt); 724EXPORT_SYMBOL(machine_halt);
703 725
704unsigned long ppc_proc_freq;
705unsigned long ppc_tb_freq;
706
707static int ppc64_panic_event(struct notifier_block *this, 726static int ppc64_panic_event(struct notifier_block *this,
708 unsigned long event, void *ptr) 727 unsigned long event, void *ptr)
709{ 728{
@@ -1055,6 +1074,7 @@ void __init setup_arch(char **cmdline_p)
1055 1074
1056 /* set up the bootmem stuff with available memory */ 1075 /* set up the bootmem stuff with available memory */
1057 do_init_bootmem(); 1076 do_init_bootmem();
1077 sparse_init();
1058 1078
1059 /* initialize the syscall map in systemcfg */ 1079 /* initialize the syscall map in systemcfg */
1060 setup_syscall_map(); 1080 setup_syscall_map();
@@ -1079,11 +1099,11 @@ void __init setup_arch(char **cmdline_p)
1079static void ppc64_do_msg(unsigned int src, const char *msg) 1099static void ppc64_do_msg(unsigned int src, const char *msg)
1080{ 1100{
1081 if (ppc_md.progress) { 1101 if (ppc_md.progress) {
1082 char buf[32]; 1102 char buf[128];
1083 1103
1084 sprintf(buf, "%08x \n", src); 1104 sprintf(buf, "%08X\n", src);
1085 ppc_md.progress(buf, 0); 1105 ppc_md.progress(buf, 0);
1086 sprintf(buf, "%-16s", msg); 1106 snprintf(buf, 128, "%s", msg);
1087 ppc_md.progress(buf, 0); 1107 ppc_md.progress(buf, 0);
1088 } 1108 }
1089} 1109}
@@ -1117,7 +1137,7 @@ void ppc64_dump_msg(unsigned int src, const char *msg)
1117} 1137}
1118 1138
1119/* This should only be called on processor 0 during calibrate decr */ 1139/* This should only be called on processor 0 during calibrate decr */
1120void setup_default_decr(void) 1140void __init setup_default_decr(void)
1121{ 1141{
1122 struct paca_struct *lpaca = get_paca(); 1142 struct paca_struct *lpaca = get_paca();
1123 1143
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index 9ef5d36d6b25..2fcddfcb594d 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -71,7 +71,7 @@ void smp_call_function_interrupt(void);
71 71
72int smt_enabled_at_boot = 1; 72int smt_enabled_at_boot = 1;
73 73
74#ifdef CONFIG_PPC_MULTIPLATFORM 74#ifdef CONFIG_MPIC
75void smp_mpic_message_pass(int target, int msg) 75void smp_mpic_message_pass(int target, int msg)
76{ 76{
77 /* make sure we're sending something that translates to an IPI */ 77 /* make sure we're sending something that translates to an IPI */
@@ -128,7 +128,7 @@ void __devinit smp_generic_kick_cpu(int nr)
128 smp_mb(); 128 smp_mb();
129} 129}
130 130
131#endif /* CONFIG_PPC_MULTIPLATFORM */ 131#endif /* CONFIG_MPIC */
132 132
133static void __init smp_space_timers(unsigned int max_cpus) 133static void __init smp_space_timers(unsigned int max_cpus)
134{ 134{
diff --git a/arch/ppc64/kernel/spider-pic.c b/arch/ppc64/kernel/spider-pic.c
new file mode 100644
index 000000000000..d5c9a02fb119
--- /dev/null
+++ b/arch/ppc64/kernel/spider-pic.c
@@ -0,0 +1,191 @@
1/*
2 * External Interrupt Controller on Spider South Bridge
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25
26#include <asm/pgtable.h>
27#include <asm/prom.h>
28#include <asm/io.h>
29
30#include "bpa_iic.h"
31
32/* register layout taken from Spider spec, table 7.4-4 */
33enum {
34 TIR_DEN = 0x004, /* Detection Enable Register */
35 TIR_MSK = 0x084, /* Mask Level Register */
36 TIR_EDC = 0x0c0, /* Edge Detection Clear Register */
37 TIR_PNDA = 0x100, /* Pending Register A */
38 TIR_PNDB = 0x104, /* Pending Register B */
39 TIR_CS = 0x144, /* Current Status Register */
40 TIR_LCSA = 0x150, /* Level Current Status Register A */
41 TIR_LCSB = 0x154, /* Level Current Status Register B */
42 TIR_LCSC = 0x158, /* Level Current Status Register C */
43 TIR_LCSD = 0x15c, /* Level Current Status Register D */
44 TIR_CFGA = 0x200, /* Setting Register A0 */
45 TIR_CFGB = 0x204, /* Setting Register B0 */
46 /* 0x208 ... 0x3ff Setting Register An/Bn */
47 TIR_PPNDA = 0x400, /* Packet Pending Register A */
48 TIR_PPNDB = 0x404, /* Packet Pending Register B */
49 TIR_PIERA = 0x408, /* Packet Output Error Register A */
50 TIR_PIERB = 0x40c, /* Packet Output Error Register B */
51 TIR_PIEN = 0x444, /* Packet Output Enable Register */
52 TIR_PIPND = 0x454, /* Packet Output Pending Register */
53 TIRDID = 0x484, /* Spider Device ID Register */
54 REISTIM = 0x500, /* Reissue Command Timeout Time Setting */
55 REISTIMEN = 0x504, /* Reissue Command Timeout Setting */
56 REISWAITEN = 0x508, /* Reissue Wait Control*/
57};
58
59static void __iomem *spider_pics[4];
60
61static void __iomem *spider_get_pic(int irq)
62{
63 int node = irq / IIC_NODE_STRIDE;
64 irq %= IIC_NODE_STRIDE;
65
66 if (irq >= IIC_EXT_OFFSET &&
67 irq < IIC_EXT_OFFSET + IIC_NUM_EXT &&
68 spider_pics)
69 return spider_pics[node];
70 return NULL;
71}
72
73static int spider_get_nr(unsigned int irq)
74{
75 return (irq % IIC_NODE_STRIDE) - IIC_EXT_OFFSET;
76}
77
78static void __iomem *spider_get_irq_config(int irq)
79{
80 void __iomem *pic;
81 pic = spider_get_pic(irq);
82 return pic + TIR_CFGA + 8 * spider_get_nr(irq);
83}
84
85static void spider_enable_irq(unsigned int irq)
86{
87 void __iomem *cfg = spider_get_irq_config(irq);
88 irq = spider_get_nr(irq);
89
90 out_be32(cfg, in_be32(cfg) | 0x3107000eu);
91 out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
92}
93
94static void spider_disable_irq(unsigned int irq)
95{
96 void __iomem *cfg = spider_get_irq_config(irq);
97 irq = spider_get_nr(irq);
98
99 out_be32(cfg, in_be32(cfg) & ~0x30000000u);
100}
101
102static unsigned int spider_startup_irq(unsigned int irq)
103{
104 spider_enable_irq(irq);
105 return 0;
106}
107
108static void spider_shutdown_irq(unsigned int irq)
109{
110 spider_disable_irq(irq);
111}
112
113static void spider_end_irq(unsigned int irq)
114{
115 spider_enable_irq(irq);
116}
117
118static void spider_ack_irq(unsigned int irq)
119{
120 spider_disable_irq(irq);
121 iic_local_enable();
122}
123
124static struct hw_interrupt_type spider_pic = {
125 .typename = " SPIDER ",
126 .startup = spider_startup_irq,
127 .shutdown = spider_shutdown_irq,
128 .enable = spider_enable_irq,
129 .disable = spider_disable_irq,
130 .ack = spider_ack_irq,
131 .end = spider_end_irq,
132};
133
134
135int spider_get_irq(unsigned long int_pending)
136{
137 void __iomem *regs = spider_get_pic(int_pending);
138 unsigned long cs;
139 int irq;
140
141 cs = in_be32(regs + TIR_CS);
142
143 irq = cs >> 24;
144 if (irq != 63)
145 return irq;
146
147 return -1;
148}
149
150void spider_init_IRQ(void)
151{
152 int node;
153 struct device_node *dn;
154 unsigned int *property;
155 long spiderpic;
156 int n;
157
158/* FIXME: detect multiple PICs as soon as the device tree has them */
159 for (node = 0; node < 1; node++) {
160 dn = of_find_node_by_path("/");
161 n = prom_n_addr_cells(dn);
162 property = (unsigned int *) get_property(dn,
163 "platform-spider-pic", NULL);
164
165 if (!property)
166 continue;
167 for (spiderpic = 0; n > 0; --n)
168 spiderpic = (spiderpic << 32) + *property++;
169 printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic);
170 spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE);
171 for (n = 0; n < IIC_NUM_EXT; n++) {
172 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
173 get_irq_desc(irq)->handler = &spider_pic;
174
175 /* do not mask any interrupts because of level */
176 out_be32(spider_pics[node] + TIR_MSK, 0x0);
177
178 /* disable edge detection clear */
179 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */
180
181 /* enable interrupt packets to be output */
182 out_be32(spider_pics[node] + TIR_PIEN,
183 in_be32(spider_pics[node] + TIR_PIEN) | 0x1);
184
185 /* Enable the interrupt detection enable bit. Do this last! */
186 out_be32(spider_pics[node] + TIR_DEN,
187 in_be32(spider_pics[node] +TIR_DEN) | 0x1);
188
189 }
190 }
191}
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 33364a7d2cd2..2348a75e050d 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -107,6 +107,9 @@ void ppc_adjtimex(void);
107 107
108static unsigned adjusting_time = 0; 108static unsigned adjusting_time = 0;
109 109
110unsigned long ppc_proc_freq;
111unsigned long ppc_tb_freq;
112
110static __inline__ void timer_check_rtc(void) 113static __inline__ void timer_check_rtc(void)
111{ 114{
112 /* 115 /*
@@ -472,6 +475,66 @@ int do_settimeofday(struct timespec *tv)
472 475
473EXPORT_SYMBOL(do_settimeofday); 476EXPORT_SYMBOL(do_settimeofday);
474 477
478#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
479void __init generic_calibrate_decr(void)
480{
481 struct device_node *cpu;
482 struct div_result divres;
483 unsigned int *fp;
484 int node_found;
485
486 /*
487 * The cpu node should have a timebase-frequency property
488 * to tell us the rate at which the decrementer counts.
489 */
490 cpu = of_find_node_by_type(NULL, "cpu");
491
492 ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */
493 node_found = 0;
494 if (cpu != 0) {
495 fp = (unsigned int *)get_property(cpu, "timebase-frequency",
496 NULL);
497 if (fp != 0) {
498 node_found = 1;
499 ppc_tb_freq = *fp;
500 }
501 }
502 if (!node_found)
503 printk(KERN_ERR "WARNING: Estimating decrementer frequency "
504 "(not found)\n");
505
506 ppc_proc_freq = DEFAULT_PROC_FREQ;
507 node_found = 0;
508 if (cpu != 0) {
509 fp = (unsigned int *)get_property(cpu, "clock-frequency",
510 NULL);
511 if (fp != 0) {
512 node_found = 1;
513 ppc_proc_freq = *fp;
514 }
515 }
516 if (!node_found)
517 printk(KERN_ERR "WARNING: Estimating processor frequency "
518 "(not found)\n");
519
520 of_node_put(cpu);
521
522 printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
523 ppc_tb_freq/1000000, ppc_tb_freq%1000000);
524 printk(KERN_INFO "time_init: processor frequency = %lu.%.6lu MHz\n",
525 ppc_proc_freq/1000000, ppc_proc_freq%1000000);
526
527 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
528 tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
529 tb_ticks_per_usec = ppc_tb_freq / 1000000;
530 tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
531 div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
532 tb_to_xs = divres.result_low;
533
534 setup_default_decr();
535}
536#endif
537
475void __init time_init(void) 538void __init time_init(void)
476{ 539{
477 /* This function is only called on the boot processor */ 540 /* This function is only called on the boot processor */
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
index 7e52cb2605e0..a8d5e83ee89f 100644
--- a/arch/ppc64/kernel/traps.c
+++ b/arch/ppc64/kernel/traps.c
@@ -126,6 +126,10 @@ int die(const char *str, struct pt_regs *regs, long err)
126 printk("POWERMAC "); 126 printk("POWERMAC ");
127 nl = 1; 127 nl = 1;
128 break; 128 break;
129 case PLATFORM_BPA:
130 printk("BPA ");
131 nl = 1;
132 break;
129 } 133 }
130 if (nl) 134 if (nl)
131 printk("\n"); 135 printk("\n");
diff --git a/arch/ppc64/mm/Makefile b/arch/ppc64/mm/Makefile
index ac522d57b2a7..3695d00d347f 100644
--- a/arch/ppc64/mm/Makefile
+++ b/arch/ppc64/mm/Makefile
@@ -6,6 +6,6 @@ EXTRA_CFLAGS += -mno-minimal-toc
6 6
7obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \ 7obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \
8 slb_low.o slb.o stab.o mmap.o 8 slb_low.o slb.o stab.o mmap.o
9obj-$(CONFIG_DISCONTIGMEM) += numa.o 9obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
10obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 10obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
11obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o 11obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index 6fa1e6490b57..b50b3a446dbe 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -98,7 +98,7 @@ void show_mem(void)
98 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 98 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
99 for_each_pgdat(pgdat) { 99 for_each_pgdat(pgdat) {
100 for (i = 0; i < pgdat->node_spanned_pages; i++) { 100 for (i = 0; i < pgdat->node_spanned_pages; i++) {
101 page = pgdat->node_mem_map + i; 101 page = pgdat_page_nr(pgdat, i);
102 total++; 102 total++;
103 if (PageReserved(page)) 103 if (PageReserved(page))
104 reserved++; 104 reserved++;
@@ -531,7 +531,7 @@ EXPORT_SYMBOL(page_is_ram);
531 * Initialize the bootmem system and give it all the memory we 531 * Initialize the bootmem system and give it all the memory we
532 * have available. 532 * have available.
533 */ 533 */
534#ifndef CONFIG_DISCONTIGMEM 534#ifndef CONFIG_NEED_MULTIPLE_NODES
535void __init do_init_bootmem(void) 535void __init do_init_bootmem(void)
536{ 536{
537 unsigned long i; 537 unsigned long i;
@@ -553,12 +553,20 @@ void __init do_init_bootmem(void)
553 553
554 max_pfn = max_low_pfn; 554 max_pfn = max_low_pfn;
555 555
556 /* add all physical memory to the bootmem map. Also find the first */ 556 /* Add all physical memory to the bootmem map, mark each area
557 * present.
558 */
557 for (i=0; i < lmb.memory.cnt; i++) { 559 for (i=0; i < lmb.memory.cnt; i++) {
558 unsigned long physbase, size; 560 unsigned long physbase, size;
561 unsigned long start_pfn, end_pfn;
559 562
560 physbase = lmb.memory.region[i].physbase; 563 physbase = lmb.memory.region[i].physbase;
561 size = lmb.memory.region[i].size; 564 size = lmb.memory.region[i].size;
565
566 start_pfn = physbase >> PAGE_SHIFT;
567 end_pfn = start_pfn + (size >> PAGE_SHIFT);
568 memory_present(0, start_pfn, end_pfn);
569
562 free_bootmem(physbase, size); 570 free_bootmem(physbase, size);
563 } 571 }
564 572
@@ -597,7 +605,7 @@ void __init paging_init(void)
597 free_area_init_node(0, NODE_DATA(0), zones_size, 605 free_area_init_node(0, NODE_DATA(0), zones_size,
598 __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); 606 __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
599} 607}
600#endif /* CONFIG_DISCONTIGMEM */ 608#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
601 609
602static struct kcore_list kcore_vmem; 610static struct kcore_list kcore_vmem;
603 611
@@ -628,7 +636,7 @@ module_init(setup_kcore);
628 636
629void __init mem_init(void) 637void __init mem_init(void)
630{ 638{
631#ifdef CONFIG_DISCONTIGMEM 639#ifdef CONFIG_NEED_MULTIPLE_NODES
632 int nid; 640 int nid;
633#endif 641#endif
634 pg_data_t *pgdat; 642 pg_data_t *pgdat;
@@ -639,7 +647,7 @@ void __init mem_init(void)
639 num_physpages = max_low_pfn; /* RAM is assumed contiguous */ 647 num_physpages = max_low_pfn; /* RAM is assumed contiguous */
640 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); 648 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
641 649
642#ifdef CONFIG_DISCONTIGMEM 650#ifdef CONFIG_NEED_MULTIPLE_NODES
643 for_each_online_node(nid) { 651 for_each_online_node(nid) {
644 if (NODE_DATA(nid)->node_spanned_pages != 0) { 652 if (NODE_DATA(nid)->node_spanned_pages != 0) {
645 printk("freeing bootmem node %x\n", nid); 653 printk("freeing bootmem node %x\n", nid);
@@ -654,7 +662,7 @@ void __init mem_init(void)
654 662
655 for_each_pgdat(pgdat) { 663 for_each_pgdat(pgdat) {
656 for (i = 0; i < pgdat->node_spanned_pages; i++) { 664 for (i = 0; i < pgdat->node_spanned_pages; i++) {
657 page = pgdat->node_mem_map + i; 665 page = pgdat_page_nr(pgdat, i);
658 if (PageReserved(page)) 666 if (PageReserved(page))
659 reservedpages++; 667 reservedpages++;
660 } 668 }
diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
index ea862ec643d3..cafd91aef289 100644
--- a/arch/ppc64/mm/numa.c
+++ b/arch/ppc64/mm/numa.c
@@ -440,6 +440,8 @@ new_range:
440 for (i = start ; i < (start+size); i += MEMORY_INCREMENT) 440 for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
441 numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 441 numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
442 numa_domain; 442 numa_domain;
443 memory_present(numa_domain, start >> PAGE_SHIFT,
444 (start + size) >> PAGE_SHIFT);
443 445
444 if (--ranges) 446 if (--ranges)
445 goto new_range; 447 goto new_range;
@@ -481,6 +483,7 @@ static void __init setup_nonnuma(void)
481 483
482 for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT) 484 for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT)
483 numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0; 485 numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
486 memory_present(0, 0, init_node_data[0].node_end_pfn);
484} 487}
485 488
486static void __init dump_numa_topology(void) 489static void __init dump_numa_topology(void)
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index ab79af84699a..32696c1d9280 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -226,6 +226,8 @@ config WARN_STACK_SIZE
226 This allows you to specify the maximum frame size a function may 226 This allows you to specify the maximum frame size a function may
227 have without the compiler complaining about it. 227 have without the compiler complaining about it.
228 228
229source "mm/Kconfig"
230
229comment "I/O subsystem configuration" 231comment "I/O subsystem configuration"
230 232
231config MACHCHK_WARNING 233config MACHCHK_WARNING
diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh
index 278a8139cb18..d4026f62cb06 100644
--- a/arch/s390/boot/install.sh
+++ b/arch/s390/boot/install.sh
@@ -21,8 +21,8 @@
21 21
22# User may have a custom install script 22# User may have a custom install script
23 23
24if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi 24if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
25if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi 25if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
26 26
27# Default install - same as make zlilo 27# Default install - same as make zlilo
28 28
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index bf33dcfec7db..3898f66d0b2f 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -45,7 +45,7 @@ typedef struct compat_siginfo {
45 45
46 /* POSIX.1b timers */ 46 /* POSIX.1b timers */
47 struct { 47 struct {
48 timer_t _tid; /* timer id */ 48 compat_timer_t _tid; /* timer id */
49 int _overrun; /* overrun count */ 49 int _overrun; /* overrun count */
50 compat_sigval_t _sigval; /* same as below */ 50 compat_sigval_t _sigval; /* same as below */
51 int _sys_private; /* not to be passed to user */ 51 int _sys_private; /* not to be passed to user */
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 3468d5127223..a7c8bfc11604 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -486,7 +486,7 @@ config CPU_SUBTYPE_ST40
486 depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1 486 depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
487 default y 487 default y
488 488
489config DISCONTIGMEM 489config ARCH_DISCONTIGMEM_ENABLE
490 bool 490 bool
491 depends on SH_HP690 491 depends on SH_HP690
492 default y 492 default y
@@ -496,6 +496,8 @@ config DISCONTIGMEM
496 or have huge holes in the physical address space for other reasons. 496 or have huge holes in the physical address space for other reasons.
497 See <file:Documentation/vm/numa> for more. 497 See <file:Documentation/vm/numa> for more.
498 498
499source "mm/Kconfig"
500
499config ZERO_PAGE_OFFSET 501config ZERO_PAGE_OFFSET
500 hex "Zero page offset" 502 hex "Zero page offset"
501 default "0x00001000" if !(SH_MPC1211 || SH_SH03) 503 default "0x00001000" if !(SH_MPC1211 || SH_SH03)
diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig
index 76eb81fba45e..708e59736a4d 100644
--- a/arch/sh64/Kconfig
+++ b/arch/sh64/Kconfig
@@ -217,6 +217,8 @@ config PREEMPT
217 bool "Preemptible Kernel (EXPERIMENTAL)" 217 bool "Preemptible Kernel (EXPERIMENTAL)"
218 depends on EXPERIMENTAL 218 depends on EXPERIMENTAL
219 219
220source "mm/Kconfig"
221
220endmenu 222endmenu
221 223
222menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" 224menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 237f922520fd..262e13d086fe 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -264,7 +264,11 @@ config SUNOS_EMUL
264 want to run SunOS binaries on an Ultra you must also say Y to 264 want to run SunOS binaries on an Ultra you must also say Y to
265 "Kernel support for 32-bit a.out binaries" above. 265 "Kernel support for 32-bit a.out binaries" above.
266 266
267source "drivers/parport/Kconfig" 267source "mm/Kconfig"
268
269endmenu
270
271source "drivers/Kconfig"
268 272
269config PRINTER 273config PRINTER
270 tristate "Parallel printer support" 274 tristate "Parallel printer support"
@@ -291,6 +295,8 @@ config PRINTER
291 If you have more than 8 printers, you need to increase the LP_NO 295 If you have more than 8 printers, you need to increase the LP_NO
292 macro in lp.c and the PARPORT_MAX macro in parport.h. 296 macro in lp.c and the PARPORT_MAX macro in parport.h.
293 297
298source "mm/Kconfig"
299
294endmenu 300endmenu
295 301
296source "drivers/base/Kconfig" 302source "drivers/base/Kconfig"
@@ -372,18 +378,8 @@ config UNIX98_PTY_COUNT
372 378
373endmenu 379endmenu
374 380
375source "drivers/input/Kconfig"
376
377source "fs/Kconfig" 381source "fs/Kconfig"
378 382
379source "sound/Kconfig"
380
381source "drivers/usb/Kconfig"
382
383source "drivers/infiniband/Kconfig"
384
385source "drivers/char/watchdog/Kconfig"
386
387source "arch/sparc/Kconfig.debug" 383source "arch/sparc/Kconfig.debug"
388 384
389source "security/Kconfig" 385source "security/Kconfig"
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index a72fd15d5ea8..e2b050eb3b96 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -484,6 +484,8 @@ config CMDLINE
484 484
485 NOTE: This option WILL override the PROM bootargs setting! 485 NOTE: This option WILL override the PROM bootargs setting!
486 486
487source "mm/Kconfig"
488
487endmenu 489endmenu
488 490
489source "drivers/base/Kconfig" 491source "drivers/base/Kconfig"
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 7066d7ba667a..bdac631cf011 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -6,7 +6,6 @@
6#include <linux/config.h> 6#include <linux/config.h>
7#include <linux/kernel.h> 7#include <linux/kernel.h>
8#include <linux/kprobes.h> 8#include <linux/kprobes.h>
9
10#include <asm/kdebug.h> 9#include <asm/kdebug.h>
11#include <asm/signal.h> 10#include <asm/signal.h>
12 11
@@ -47,25 +46,59 @@ void arch_copy_kprobe(struct kprobe *p)
47{ 46{
48 p->ainsn.insn[0] = *p->addr; 47 p->ainsn.insn[0] = *p->addr;
49 p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; 48 p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
49 p->opcode = *p->addr;
50} 50}
51 51
52void arch_remove_kprobe(struct kprobe *p) 52void arch_arm_kprobe(struct kprobe *p)
53{ 53{
54 *p->addr = BREAKPOINT_INSTRUCTION;
55 flushi(p->addr);
54} 56}
55 57
56/* kprobe_status settings */ 58void arch_disarm_kprobe(struct kprobe *p)
57#define KPROBE_HIT_ACTIVE 0x00000001 59{
58#define KPROBE_HIT_SS 0x00000002 60 *p->addr = p->opcode;
61 flushi(p->addr);
62}
63
64void arch_remove_kprobe(struct kprobe *p)
65{
66}
59 67
60static struct kprobe *current_kprobe; 68static struct kprobe *current_kprobe;
61static unsigned long current_kprobe_orig_tnpc; 69static unsigned long current_kprobe_orig_tnpc;
62static unsigned long current_kprobe_orig_tstate_pil; 70static unsigned long current_kprobe_orig_tstate_pil;
63static unsigned int kprobe_status; 71static unsigned int kprobe_status;
72static struct kprobe *kprobe_prev;
73static unsigned long kprobe_orig_tnpc_prev;
74static unsigned long kprobe_orig_tstate_pil_prev;
75static unsigned int kprobe_status_prev;
64 76
65static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 77static inline void save_previous_kprobe(void)
78{
79 kprobe_status_prev = kprobe_status;
80 kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc;
81 kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil;
82 kprobe_prev = current_kprobe;
83}
84
85static inline void restore_previous_kprobe(void)
86{
87 kprobe_status = kprobe_status_prev;
88 current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev;
89 current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev;
90 current_kprobe = kprobe_prev;
91}
92
93static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
66{ 94{
67 current_kprobe_orig_tnpc = regs->tnpc; 95 current_kprobe_orig_tnpc = regs->tnpc;
68 current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); 96 current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
97 current_kprobe = p;
98}
99
100static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
101{
69 regs->tstate |= TSTATE_PIL; 102 regs->tstate |= TSTATE_PIL;
70 103
71 /*single step inline, if it a breakpoint instruction*/ 104 /*single step inline, if it a breakpoint instruction*/
@@ -78,17 +111,6 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
78 } 111 }
79} 112}
80 113
81static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
82{
83 *p->addr = p->opcode;
84 flushi(p->addr);
85
86 regs->tpc = (unsigned long) p->addr;
87 regs->tnpc = current_kprobe_orig_tnpc;
88 regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
89 current_kprobe_orig_tstate_pil);
90}
91
92static int kprobe_handler(struct pt_regs *regs) 114static int kprobe_handler(struct pt_regs *regs)
93{ 115{
94 struct kprobe *p; 116 struct kprobe *p;
@@ -109,8 +131,18 @@ static int kprobe_handler(struct pt_regs *regs)
109 unlock_kprobes(); 131 unlock_kprobes();
110 goto no_kprobe; 132 goto no_kprobe;
111 } 133 }
112 disarm_kprobe(p, regs); 134 /* We have reentered the kprobe_handler(), since
113 ret = 1; 135 * another probe was hit while within the handler.
136 * We here save the original kprobes variables and
137 * just single step on the instruction of the new probe
138 * without calling any user handlers.
139 */
140 save_previous_kprobe();
141 set_current_kprobe(p, regs);
142 p->nmissed++;
143 kprobe_status = KPROBE_REENTER;
144 prepare_singlestep(p, regs);
145 return 1;
114 } else { 146 } else {
115 p = current_kprobe; 147 p = current_kprobe;
116 if (p->break_handler && p->break_handler(p, regs)) 148 if (p->break_handler && p->break_handler(p, regs))
@@ -138,8 +170,8 @@ static int kprobe_handler(struct pt_regs *regs)
138 goto no_kprobe; 170 goto no_kprobe;
139 } 171 }
140 172
173 set_current_kprobe(p, regs);
141 kprobe_status = KPROBE_HIT_ACTIVE; 174 kprobe_status = KPROBE_HIT_ACTIVE;
142 current_kprobe = p;
143 if (p->pre_handler && p->pre_handler(p, regs)) 175 if (p->pre_handler && p->pre_handler(p, regs))
144 return 1; 176 return 1;
145 177
@@ -245,12 +277,20 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
245 if (!kprobe_running()) 277 if (!kprobe_running())
246 return 0; 278 return 0;
247 279
248 if (current_kprobe->post_handler) 280 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
281 kprobe_status = KPROBE_HIT_SSDONE;
249 current_kprobe->post_handler(current_kprobe, regs, 0); 282 current_kprobe->post_handler(current_kprobe, regs, 0);
283 }
250 284
251 resume_execution(current_kprobe, regs); 285 resume_execution(current_kprobe, regs);
252 286
287 /*Restore back the original saved kprobes variables and continue. */
288 if (kprobe_status == KPROBE_REENTER) {
289 restore_previous_kprobe();
290 goto out;
291 }
253 unlock_kprobes(); 292 unlock_kprobes();
293out:
254 preempt_enable_no_resched(); 294 preempt_enable_no_resched();
255 295
256 return 1; 296 return 1;
@@ -392,3 +432,4 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
392 } 432 }
393 return 0; 433 return 0;
394} 434}
435
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 9a375e975cff..f28428f4170e 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -102,7 +102,7 @@ typedef struct compat_siginfo{
102 102
103 /* POSIX.1b timers */ 103 /* POSIX.1b timers */
104 struct { 104 struct {
105 timer_t _tid; /* timer id */ 105 compat_timer_t _tid; /* timer id */
106 int _overrun; /* overrun count */ 106 int _overrun; /* overrun count */
107 compat_sigval_t _sigval; /* same as below */ 107 compat_sigval_t _sigval; /* same as below */
108 int _sys_private; /* not to be passed to user */ 108 int _sys_private; /* not to be passed to user */
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index b8e952c88fd1..9469e77303e6 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -74,6 +74,7 @@ config MODE_SKAS
74 option will shrink the UML binary slightly. 74 option will shrink the UML binary slightly.
75 75
76source "arch/um/Kconfig_arch" 76source "arch/um/Kconfig_arch"
77source "mm/Kconfig"
77 78
78config LD_SCRIPT_STATIC 79config LD_SCRIPT_STATIC
79 bool 80 bool
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 804c6bbdf67c..157584ae4792 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -8,6 +8,7 @@
8#include "linux/kernel.h" 8#include "linux/kernel.h"
9#include "linux/sched.h" 9#include "linux/sched.h"
10#include "linux/interrupt.h" 10#include "linux/interrupt.h"
11#include "linux/string.h"
11#include "linux/mm.h" 12#include "linux/mm.h"
12#include "linux/slab.h" 13#include "linux/slab.h"
13#include "linux/utsname.h" 14#include "linux/utsname.h"
@@ -322,12 +323,7 @@ void do_uml_exitcalls(void)
322 323
323char *uml_strdup(char *string) 324char *uml_strdup(char *string)
324{ 325{
325 char *new; 326 return kstrdup(string, GFP_KERNEL);
326
327 new = kmalloc(strlen(string) + 1, GFP_KERNEL);
328 if(new == NULL) return(NULL);
329 strcpy(new, string);
330 return(new);
331} 327}
332 328
333int copy_to_user_proc(void __user *to, void *from, int size) 329int copy_to_user_proc(void __user *to, void *from, int size)
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 90cd4baa75ee..27febd6ffa80 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -218,6 +218,8 @@ menu "Processor type and features"
218 a lot of RAM, and you need to able to allocate very large 218 a lot of RAM, and you need to able to allocate very large
219 contiguous chunks. If unsure, say N. 219 contiguous chunks. If unsure, say N.
220 220
221source "mm/Kconfig"
222
221endmenu 223endmenu
222 224
223 225
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 289f448ac89c..db259757dc8a 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -265,7 +265,7 @@ config NUMA_EMU
265 into virtual nodes when booted with "numa=fake=N", where N is the 265 into virtual nodes when booted with "numa=fake=N", where N is the
266 number of nodes. This is only useful for debugging. 266 number of nodes. This is only useful for debugging.
267 267
268config DISCONTIGMEM 268config ARCH_DISCONTIGMEM_ENABLE
269 bool 269 bool
270 depends on NUMA 270 depends on NUMA
271 default y 271 default y
@@ -274,6 +274,27 @@ config NUMA
274 bool 274 bool
275 default n 275 default n
276 276
277config ARCH_DISCONTIGMEM_ENABLE
278 def_bool y
279 depends on NUMA
280
281config ARCH_DISCONTIGMEM_DEFAULT
282 def_bool y
283 depends on NUMA
284
285config ARCH_SPARSEMEM_ENABLE
286 def_bool y
287 depends on NUMA
288
289config ARCH_FLATMEM_ENABLE
290 def_bool y
291 depends on !NUMA
292
293source "mm/Kconfig"
294
295config HAVE_ARCH_EARLY_PFN_TO_NID
296 def_bool y
297
277config HAVE_DEC_LOCK 298config HAVE_DEC_LOCK
278 bool 299 bool
279 depends on SMP 300 depends on SMP
@@ -381,6 +402,8 @@ config SECCOMP
381 402
382 If unsure, say Y. Only embedded should say N here. 403 If unsure, say Y. Only embedded should say N here.
383 404
405source kernel/Kconfig.hz
406
384endmenu 407endmenu
385 408
386# 409#
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh
index 90f2452b3b9e..f17b40dfc0f4 100644
--- a/arch/x86_64/boot/install.sh
+++ b/arch/x86_64/boot/install.sh
@@ -21,8 +21,8 @@
21 21
22# User may have a custom install script 22# User may have a custom install script
23 23
24if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi 24if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
25if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi 25if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
26 26
27# Default install - same as make zlilo 27# Default install - same as make zlilo
28 28
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index fbd09b5126ce..66e2821533db 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -428,8 +428,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
428 return (void __user *)((rsp - frame_size) & -8UL); 428 return (void __user *)((rsp - frame_size) & -8UL);
429} 429}
430 430
431void ia32_setup_frame(int sig, struct k_sigaction *ka, 431int ia32_setup_frame(int sig, struct k_sigaction *ka,
432 compat_sigset_t *set, struct pt_regs * regs) 432 compat_sigset_t *set, struct pt_regs * regs)
433{ 433{
434 struct sigframe __user *frame; 434 struct sigframe __user *frame;
435 int err = 0; 435 int err = 0;
@@ -514,14 +514,15 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
514 current->comm, current->pid, frame, regs->rip, frame->pretcode); 514 current->comm, current->pid, frame, regs->rip, frame->pretcode);
515#endif 515#endif
516 516
517 return; 517 return 1;
518 518
519give_sigsegv: 519give_sigsegv:
520 force_sigsegv(sig, current); 520 force_sigsegv(sig, current);
521 return 0;
521} 522}
522 523
523void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 524int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
524 compat_sigset_t *set, struct pt_regs * regs) 525 compat_sigset_t *set, struct pt_regs * regs)
525{ 526{
526 struct rt_sigframe __user *frame; 527 struct rt_sigframe __user *frame;
527 int err = 0; 528 int err = 0;
@@ -613,9 +614,9 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
613 current->comm, current->pid, frame, regs->rip, frame->pretcode); 614 current->comm, current->pid, frame, regs->rip, frame->pretcode);
614#endif 615#endif
615 616
616 return; 617 return 1;
617 618
618give_sigsegv: 619give_sigsegv:
619 force_sigsegv(sig, current); 620 force_sigsegv(sig, current);
621 return 0;
620} 622}
621
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index 504e63474993..c9a6b812e926 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -40,11 +40,7 @@ int fix_aperture __initdata = 1;
40 40
41static u32 __init allocate_aperture(void) 41static u32 __init allocate_aperture(void)
42{ 42{
43#ifdef CONFIG_DISCONTIGMEM
44 pg_data_t *nd0 = NODE_DATA(0); 43 pg_data_t *nd0 = NODE_DATA(0);
45#else
46 pg_data_t *nd0 = &contig_page_data;
47#endif
48 u32 aper_size; 44 u32 aper_size;
49 void *p; 45 void *p;
50 46
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index e3a19e8ebbf8..9631c747c5e3 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -2,20 +2,24 @@
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/tty.h>
5#include <asm/io.h> 6#include <asm/io.h>
6#include <asm/processor.h> 7#include <asm/processor.h>
7 8
8/* Simple VGA output */ 9/* Simple VGA output */
9 10
10#ifdef __i386__ 11#ifdef __i386__
12#include <asm/setup.h>
11#define VGABASE (__ISA_IO_base + 0xb8000) 13#define VGABASE (__ISA_IO_base + 0xb8000)
12#else 14#else
15#include <asm/bootsetup.h>
13#define VGABASE ((void __iomem *)0xffffffff800b8000UL) 16#define VGABASE ((void __iomem *)0xffffffff800b8000UL)
14#endif 17#endif
15 18
16#define MAX_YPOS 25 19#define MAX_YPOS max_ypos
17#define MAX_XPOS 80 20#define MAX_XPOS max_xpos
18 21
22static int max_ypos = 25, max_xpos = 80;
19static int current_ypos = 1, current_xpos = 0; 23static int current_ypos = 1, current_xpos = 0;
20 24
21static void early_vga_write(struct console *con, const char *str, unsigned n) 25static void early_vga_write(struct console *con, const char *str, unsigned n)
@@ -196,7 +200,10 @@ int __init setup_early_printk(char *opt)
196 } else if (!strncmp(buf, "ttyS", 4)) { 200 } else if (!strncmp(buf, "ttyS", 4)) {
197 early_serial_init(buf); 201 early_serial_init(buf);
198 early_console = &early_serial_console; 202 early_console = &early_serial_console;
199 } else if (!strncmp(buf, "vga", 3)) { 203 } else if (!strncmp(buf, "vga", 3)
204 && SCREEN_INFO.orig_video_isVGA == 1) {
205 max_xpos = SCREEN_INFO.orig_video_cols;
206 max_ypos = SCREEN_INFO.orig_video_lines;
200 early_console = &early_vga_console; 207 early_console = &early_vga_console;
201 } 208 }
202 early_console_initialized = 1; 209 early_console_initialized = 1;
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 0f8c78dcd38c..cf6ab147a2a5 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -94,7 +94,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
94 s = strstr(saved_command_line, "earlyprintk="); 94 s = strstr(saved_command_line, "earlyprintk=");
95 if (s != NULL) 95 if (s != NULL)
96 setup_early_printk(s); 96 setup_early_printk(s);
97#ifdef CONFIG_DISCONTIGMEM 97#ifdef CONFIG_NUMA
98 s = strstr(saved_command_line, "numa="); 98 s = strstr(saved_command_line, "numa=");
99 if (s != NULL) 99 if (s != NULL)
100 numa_setup(s+5); 100 numa_setup(s+5);
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index 7873d9ba8814..19eafa0aa95c 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -157,14 +157,13 @@ static unsigned int startup_8259A_irq(unsigned int irq)
157} 157}
158 158
159static struct hw_interrupt_type i8259A_irq_type = { 159static struct hw_interrupt_type i8259A_irq_type = {
160 "XT-PIC", 160 .typename = "XT-PIC",
161 startup_8259A_irq, 161 .startup = startup_8259A_irq,
162 shutdown_8259A_irq, 162 .shutdown = shutdown_8259A_irq,
163 enable_8259A_irq, 163 .enable = enable_8259A_irq,
164 disable_8259A_irq, 164 .disable = disable_8259A_irq,
165 mask_and_ack_8259A, 165 .ack = mask_and_ack_8259A,
166 end_8259A_irq, 166 .end = end_8259A_irq,
167 NULL
168}; 167};
169 168
170/* 169/*
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index f77f8a0ff187..4e680f87a75f 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -27,6 +27,8 @@
27 * <prasanna@in.ibm.com> adapted for x86_64 27 * <prasanna@in.ibm.com> adapted for x86_64
28 * 2005-Mar Roland McGrath <roland@redhat.com> 28 * 2005-Mar Roland McGrath <roland@redhat.com>
29 * Fixed to handle %rip-relative addressing mode correctly. 29 * Fixed to handle %rip-relative addressing mode correctly.
30 * 2005-May Rusty Lynch <rusty.lynch@intel.com>
31 * Added function return probes functionality
30 */ 32 */
31 33
32#include <linux/config.h> 34#include <linux/config.h>
@@ -37,18 +39,16 @@
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/preempt.h> 40#include <linux/preempt.h>
39#include <linux/moduleloader.h> 41#include <linux/moduleloader.h>
40 42#include <asm/cacheflush.h>
41#include <asm/pgtable.h> 43#include <asm/pgtable.h>
42#include <asm/kdebug.h> 44#include <asm/kdebug.h>
43 45
44static DECLARE_MUTEX(kprobe_mutex); 46static DECLARE_MUTEX(kprobe_mutex);
45 47
46/* kprobe_status settings */
47#define KPROBE_HIT_ACTIVE 0x00000001
48#define KPROBE_HIT_SS 0x00000002
49
50static struct kprobe *current_kprobe; 48static struct kprobe *current_kprobe;
51static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags; 49static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
50static struct kprobe *kprobe_prev;
51static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
52static struct pt_regs jprobe_saved_regs; 52static struct pt_regs jprobe_saved_regs;
53static long *jprobe_saved_rsp; 53static long *jprobe_saved_rsp;
54static kprobe_opcode_t *get_insn_slot(void); 54static kprobe_opcode_t *get_insn_slot(void);
@@ -214,6 +214,21 @@ void arch_copy_kprobe(struct kprobe *p)
214 BUG_ON((s64) (s32) disp != disp); /* Sanity check. */ 214 BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
215 *ripdisp = disp; 215 *ripdisp = disp;
216 } 216 }
217 p->opcode = *p->addr;
218}
219
220void arch_arm_kprobe(struct kprobe *p)
221{
222 *p->addr = BREAKPOINT_INSTRUCTION;
223 flush_icache_range((unsigned long) p->addr,
224 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
225}
226
227void arch_disarm_kprobe(struct kprobe *p)
228{
229 *p->addr = p->opcode;
230 flush_icache_range((unsigned long) p->addr,
231 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
217} 232}
218 233
219void arch_remove_kprobe(struct kprobe *p) 234void arch_remove_kprobe(struct kprobe *p)
@@ -223,10 +238,29 @@ void arch_remove_kprobe(struct kprobe *p)
223 down(&kprobe_mutex); 238 down(&kprobe_mutex);
224} 239}
225 240
226static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) 241static inline void save_previous_kprobe(void)
227{ 242{
228 *p->addr = p->opcode; 243 kprobe_prev = current_kprobe;
229 regs->rip = (unsigned long)p->addr; 244 kprobe_status_prev = kprobe_status;
245 kprobe_old_rflags_prev = kprobe_old_rflags;
246 kprobe_saved_rflags_prev = kprobe_saved_rflags;
247}
248
249static inline void restore_previous_kprobe(void)
250{
251 current_kprobe = kprobe_prev;
252 kprobe_status = kprobe_status_prev;
253 kprobe_old_rflags = kprobe_old_rflags_prev;
254 kprobe_saved_rflags = kprobe_saved_rflags_prev;
255}
256
257static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
258{
259 current_kprobe = p;
260 kprobe_saved_rflags = kprobe_old_rflags
261 = (regs->eflags & (TF_MASK | IF_MASK));
262 if (is_IF_modifier(p->ainsn.insn))
263 kprobe_saved_rflags &= ~IF_MASK;
230} 264}
231 265
232static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 266static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -240,6 +274,50 @@ static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
240 regs->rip = (unsigned long)p->ainsn.insn; 274 regs->rip = (unsigned long)p->ainsn.insn;
241} 275}
242 276
277struct task_struct *arch_get_kprobe_task(void *ptr)
278{
279 return ((struct thread_info *) (((unsigned long) ptr) &
280 (~(THREAD_SIZE -1))))->task;
281}
282
283void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
284{
285 unsigned long *sara = (unsigned long *)regs->rsp;
286 struct kretprobe_instance *ri;
287 static void *orig_ret_addr;
288
289 /*
290 * Save the return address when the return probe hits
291 * the first time, and use it to populate the (krprobe
292 * instance)->ret_addr for subsequent return probes at
293 * the same addrress since stack address would have
294 * the kretprobe_trampoline by then.
295 */
296 if (((void*) *sara) != kretprobe_trampoline)
297 orig_ret_addr = (void*) *sara;
298
299 if ((ri = get_free_rp_inst(rp)) != NULL) {
300 ri->rp = rp;
301 ri->stack_addr = sara;
302 ri->ret_addr = orig_ret_addr;
303 add_rp_inst(ri);
304 /* Replace the return addr with trampoline addr */
305 *sara = (unsigned long) &kretprobe_trampoline;
306 } else {
307 rp->nmissed++;
308 }
309}
310
311void arch_kprobe_flush_task(struct task_struct *tk)
312{
313 struct kretprobe_instance *ri;
314 while ((ri = get_rp_inst_tsk(tk)) != NULL) {
315 *((unsigned long *)(ri->stack_addr)) =
316 (unsigned long) ri->ret_addr;
317 recycle_rp_inst(ri);
318 }
319}
320
243/* 321/*
244 * Interrupts are disabled on entry as trap3 is an interrupt gate and they 322 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
245 * remain disabled thorough out this function. 323 * remain disabled thorough out this function.
@@ -264,9 +342,30 @@ int kprobe_handler(struct pt_regs *regs)
264 regs->eflags |= kprobe_saved_rflags; 342 regs->eflags |= kprobe_saved_rflags;
265 unlock_kprobes(); 343 unlock_kprobes();
266 goto no_kprobe; 344 goto no_kprobe;
345 } else if (kprobe_status == KPROBE_HIT_SSDONE) {
346 /* TODO: Provide re-entrancy from
347 * post_kprobes_handler() and avoid exception
348 * stack corruption while single-stepping on
349 * the instruction of the new probe.
350 */
351 arch_disarm_kprobe(p);
352 regs->rip = (unsigned long)p->addr;
353 ret = 1;
354 } else {
355 /* We have reentered the kprobe_handler(), since
356 * another probe was hit while within the
357 * handler. We here save the original kprobe
358 * variables and just single step on instruction
359 * of the new probe without calling any user
360 * handlers.
361 */
362 save_previous_kprobe();
363 set_current_kprobe(p, regs);
364 p->nmissed++;
365 prepare_singlestep(p, regs);
366 kprobe_status = KPROBE_REENTER;
367 return 1;
267 } 368 }
268 disarm_kprobe(p, regs);
269 ret = 1;
270 } else { 369 } else {
271 p = current_kprobe; 370 p = current_kprobe;
272 if (p->break_handler && p->break_handler(p, regs)) { 371 if (p->break_handler && p->break_handler(p, regs)) {
@@ -296,11 +395,7 @@ int kprobe_handler(struct pt_regs *regs)
296 } 395 }
297 396
298 kprobe_status = KPROBE_HIT_ACTIVE; 397 kprobe_status = KPROBE_HIT_ACTIVE;
299 current_kprobe = p; 398 set_current_kprobe(p, regs);
300 kprobe_saved_rflags = kprobe_old_rflags
301 = (regs->eflags & (TF_MASK | IF_MASK));
302 if (is_IF_modifier(p->ainsn.insn))
303 kprobe_saved_rflags &= ~IF_MASK;
304 399
305 if (p->pre_handler && p->pre_handler(p, regs)) 400 if (p->pre_handler && p->pre_handler(p, regs))
306 /* handler has already set things up, so skip ss setup */ 401 /* handler has already set things up, so skip ss setup */
@@ -317,6 +412,55 @@ no_kprobe:
317} 412}
318 413
319/* 414/*
415 * For function-return probes, init_kprobes() establishes a probepoint
416 * here. When a retprobed function returns, this probe is hit and
417 * trampoline_probe_handler() runs, calling the kretprobe's handler.
418 */
419 void kretprobe_trampoline_holder(void)
420 {
421 asm volatile ( ".global kretprobe_trampoline\n"
422 "kretprobe_trampoline: \n"
423 "nop\n");
424 }
425
426/*
427 * Called when we hit the probe point at kretprobe_trampoline
428 */
429int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
430{
431 struct task_struct *tsk;
432 struct kretprobe_instance *ri;
433 struct hlist_head *head;
434 struct hlist_node *node;
435 unsigned long *sara = (unsigned long *)regs->rsp - 1;
436
437 tsk = arch_get_kprobe_task(sara);
438 head = kretprobe_inst_table_head(tsk);
439
440 hlist_for_each_entry(ri, node, head, hlist) {
441 if (ri->stack_addr == sara && ri->rp) {
442 if (ri->rp->handler)
443 ri->rp->handler(ri, regs);
444 }
445 }
446 return 0;
447}
448
449void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs,
450 unsigned long flags)
451{
452 struct kretprobe_instance *ri;
453 /* RA already popped */
454 unsigned long *sara = ((unsigned long *)regs->rsp) - 1;
455
456 while ((ri = get_rp_inst(sara))) {
457 regs->rip = (unsigned long)ri->ret_addr;
458 recycle_rp_inst(ri);
459 }
460 regs->eflags &= ~TF_MASK;
461}
462
463/*
320 * Called after single-stepping. p->addr is the address of the 464 * Called after single-stepping. p->addr is the address of the
321 * instruction whose first byte has been replaced by the "int 3" 465 * instruction whose first byte has been replaced by the "int 3"
322 * instruction. To avoid the SMP problems that can occur when we 466 * instruction. To avoid the SMP problems that can occur when we
@@ -401,13 +545,23 @@ int post_kprobe_handler(struct pt_regs *regs)
401 if (!kprobe_running()) 545 if (!kprobe_running())
402 return 0; 546 return 0;
403 547
404 if (current_kprobe->post_handler) 548 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
549 kprobe_status = KPROBE_HIT_SSDONE;
405 current_kprobe->post_handler(current_kprobe, regs, 0); 550 current_kprobe->post_handler(current_kprobe, regs, 0);
551 }
406 552
407 resume_execution(current_kprobe, regs); 553 if (current_kprobe->post_handler != trampoline_post_handler)
554 resume_execution(current_kprobe, regs);
408 regs->eflags |= kprobe_saved_rflags; 555 regs->eflags |= kprobe_saved_rflags;
409 556
410 unlock_kprobes(); 557 /* Restore the original saved kprobes variables and continue. */
558 if (kprobe_status == KPROBE_REENTER) {
559 restore_previous_kprobe();
560 goto out;
561 } else {
562 unlock_kprobes();
563 }
564out:
411 preempt_enable_no_resched(); 565 preempt_enable_no_resched();
412 566
413 /* 567 /*
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 61a63be6b294..9c5aa2a790c7 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -23,6 +23,7 @@
23#include <linux/kernel_stat.h> 23#include <linux/kernel_stat.h>
24#include <linux/mc146818rtc.h> 24#include <linux/mc146818rtc.h>
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <linux/module.h>
26 27
27#include <asm/smp.h> 28#include <asm/smp.h>
28#include <asm/mtrr.h> 29#include <asm/mtrr.h>
@@ -45,7 +46,8 @@ int acpi_found_madt;
45int apic_version [MAX_APICS]; 46int apic_version [MAX_APICS];
46unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; 47unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
47int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; 48int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
48cpumask_t pci_bus_to_cpumask [256] = { [0 ... 255] = CPU_MASK_ALL }; 49unsigned char pci_bus_to_node [256];
50EXPORT_SYMBOL(pci_bus_to_node);
49 51
50static int mp_current_pci_id = 0; 52static int mp_current_pci_id = 0;
51/* I/O APIC entries */ 53/* I/O APIC entries */
@@ -904,11 +906,20 @@ void __init mp_config_acpi_legacy_irqs (void)
904 return; 906 return;
905} 907}
906 908
909#define MAX_GSI_NUM 4096
910
907int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) 911int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
908{ 912{
909 int ioapic = -1; 913 int ioapic = -1;
910 int ioapic_pin = 0; 914 int ioapic_pin = 0;
911 int idx, bit = 0; 915 int idx, bit = 0;
916 static int pci_irq = 16;
917 /*
918 * Mapping between Global System Interrupts, which
919 * represent all possible interrupts, to the IRQs
920 * assigned to actual devices.
921 */
922 static int gsi_to_irq[MAX_GSI_NUM];
912 923
913 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) 924 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
914 return gsi; 925 return gsi;
@@ -943,11 +954,21 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
943 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 954 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
944 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 955 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
945 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 956 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
946 return gsi; 957 return gsi_to_irq[gsi];
947 } 958 }
948 959
949 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 960 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
950 961
962 if (edge_level) {
963 /*
964 * For PCI devices assign IRQs in order, avoiding gaps
965 * due to unused I/O APIC pins.
966 */
967 int irq = gsi;
968 gsi = pci_irq++;
969 gsi_to_irq[irq] = gsi;
970 }
971
951 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 972 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
952 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, 973 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
953 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); 974 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index dce8bab4306c..e59d1f9d6163 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -34,6 +34,7 @@
34#include <linux/ptrace.h> 34#include <linux/ptrace.h>
35#include <linux/utsname.h> 35#include <linux/utsname.h>
36#include <linux/random.h> 36#include <linux/random.h>
37#include <linux/kprobes.h>
37 38
38#include <asm/uaccess.h> 39#include <asm/uaccess.h>
39#include <asm/pgtable.h> 40#include <asm/pgtable.h>
@@ -293,6 +294,14 @@ void exit_thread(void)
293{ 294{
294 struct task_struct *me = current; 295 struct task_struct *me = current;
295 struct thread_struct *t = &me->thread; 296 struct thread_struct *t = &me->thread;
297
298 /*
299 * Remove function-return probe instances associated with this task
300 * and put them back on the free list. Do not insert an exit probe for
301 * this function, it will be disabled by kprobe_flush_task if you do.
302 */
303 kprobe_flush_task(me);
304
296 if (me->thread.io_bitmap_ptr) { 305 if (me->thread.io_bitmap_ptr) {
297 struct tss_struct *tss = &per_cpu(init_tss, get_cpu()); 306 struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
298 307
@@ -312,6 +321,13 @@ void flush_thread(void)
312 struct task_struct *tsk = current; 321 struct task_struct *tsk = current;
313 struct thread_info *t = current_thread_info(); 322 struct thread_info *t = current_thread_info();
314 323
324 /*
325 * Remove function-return probe instances associated with this task
326 * and put them back on the free list. Do not insert an exit probe for
327 * this function, it will be disabled by kprobe_flush_task if you do.
328 */
329 kprobe_flush_task(tsk);
330
315 if (t->flags & _TIF_ABI_PENDING) 331 if (t->flags & _TIF_ABI_PENDING)
316 t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32); 332 t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
317 333
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 99f038ede23c..000015dd5a8b 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -40,6 +40,8 @@
40#include <linux/acpi.h> 40#include <linux/acpi.h>
41#include <linux/kallsyms.h> 41#include <linux/kallsyms.h>
42#include <linux/edd.h> 42#include <linux/edd.h>
43#include <linux/mmzone.h>
44
43#include <asm/mtrr.h> 45#include <asm/mtrr.h>
44#include <asm/uaccess.h> 46#include <asm/uaccess.h>
45#include <asm/system.h> 47#include <asm/system.h>
@@ -348,7 +350,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
348 if (!memcmp(from, "mem=", 4)) 350 if (!memcmp(from, "mem=", 4))
349 parse_memopt(from+4, &from); 351 parse_memopt(from+4, &from);
350 352
351#ifdef CONFIG_DISCONTIGMEM 353#ifdef CONFIG_NUMA
352 if (!memcmp(from, "numa=", 5)) 354 if (!memcmp(from, "numa=", 5))
353 numa_setup(from+5); 355 numa_setup(from+5);
354#endif 356#endif
@@ -377,17 +379,20 @@ static __init void parse_cmdline_early (char ** cmdline_p)
377 *cmdline_p = command_line; 379 *cmdline_p = command_line;
378} 380}
379 381
380#ifndef CONFIG_DISCONTIGMEM 382#ifndef CONFIG_NUMA
381static void __init contig_initmem_init(void) 383static void __init
384contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
382{ 385{
383 unsigned long bootmap_size, bootmap; 386 unsigned long bootmap_size, bootmap;
384 bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; 387
385 bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); 388 memory_present(0, start_pfn, end_pfn);
386 if (bootmap == -1L) 389 bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
387 panic("Cannot find bootmem map of size %ld\n",bootmap_size); 390 bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
388 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); 391 if (bootmap == -1L)
389 e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); 392 panic("Cannot find bootmem map of size %ld\n",bootmap_size);
390 reserve_bootmem(bootmap, bootmap_size); 393 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
394 e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
395 reserve_bootmem(bootmap, bootmap_size);
391} 396}
392#endif 397#endif
393 398
@@ -554,10 +559,10 @@ void __init setup_arch(char **cmdline_p)
554 acpi_numa_init(); 559 acpi_numa_init();
555#endif 560#endif
556 561
557#ifdef CONFIG_DISCONTIGMEM 562#ifdef CONFIG_NUMA
558 numa_initmem_init(0, end_pfn); 563 numa_initmem_init(0, end_pfn);
559#else 564#else
560 contig_initmem_init(); 565 contig_initmem_init(0, end_pfn);
561#endif 566#endif
562 567
563 /* Reserve direct mapping */ 568 /* Reserve direct mapping */
@@ -618,6 +623,8 @@ void __init setup_arch(char **cmdline_p)
618 } 623 }
619 } 624 }
620#endif 625#endif
626
627 sparse_init();
621 paging_init(); 628 paging_init();
622 629
623 check_ioapic(); 630 check_ioapic();
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index 429c0269dc4e..98b7ba95d581 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -34,9 +34,9 @@
34 34
35#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 35#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
36 36
37void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 37int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
38 sigset_t *set, struct pt_regs * regs); 38 sigset_t *set, struct pt_regs * regs);
39void ia32_setup_frame(int sig, struct k_sigaction *ka, 39int ia32_setup_frame(int sig, struct k_sigaction *ka,
40 sigset_t *set, struct pt_regs * regs); 40 sigset_t *set, struct pt_regs * regs);
41 41
42asmlinkage long 42asmlinkage long
@@ -238,7 +238,7 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
238 return (void __user *)round_down(rsp - size, 16); 238 return (void __user *)round_down(rsp - size, 16);
239} 239}
240 240
241static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 241static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
242 sigset_t *set, struct pt_regs * regs) 242 sigset_t *set, struct pt_regs * regs)
243{ 243{
244 struct rt_sigframe __user *frame; 244 struct rt_sigframe __user *frame;
@@ -327,20 +327,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
327 current->comm, current->pid, frame, regs->rip, frame->pretcode); 327 current->comm, current->pid, frame, regs->rip, frame->pretcode);
328#endif 328#endif
329 329
330 return; 330 return 1;
331 331
332give_sigsegv: 332give_sigsegv:
333 force_sigsegv(sig, current); 333 force_sigsegv(sig, current);
334 return 0;
334} 335}
335 336
336/* 337/*
337 * OK, we're invoking a handler 338 * OK, we're invoking a handler
338 */ 339 */
339 340
340static void 341static int
341handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 342handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
342 sigset_t *oldset, struct pt_regs *regs) 343 sigset_t *oldset, struct pt_regs *regs)
343{ 344{
345 int ret;
346
344#ifdef DEBUG_SIG 347#ifdef DEBUG_SIG
345 printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", 348 printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n",
346 current->pid, sig, 349 current->pid, sig,
@@ -384,20 +387,22 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
384#ifdef CONFIG_IA32_EMULATION 387#ifdef CONFIG_IA32_EMULATION
385 if (test_thread_flag(TIF_IA32)) { 388 if (test_thread_flag(TIF_IA32)) {
386 if (ka->sa.sa_flags & SA_SIGINFO) 389 if (ka->sa.sa_flags & SA_SIGINFO)
387 ia32_setup_rt_frame(sig, ka, info, oldset, regs); 390 ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
388 else 391 else
389 ia32_setup_frame(sig, ka, oldset, regs); 392 ret = ia32_setup_frame(sig, ka, oldset, regs);
390 } else 393 } else
391#endif 394#endif
392 setup_rt_frame(sig, ka, info, oldset, regs); 395 ret = setup_rt_frame(sig, ka, info, oldset, regs);
393 396
394 if (!(ka->sa.sa_flags & SA_NODEFER)) { 397 if (ret && !(ka->sa.sa_flags & SA_NODEFER)) {
395 spin_lock_irq(&current->sighand->siglock); 398 spin_lock_irq(&current->sighand->siglock);
396 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 399 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
397 sigaddset(&current->blocked,sig); 400 sigaddset(&current->blocked,sig);
398 recalc_sigpending(); 401 recalc_sigpending();
399 spin_unlock_irq(&current->sighand->siglock); 402 spin_unlock_irq(&current->sighand->siglock);
400 } 403 }
404
405 return ret;
401} 406}
402 407
403/* 408/*
@@ -417,7 +422,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
417 * kernel mode. Just return without doing anything 422 * kernel mode. Just return without doing anything
418 * if so. 423 * if so.
419 */ 424 */
420 if ((regs->cs & 3) != 3) 425 if (!user_mode(regs))
421 return 1; 426 return 1;
422 427
423 if (try_to_freeze(0)) 428 if (try_to_freeze(0))
@@ -434,11 +439,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
434 * inside the kernel. 439 * inside the kernel.
435 */ 440 */
436 if (current->thread.debugreg7) 441 if (current->thread.debugreg7)
437 asm volatile("movq %0,%%db7" : : "r" (current->thread.debugreg7)); 442 set_debugreg(current->thread.debugreg7, 7);
438 443
439 /* Whee! Actually deliver the signal. */ 444 /* Whee! Actually deliver the signal. */
440 handle_signal(signr, &info, &ka, oldset, regs); 445 return handle_signal(signr, &info, &ka, oldset, regs);
441 return 1;
442 } 446 }
443 447
444 no_signal: 448 no_signal:
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index fb8c809b4cd9..66bf6ddeb0c3 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -64,6 +64,7 @@ static int notsc __initdata = 0;
64unsigned int cpu_khz; /* TSC clocks / usec, not used here */ 64unsigned int cpu_khz; /* TSC clocks / usec, not used here */
65static unsigned long hpet_period; /* fsecs / HPET clock */ 65static unsigned long hpet_period; /* fsecs / HPET clock */
66unsigned long hpet_tick; /* HPET clocks / interrupt */ 66unsigned long hpet_tick; /* HPET clocks / interrupt */
67static int hpet_use_timer;
67unsigned long vxtime_hz = PIT_TICK_RATE; 68unsigned long vxtime_hz = PIT_TICK_RATE;
68int report_lost_ticks; /* command line option */ 69int report_lost_ticks; /* command line option */
69unsigned long long monotonic_base; 70unsigned long long monotonic_base;
@@ -105,7 +106,9 @@ static inline unsigned int do_gettimeoffset_tsc(void)
105 106
106static inline unsigned int do_gettimeoffset_hpet(void) 107static inline unsigned int do_gettimeoffset_hpet(void)
107{ 108{
108 return ((hpet_readl(HPET_COUNTER) - vxtime.last) * vxtime.quot) >> 32; 109 /* cap counter read to one tick to avoid inconsistencies */
110 unsigned long counter = hpet_readl(HPET_COUNTER) - vxtime.last;
111 return (min(counter,hpet_tick) * vxtime.quot) >> 32;
109} 112}
110 113
111unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; 114unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc;
@@ -301,7 +304,7 @@ unsigned long long monotonic_clock(void)
301 304
302 last_offset = vxtime.last; 305 last_offset = vxtime.last;
303 base = monotonic_base; 306 base = monotonic_base;
304 this_offset = hpet_readl(HPET_T0_CMP) - hpet_tick; 307 this_offset = hpet_readl(HPET_COUNTER);
305 308
306 } while (read_seqretry(&xtime_lock, seq)); 309 } while (read_seqretry(&xtime_lock, seq));
307 offset = (this_offset - last_offset); 310 offset = (this_offset - last_offset);
@@ -377,7 +380,14 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
377 380
378 write_seqlock(&xtime_lock); 381 write_seqlock(&xtime_lock);
379 382
380 if (vxtime.hpet_address) { 383 if (vxtime.hpet_address)
384 offset = hpet_readl(HPET_COUNTER);
385
386 if (hpet_use_timer) {
387 /* if we're using the hpet timer functionality,
388 * we can more accurately know the counter value
389 * when the timer interrupt occured.
390 */
381 offset = hpet_readl(HPET_T0_CMP) - hpet_tick; 391 offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
382 delay = hpet_readl(HPET_COUNTER) - offset; 392 delay = hpet_readl(HPET_COUNTER) - offset;
383 } else { 393 } else {
@@ -803,17 +813,18 @@ static int hpet_timer_stop_set_go(unsigned long tick)
803 * Set up timer 0, as periodic with first interrupt to happen at hpet_tick, 813 * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
804 * and period also hpet_tick. 814 * and period also hpet_tick.
805 */ 815 */
806 816 if (hpet_use_timer) {
807 hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | 817 hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
808 HPET_TN_32BIT, HPET_T0_CFG); 818 HPET_TN_32BIT, HPET_T0_CFG);
809 hpet_writel(hpet_tick, HPET_T0_CMP); 819 hpet_writel(hpet_tick, HPET_T0_CMP);
810 hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */ 820 hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */
811 821 cfg |= HPET_CFG_LEGACY;
822 }
812/* 823/*
813 * Go! 824 * Go!
814 */ 825 */
815 826
816 cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY; 827 cfg |= HPET_CFG_ENABLE;
817 hpet_writel(cfg, HPET_CFG); 828 hpet_writel(cfg, HPET_CFG);
818 829
819 return 0; 830 return 0;
@@ -834,8 +845,7 @@ static int hpet_init(void)
834 845
835 id = hpet_readl(HPET_ID); 846 id = hpet_readl(HPET_ID);
836 847
837 if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER) || 848 if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER))
838 !(id & HPET_ID_LEGSUP))
839 return -1; 849 return -1;
840 850
841 hpet_period = hpet_readl(HPET_PERIOD); 851 hpet_period = hpet_readl(HPET_PERIOD);
@@ -845,6 +855,8 @@ static int hpet_init(void)
845 hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) / 855 hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) /
846 hpet_period; 856 hpet_period;
847 857
858 hpet_use_timer = (id & HPET_ID_LEGSUP);
859
848 return hpet_timer_stop_set_go(hpet_tick); 860 return hpet_timer_stop_set_go(hpet_tick);
849} 861}
850 862
@@ -901,9 +913,11 @@ void __init time_init(void)
901 set_normalized_timespec(&wall_to_monotonic, 913 set_normalized_timespec(&wall_to_monotonic,
902 -xtime.tv_sec, -xtime.tv_nsec); 914 -xtime.tv_sec, -xtime.tv_nsec);
903 915
904 if (!hpet_init()) { 916 if (!hpet_init())
905 vxtime_hz = (1000000000000000L + hpet_period / 2) / 917 vxtime_hz = (1000000000000000L + hpet_period / 2) /
906 hpet_period; 918 hpet_period;
919
920 if (hpet_use_timer) {
907 cpu_khz = hpet_calibrate_tsc(); 921 cpu_khz = hpet_calibrate_tsc();
908 timename = "HPET"; 922 timename = "HPET";
909#ifdef CONFIG_X86_PM_TIMER 923#ifdef CONFIG_X86_PM_TIMER
@@ -968,7 +982,7 @@ void __init time_init_gtod(void)
968 if (unsynchronized_tsc()) 982 if (unsynchronized_tsc())
969 notsc = 1; 983 notsc = 1;
970 if (vxtime.hpet_address && notsc) { 984 if (vxtime.hpet_address && notsc) {
971 timetype = "HPET"; 985 timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
972 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; 986 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
973 vxtime.mode = VXTIME_HPET; 987 vxtime.mode = VXTIME_HPET;
974 do_gettimeoffset = do_gettimeoffset_hpet; 988 do_gettimeoffset = do_gettimeoffset_hpet;
@@ -983,7 +997,7 @@ void __init time_init_gtod(void)
983 printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n"); 997 printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n");
984#endif 998#endif
985 } else { 999 } else {
986 timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC"; 1000 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
987 vxtime.mode = VXTIME_TSC; 1001 vxtime.mode = VXTIME_TSC;
988 } 1002 }
989 1003
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 3dfec8fdabcd..121646fc43f6 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -274,7 +274,7 @@ EXPORT_SYMBOL(dump_stack);
274void show_registers(struct pt_regs *regs) 274void show_registers(struct pt_regs *regs)
275{ 275{
276 int i; 276 int i;
277 int in_kernel = (regs->cs & 3) == 0; 277 int in_kernel = !user_mode(regs);
278 unsigned long rsp; 278 unsigned long rsp;
279 const int cpu = safe_smp_processor_id(); 279 const int cpu = safe_smp_processor_id();
280 struct task_struct *cur = cpu_pda[cpu].pcurrent; 280 struct task_struct *cur = cpu_pda[cpu].pcurrent;
@@ -318,7 +318,7 @@ void handle_BUG(struct pt_regs *regs)
318 struct bug_frame f; 318 struct bug_frame f;
319 char tmp; 319 char tmp;
320 320
321 if (regs->cs & 3) 321 if (user_mode(regs))
322 return; 322 return;
323 if (__copy_from_user(&f, (struct bug_frame *) regs->rip, 323 if (__copy_from_user(&f, (struct bug_frame *) regs->rip,
324 sizeof(struct bug_frame))) 324 sizeof(struct bug_frame)))
@@ -437,7 +437,7 @@ static void do_trap(int trapnr, int signr, char *str,
437 } 437 }
438#endif 438#endif
439 439
440 if ((regs->cs & 3) != 0) { 440 if (user_mode(regs)) {
441 struct task_struct *tsk = current; 441 struct task_struct *tsk = current;
442 442
443 if (exception_trace && unhandled_signal(tsk, signr)) 443 if (exception_trace && unhandled_signal(tsk, signr))
@@ -522,7 +522,7 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
522 } 522 }
523#endif 523#endif
524 524
525 if ((regs->cs & 3)!=0) { 525 if (user_mode(regs)) {
526 struct task_struct *tsk = current; 526 struct task_struct *tsk = current;
527 527
528 if (exception_trace && unhandled_signal(tsk, SIGSEGV)) 528 if (exception_trace && unhandled_signal(tsk, SIGSEGV))
@@ -638,7 +638,7 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs)
638 if (eregs == (struct pt_regs *)eregs->rsp) 638 if (eregs == (struct pt_regs *)eregs->rsp)
639 ; 639 ;
640 /* Exception from user space */ 640 /* Exception from user space */
641 else if (eregs->cs & 3) 641 else if (user_mode(eregs))
642 regs = ((struct pt_regs *)current->thread.rsp0) - 1; 642 regs = ((struct pt_regs *)current->thread.rsp0) - 1;
643 /* Exception from kernel and interrupts are enabled. Move to 643 /* Exception from kernel and interrupts are enabled. Move to
644 kernel process stack. */ 644 kernel process stack. */
@@ -669,7 +669,7 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
669 } 669 }
670#endif 670#endif
671 671
672 asm("movq %%db6,%0" : "=r" (condition)); 672 get_debugreg(condition, 6);
673 673
674 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, 674 if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
675 SIGTRAP) == NOTIFY_STOP) 675 SIGTRAP) == NOTIFY_STOP)
@@ -697,7 +697,7 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
697 * allowing programs to debug themselves without the ptrace() 697 * allowing programs to debug themselves without the ptrace()
698 * interface. 698 * interface.
699 */ 699 */
700 if ((regs->cs & 3) == 0) 700 if (!user_mode(regs))
701 goto clear_TF_reenable; 701 goto clear_TF_reenable;
702 /* 702 /*
703 * Was the TF flag set by a debugger? If so, clear it now, 703 * Was the TF flag set by a debugger? If so, clear it now,
@@ -715,13 +715,13 @@ asmlinkage void do_debug(struct pt_regs * regs, unsigned long error_code)
715 info.si_signo = SIGTRAP; 715 info.si_signo = SIGTRAP;
716 info.si_errno = 0; 716 info.si_errno = 0;
717 info.si_code = TRAP_BRKPT; 717 info.si_code = TRAP_BRKPT;
718 if ((regs->cs & 3) == 0) 718 if (!user_mode(regs))
719 goto clear_dr7; 719 goto clear_dr7;
720 720
721 info.si_addr = (void __user *)regs->rip; 721 info.si_addr = (void __user *)regs->rip;
722 force_sig_info(SIGTRAP, &info, tsk); 722 force_sig_info(SIGTRAP, &info, tsk);
723clear_dr7: 723clear_dr7:
724 asm volatile("movq %0,%%db7"::"r"(0UL)); 724 set_debugreg(0UL, 7);
725 return; 725 return;
726 726
727clear_TF_reenable: 727clear_TF_reenable:
@@ -756,7 +756,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
756 unsigned short cwd, swd; 756 unsigned short cwd, swd;
757 757
758 conditional_sti(regs); 758 conditional_sti(regs);
759 if ((regs->cs & 3) == 0 && 759 if (!user_mode(regs) &&
760 kernel_math_error(regs, "kernel x87 math error")) 760 kernel_math_error(regs, "kernel x87 math error"))
761 return; 761 return;
762 762
@@ -822,7 +822,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
822 unsigned short mxcsr; 822 unsigned short mxcsr;
823 823
824 conditional_sti(regs); 824 conditional_sti(regs);
825 if ((regs->cs & 3) == 0 && 825 if (!user_mode(regs) &&
826 kernel_math_error(regs, "kernel simd math error")) 826 kernel_math_error(regs, "kernel simd math error"))
827 return; 827 return;
828 828
diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c
index aed61a668a1b..33a873a3c223 100644
--- a/arch/x86_64/lib/delay.c
+++ b/arch/x86_64/lib/delay.c
@@ -12,6 +12,7 @@
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <asm/delay.h> 14#include <asm/delay.h>
15#include <asm/msr.h>
15 16
16#ifdef CONFIG_SMP 17#ifdef CONFIG_SMP
17#include <asm/smp.h> 18#include <asm/smp.h>
@@ -19,6 +20,12 @@
19 20
20int x86_udelay_tsc = 0; /* Delay via TSC */ 21int x86_udelay_tsc = 0; /* Delay via TSC */
21 22
23int read_current_timer(unsigned long *timer_value)
24{
25 rdtscll(*timer_value);
26 return 0;
27}
28
22void __delay(unsigned long loops) 29void __delay(unsigned long loops)
23{ 30{
24 unsigned bclock, now; 31 unsigned bclock, now;
diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
index 66c354ad80ca..1d232a87f113 100644
--- a/arch/x86_64/mm/Makefile
+++ b/arch/x86_64/mm/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-y := init.o fault.o ioremap.o extable.o pageattr.o 5obj-y := init.o fault.o ioremap.o extable.o pageattr.o
6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 6obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
7obj-$(CONFIG_DISCONTIGMEM) += numa.o 7obj-$(CONFIG_NUMA) += numa.o
8obj-$(CONFIG_K8_NUMA) += k8topology.o 8obj-$(CONFIG_K8_NUMA) += k8topology.o
9obj-$(CONFIG_ACPI_NUMA) += srat.o 9obj-$(CONFIG_ACPI_NUMA) += srat.o
10 10
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index 57d3ab15a5c7..2f187986f940 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -74,7 +74,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
74 instr = (unsigned char *)convert_rip_to_linear(current, regs); 74 instr = (unsigned char *)convert_rip_to_linear(current, regs);
75 max_instr = instr + 15; 75 max_instr = instr + 15;
76 76
77 if ((regs->cs & 3) != 0 && instr >= (unsigned char *)TASK_SIZE) 77 if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
78 return 0; 78 return 0;
79 79
80 while (scan_more && instr < max_instr) { 80 while (scan_more && instr < max_instr) {
@@ -106,7 +106,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
106 /* Could check the LDT for lm, but for now it's good 106 /* Could check the LDT for lm, but for now it's good
107 enough to assume that long mode only uses well known 107 enough to assume that long mode only uses well known
108 segments or kernel. */ 108 segments or kernel. */
109 scan_more = ((regs->cs & 3) == 0) || (regs->cs == __USER_CS); 109 scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
110 break; 110 break;
111 111
112 case 0x60: 112 case 0x60:
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index dbe53b4c7e66..72e4b364ed73 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -318,7 +318,7 @@ void zap_low_mappings(void)
318 flush_tlb_all(); 318 flush_tlb_all();
319} 319}
320 320
321#ifndef CONFIG_DISCONTIGMEM 321#ifndef CONFIG_NUMA
322void __init paging_init(void) 322void __init paging_init(void)
323{ 323{
324 { 324 {
@@ -427,13 +427,16 @@ void __init mem_init(void)
427 reservedpages = 0; 427 reservedpages = 0;
428 428
429 /* this will put all low memory onto the freelists */ 429 /* this will put all low memory onto the freelists */
430#ifdef CONFIG_DISCONTIGMEM 430#ifdef CONFIG_NUMA
431 totalram_pages += numa_free_all_bootmem(); 431 totalram_pages += numa_free_all_bootmem();
432 tmp = 0; 432 tmp = 0;
433 /* should count reserved pages here for all nodes */ 433 /* should count reserved pages here for all nodes */
434#else 434#else
435
436#ifdef CONFIG_FLATMEM
435 max_mapnr = end_pfn; 437 max_mapnr = end_pfn;
436 if (!mem_map) BUG(); 438 if (!mem_map) BUG();
439#endif
437 440
438 totalram_pages += free_all_bootmem(); 441 totalram_pages += free_all_bootmem();
439 442
@@ -515,7 +518,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
515void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 518void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
516{ 519{
517 /* Should check here against the e820 map to avoid double free */ 520 /* Should check here against the e820 map to avoid double free */
518#ifdef CONFIG_DISCONTIGMEM 521#ifdef CONFIG_NUMA
519 int nid = phys_to_nid(phys); 522 int nid = phys_to_nid(phys);
520 reserve_bootmem_node(NODE_DATA(nid), phys, len); 523 reserve_bootmem_node(NODE_DATA(nid), phys, len);
521#else 524#else
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 58aac23760ef..6972df480d2b 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -178,7 +178,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
178 if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS) 178 if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
179 return (__force void __iomem *)phys_to_virt(phys_addr); 179 return (__force void __iomem *)phys_to_virt(phys_addr);
180 180
181#ifndef CONFIG_DISCONTIGMEM 181#ifdef CONFIG_FLATMEM
182 /* 182 /*
183 * Don't allow anybody to remap normal RAM that we're using.. 183 * Don't allow anybody to remap normal RAM that we're using..
184 */ 184 */
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index fd9f25d7a6c4..84cde796ecb1 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -66,6 +66,13 @@ int __init compute_hash_shift(struct node *nodes, int numnodes)
66 return -1; 66 return -1;
67} 67}
68 68
69#ifdef CONFIG_SPARSEMEM
70int early_pfn_to_nid(unsigned long pfn)
71{
72 return phys_to_nid(pfn << PAGE_SHIFT);
73}
74#endif
75
69/* Initialize bootmem allocator for a node */ 76/* Initialize bootmem allocator for a node */
70void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) 77void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
71{ 78{
@@ -80,6 +87,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
80 start_pfn = start >> PAGE_SHIFT; 87 start_pfn = start >> PAGE_SHIFT;
81 end_pfn = end >> PAGE_SHIFT; 88 end_pfn = end >> PAGE_SHIFT;
82 89
90 memory_present(nodeid, start_pfn, end_pfn);
83 nodedata_phys = find_e820_area(start, end, pgdat_size); 91 nodedata_phys = find_e820_area(start, end, pgdat_size);
84 if (nodedata_phys == -1L) 92 if (nodedata_phys == -1L)
85 panic("Cannot find memory pgdat in node %d\n", nodeid); 93 panic("Cannot find memory pgdat in node %d\n", nodeid);
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c
index 62349c78db57..7e7d0c2a0025 100644
--- a/arch/x86_64/pci/k8-bus.c
+++ b/arch/x86_64/pci/k8-bus.c
@@ -53,25 +53,11 @@ fill_mp_bus_to_cpumask(void)
53 for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus); 53 for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus);
54 j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus); 54 j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
55 j++) 55 j++)
56 pci_bus_to_cpumask[j] = 56 pci_bus_to_node[j] = NODE_ID(nid);
57 node_to_cpumask(NODE_ID(nid));
58 } 57 }
59 } 58 }
60 } 59 }
61 60
62 /* quick sanity check */
63 printed = 0;
64 for (i = 0; i < 256; i++) {
65 if (cpus_empty(pci_bus_to_cpumask[i])) {
66 pci_bus_to_cpumask[i] = CPU_MASK_ALL;
67 if (printed)
68 continue;
69 printk(KERN_ERR
70 "k8-bus.c: some busses have empty cpu mask\n");
71 printed = 1;
72 }
73 }
74
75 return 0; 61 return 0;
76} 62}
77 63
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
new file mode 100644
index 000000000000..3e89767cea72
--- /dev/null
+++ b/arch/xtensa/Kconfig
@@ -0,0 +1,258 @@
1# For a description of the syntax of this configuration file,
2# see Documentation/kbuild/config-language.txt.
3
4mainmenu "Linux/Xtensa Kernel Configuration"
5
6config FRAME_POINTER
7 bool
8 default n
9
10config XTENSA
11 bool
12 default y
13 help
14 Xtensa processors are 32-bit RISC machines designed by Tensilica
15 primarily for embedded systems. These processors are both
16 configurable and extensible. The Linux port to the Xtensa
17 architecture supports all processor configurations and extensions,
18 with reasonable minimum requirements. The Xtensa Linux project has
19 a home page at <http://xtensa.sourceforge.net/>.
20
21config UID16
22 bool
23 default n
24
25config RWSEM_XCHGADD_ALGORITHM
26 bool
27 default y
28
29config HAVE_DEC_LOCK
30 bool
31 default y
32
33config GENERIC_HARDIRQS
34 bool
35 default y
36
37source "init/Kconfig"
38
39menu "Processor type and features"
40
41choice
42 prompt "Xtensa Processor Configuration"
43 default XTENSA_CPU_LINUX_BE
44
45config XTENSA_CPU_LINUX_BE
46 bool "linux_be"
47 ---help---
48 The linux_be processor configuration is the baseline Xtensa
49 configurations included in this kernel and also used by
50 binutils, gcc, and gdb. It contains no TIE, no coprocessors,
51 and the following configuration options:
52
53 Code Density Option 2 Misc Special Registers
54 NSA/NSAU Instructions 128-bit Data Bus Width
55 Processor ID 8K, 2-way I and D Caches
56 Zero-Overhead Loops 2 Inst Address Break Registers
57 Big Endian 2 Data Address Break Registers
58 64 General-Purpose Registers JTAG Interface and Trace Port
59 17 Interrupts MMU w/ TLBs and Autorefill
60 3 Interrupt Levels 8 Autorefill Ways (I/D TLBs)
61 3 Timers Unaligned Exceptions
62endchoice
63
64config MMU
65 bool
66 default y
67
68config XTENSA_UNALIGNED_USER
69 bool "Unaligned memory access in use space"
70 ---help---
71 The Xtensa architecture currently does not handle unaligned
72 memory accesses in hardware but through an exception handler.
73 Per default, unaligned memory accesses are disabled in user space.
74
75 Say Y here to enable unaligned memory access in user space.
76
77config PREEMPT
78 bool "Preemptible Kernel"
79 ---help---
80 This option reduces the latency of the kernel when reacting to
81 real-time or interactive events by allowing a low priority process to
82 be preempted even if it is in kernel mode executing a system call.
83 Unfortunately the kernel code has some race conditions if both
84 CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
85 currently disabled if you are building an SMP kernel.
86
87 Say Y here if you are building a kernel for a desktop, embedded
88 or real-time system. Say N if you are unsure.
89
90config MATH_EMULATION
91 bool "Math emulation"
92 help
93 Can we use information of configuration file?
94
95config HIGHMEM
96 bool "High memory support"
97
98endmenu
99
100menu "Platform options"
101
102choice
103 prompt "Xtensa System Type"
104 default XTENSA_PLATFORM_ISS
105
106config XTENSA_PLATFORM_ISS
107 bool "ISS"
108 help
109 ISS is an acronym for Tensilica's Instruction Set Simulator.
110
111config XTENSA_PLATFORM_XT2000
112 bool "XT2000"
113 help
114 XT2000 is the name of Tensilica's feature-rich emulation platform.
115 This hardware is capable of running a full Linux distribution.
116
117endchoice
118
119
120config XTENSA_CALIBRATE_CCOUNT
121 bool "Auto calibration of the CPU clock rate"
122 ---help---
123 On some platforms (XT2000, for example), the CPU clock rate can
124 vary. The frequency can be determined, however, by measuring
125 against a well known, fixed frequency, such as an UART oscillator.
126
127config XTENSA_CPU_CLOCK
128 int "CPU clock rate [MHz]"
129 depends on !XTENSA_CALIBRATE_CCOUNT
130 default "16"
131
132config GENERIC_CALIBRATE_DELAY
133 bool "Auto calibration of the BogoMIPS value"
134 ---help---
135 The BogoMIPS value can easily derived from the CPU frequency.
136
137config CMDLINE_BOOL
138 bool "Default bootloader kernel arguments"
139
140config CMDLINE
141 string "Initial kernel command string"
142 depends on CMDLINE_BOOL
143 default "console=ttyS0,38400 root=/dev/ram"
144 help
145 On some architectures (EBSA110 and CATS), there is currently no way
146 for the boot loader to pass arguments to the kernel. For these
147 architectures, you should supply some command-line options at build
148 time by entering them here. As a minimum, you should specify the
149 memory size and the root device (e.g., mem=64M root=/dev/nfs).
150
151config SERIAL_CONSOLE
152 bool
153 depends on XTENSA_PLATFORM_ISS
154 default y
155
156config XTENSA_ISS_NETWORK
157 bool
158 depends on XTENSA_PLATFORM_ISS
159 default y
160
161endmenu
162
163menu "Bus options"
164
165config PCI
166 bool "PCI support" if !XTENSA_PLATFORM_ISS
167 depends on !XTENSA_PLATFORM_ISS
168 default y
169 help
170 Find out whether you have a PCI motherboard. PCI is the name of a
171 bus system, i.e. the way the CPU talks to the other stuff inside
172 your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
173 VESA. If you have PCI, say Y, otherwise N.
174
175 The PCI-HOWTO, available from
176 <http://www.linuxdoc.org/docs.html#howto>, contains valuable
177 information about which PCI hardware does work under Linux and which
178 doesn't
179
180source "drivers/pci/Kconfig"
181
182config HOTPLUG
183
184 bool "Support for hot-pluggable devices"
185 ---help---
186 Say Y here if you want to plug devices into your computer while
187 the system is running, and be able to use them quickly. In many
188 cases, the devices can likewise be unplugged at any time too.
189
190 One well known example of this is PCMCIA- or PC-cards, credit-card
191 size devices such as network cards, modems or hard drives which are
192 plugged into slots found on all modern laptop computers. Another
193 example, used on modern desktops as well as laptops, is USB.
194
195 Enable HOTPLUG and KMOD, and build a modular kernel. Get agent
196 software (at <http://linux-hotplug.sourceforge.net/>) and install it.
197 Then your kernel will automatically call out to a user mode "policy
198 agent" (/sbin/hotplug) to load modules and set up software needed
199 to use devices as you hotplug them.
200
201source "drivers/pcmcia/Kconfig"
202
203source "drivers/pci/hotplug/Kconfig"
204
205endmenu
206
207menu "Exectuable file formats"
208
209# only elf supported
210config KCORE_ELF
211 bool
212 depends on PROC_FS
213 default y
214 help
215 If you enabled support for /proc file system then the file
216 /proc/kcore will contain the kernel core image in ELF format. This
217 can be used in gdb:
218
219 $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
220
221 This is especially useful if you have compiled the kernel with the
222 "-g" option to preserve debugging information. It is mainly used
223 for examining kernel data structures on the live kernel.
224
225source "fs/Kconfig.binfmt"
226
227endmenu
228
229source "drivers/Kconfig"
230
231source "fs/Kconfig"
232
233menu "Xtensa initrd options"
234 depends on BLK_DEV_INITRD
235
236 config EMBEDDED_RAMDISK
237 bool "Embed root filesystem ramdisk into the kernel"
238
239config EMBEDDED_RAMDISK_IMAGE
240 string "Filename of gziped ramdisk image"
241 depends on EMBEDDED_RAMDISK
242 default "ramdisk.gz"
243 help
244 This is the filename of the ramdisk image to be built into the
245 kernel. Relative pathnames are relative to arch/xtensa/boot/ramdisk/.
246 The ramdisk image is not part of the kernel distribution; you must
247 provide one yourself.
248endmenu
249
250source "arch/xtensa/Kconfig.debug"
251
252source "security/Kconfig"
253
254source "crypto/Kconfig"
255
256source "lib/Kconfig"
257
258
diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug
new file mode 100644
index 000000000000..11c585295dd7
--- /dev/null
+++ b/arch/xtensa/Kconfig.debug
@@ -0,0 +1,7 @@
1menu "Kernel hacking"
2
3source "lib/Kconfig.debug"
4
5endmenu
6
7
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
new file mode 100644
index 000000000000..4fa27453b1f9
--- /dev/null
+++ b/arch/xtensa/Makefile
@@ -0,0 +1,102 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright (C) 2001 - 2005 Tensilica Inc.
7#
8# This file is included by the global makefile so that you can add your own
9# architecture-specific flags and dependencies. Remember to do have actions
10# for "archclean" and "archdep" for cleaning up and making dependencies for
11# this architecture
12
13# Core configuration.
14# (Use CPU=<xtensa_config> to use another default compiler.)
15
16cpu-$(CONFIG_XTENSA_CPU_LINUX_BE) := linux_be
17cpu-$(CONFIG_XTENSA_CPU_LINUX_CUSTOM) := linux_custom
18
19CPU = $(cpu-y)
20export CPU
21
22# Platform configuration
23
24platform-y := common
25platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
26platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
27
28PLATFORM = $(platform-y)
29export PLATFORM
30
31#LDFLAGS_vmlinux := -T$(word 1,$(LINKSCRIPT))
32AFLAGS_vmlinux.lds.o := -Uxtensa
33CPPFLAGS += -Iarch/xtensa -Iinclude/asm -mlongcalls -g
34AFLAGS += -Iarch/xtensa -Iinclude/asm
35CPP = $(CC) -E $(CFLAGS)
36
37cflags-y += -Iarch/xtensa -pipe -mlongcalls
38
39
40KBUILD_DEFCONFIG := common_defconfig
41
42# ramdisk/initrd support
43# You need a compressed ramdisk image, named ramdisk.gz in
44# arch/xtensa/boot/ramdisk
45
46core-$(CONFIG_EMBEDDED_RAMDISK) += arch/xtensa/boot/ramdisk/
47
48# Test for cross compiling
49
50ifneq ($(CPU),)
51 COMPILE_ARCH = $(shell uname -m)
52
53 ifneq ($(COMPILE_ARCH), xtensa)
54 ifndef CROSS_COMPILE
55 CROSS_COMPILE = xtensa_$(CPU)-
56 endif
57 endif
58endif
59
60#
61
62LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
63
64head-y := arch/xtensa/kernel/head.o
65core-y += arch/xtensa/kernel/ \
66 arch/xtensa/mm/ arch/xtensa/platform-$(PLATFORM)/
67libs-y += arch/xtensa/lib/ $(LIBGCC)
68
69boot := arch/xtensa/boot
70
71arch/xtensa/kernel/asm-offsets.s: \
72 arch/xtensa/kernel/asm-offsets.c \
73 include/asm-xtensa/.platform
74
75include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s
76 $(call filechk,gen-asm-offsets)
77
78prepare: include/asm-xtensa/.platform include/asm-xtensa/offsets.h
79
80# Update machine cpu and platform symlinks if something which affects
81# them changed.
82
83include/asm-xtensa/.platform: $(wildcard include/config/arch/*.h)
84 @echo ' Setting up cpu ($(CPU)) and platform ($(PLATFORM)) symlinks'
85 $(Q)rm -f include/asm-xtensa/platform
86 $(Q)rm -f include/asm-xtensa/xtensa/config
87 $(Q)(cd include/asm-xtensa/; ln -sf platform-$(PLATFORM) platform)
88 $(Q)(cd include/asm-xtensa/xtensa; ln -sf config-$(CPU) config)
89
90all: zImage
91
92bzImage : zImage
93
94zImage zImage.initrd: vmlinux
95 $(Q)$(MAKE) $(build)=$(boot) $@
96
97CLEAN_FILES += arch/xtensa/vmlinux.lds include/asm-xtensa/offset.h
98
99define archhelp
100 @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)'
101endef
102
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
new file mode 100644
index 000000000000..260f456ccf0b
--- /dev/null
+++ b/arch/xtensa/boot/Makefile
@@ -0,0 +1,37 @@
1#
2# arch/xtensa/boot/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8#
9
10
11CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include
12HOSTFLAGS += -Iarch/$(ARCH)/boot/include
13
14BIG_ENDIAN := $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big)
15
16
17export CFLAGS
18export AFLAGS
19export BIG_ENDIAN
20
21# Subdirs for the boot loader(s)
22
23bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf
24bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
25
26subdir-y := lib/
27
28subdir-y += boot-elf/ boot-redboot/
29
30zImage zImage.initrd Image Image.initrd: $(bootdir-y)
31
32$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
33 $(addprefix $(obj)/,$(host-progs))
34 $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
35
36
37
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
new file mode 100644
index 000000000000..f6ef6a369667
--- /dev/null
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -0,0 +1,52 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6
7GZIP = gzip
8GZIP_FLAGS = -v9fc
9
10ifeq ($(BIG_ENDIAN),1)
11OBJCOPY_ARGS := -O elf32-xtensa-be
12else
13OBJCOPY_ARGS := -O elf32-xtensa-le
14endif
15
16export OBJCOPY_ARGS
17
18boot-y := bootstrap.o
19
20OBJS := $(addprefix $(obj)/,$(boot-y))
21
22Image: vmlinux $(OBJS)
23 $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
24 vmlinux vmlinux.tmp
25 $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
26 --add-section image=vmlinux.tmp \
27 --set-section-flags image=contents,alloc,load,load,data \
28 $(OBJS) $@.tmp
29 $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
30 -T arch/$(ARCH)/boot/boot-elf/boot.ld \
31 -o arch/$(ARCH)/boot/$@.elf $@.tmp
32 rm -f $@.tmp vmlinux.tmp
33
34Image.initrd: vmlinux $(OBJS)
35 $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
36 --add-section .initrd=arch/$(ARCH)/boot/ramdisk \
37 --set-section-flags .initrd=contents,alloc,load,load,data \
38 vmlinux vmlinux.tmp
39 $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
40 --add-section image=vmlinux.tmp \
41 --set-section-flags image=contents,alloc,load,load,data \
42 $(OBJS) $@.tmp
43 $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
44 -T arch/$(ARCH)/boot/boot-elf/boot.ld \
45 -o arch/$(ARCH)/boot/$@.elf $@.tmp
46 rm -f $@.tmp vmlinux.tmp
47
48
49zImage: Image
50
51zImage.initrd: Image.initrd
52
diff --git a/arch/xtensa/boot/boot-elf/boot.ld b/arch/xtensa/boot/boot-elf/boot.ld
new file mode 100644
index 000000000000..4ab06a0a7a6b
--- /dev/null
+++ b/arch/xtensa/boot/boot-elf/boot.ld
@@ -0,0 +1,71 @@
1OUTPUT_ARCH(xtensa)
2
3SECTIONS
4{
5 .start 0xD0000000 : { *(.start) }
6
7 .text 0xD0000000:
8 {
9 __reloc_start = . ;
10 _text_start = . ;
11 *(.literal .text.literal .text)
12 _text_end = . ;
13 }
14
15 .rodata ALIGN(0x04):
16 {
17 *(.rodata)
18 *(.rodata1)
19 }
20
21 .data ALIGN(0x04):
22 {
23 *(.data)
24 *(.data1)
25 *(.sdata)
26 *(.sdata2)
27 *(.got.plt)
28 *(.got)
29 *(.dynamic)
30 }
31
32 __reloc_end = . ;
33
34 .initrd ALIGN(0x10) :
35 {
36 boot_initrd_start = . ;
37 *(.initrd)
38 boot_initrd_end = .;
39 }
40
41 . = ALIGN(0x10);
42 __image_load = . ;
43 .image 0xd0001000:
44 {
45 _image_start = .;
46 *(image)
47 . = (. + 3) & ~ 3;
48 _image_end = . ;
49 }
50
51
52 .bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
53 {
54 __bss_start = .;
55 *(.sbss)
56 *(.scommon)
57 *(.dynbss)
58 *(.bss)
59 __bss_end = .;
60 }
61 _end = .;
62 _param_start = .;
63
64 .ResetVector.text 0xfe000020 :
65 {
66 *(.ResetVector.text)
67 }
68
69
70 PROVIDE (end = .);
71}
diff --git a/arch/xtensa/boot/boot-elf/bootstrap.S b/arch/xtensa/boot/boot-elf/bootstrap.S
new file mode 100644
index 000000000000..7cba94abdab8
--- /dev/null
+++ b/arch/xtensa/boot/boot-elf/bootstrap.S
@@ -0,0 +1,37 @@
1
2#include <xtensa/config/specreg.h>
3#include <xtensa/config/core.h>
4
5#include <linux/config.h>
6#include <asm/bootparam.h>
7
8
9/* ResetVector
10 */
11 .section .ResetVector.text, "ax"
12 .global _ResetVector
13_ResetVector:
14 _j reset
15 .align 4
16RomInitAddr:
17 .word 0xd0001000
18RomBootParam:
19 .word _bootparam
20reset:
21 l32r a0, RomInitAddr
22 l32r a2, RomBootParam
23 movi a3, 0
24 movi a4, 0
25 jx a0
26
27 .align 4
28 .section .bootstrap.data, "aw"
29
30 .globl _bootparam
31_bootparam:
32 .short BP_TAG_FIRST
33 .short 4
34 .long BP_VERSION
35 .short BP_TAG_LAST
36 .short 0
37 .long 0
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
new file mode 100644
index 000000000000..ca8a68bc8472
--- /dev/null
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -0,0 +1,35 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6
7GZIP = gzip
8GZIP_FLAGS = -v9fc
9ifeq ($(BIG_ENDIAN),1)
10OBJCOPY_ARGS := -O elf32-xtensa-be
11else
12OBJCOPY_ARGS := -O elf32-xtensa-le
13endif
14
15LD_ARGS = -T $(obj)/boot.ld
16
17boot-y := bootstrap.o
18
19OBJS := $(addprefix $(obj)/,$(boot-y))
20LIBS := arch/$(ARCH)/boot/lib/lib.a arch/$(ARCH)/lib/lib.a
21
22LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
23
24zImage: vmlinux $(OBJS) $(LIBS)
25 $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
26 $(TOPDIR)/vmlinux vmlinux.tmp
27 gzip -vf9 vmlinux.tmp
28 $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
29 --add-section image=vmlinux.tmp.gz \
30 --set-section-flags image=contents,alloc,load,load,data \
31 $(OBJS) $@.tmp
32 $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC)
33 $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/images/$@.redboot
34# rm -f $@.tmp $@.elf vmlinux.tmp.gz
35
diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
new file mode 100644
index 000000000000..65b726410e8a
--- /dev/null
+++ b/arch/xtensa/boot/boot-redboot/boot.ld
@@ -0,0 +1,66 @@
1OUTPUT_ARCH(xtensa)
2
3SECTIONS
4{
5 .start 0xD0200000 : { *(.start) }
6
7 .text :
8 {
9 __reloc_start = . ;
10 _text_start = . ;
11 *(.literal .text.literal .text)
12 _text_end = . ;
13 }
14
15 .rodata ALIGN(0x04):
16 {
17 *(.rodata)
18 *(.rodata1)
19 }
20
21 .data ALIGN(0x04):
22 {
23 *(.data)
24 *(.data1)
25 *(.sdata)
26 *(.sdata2)
27 *(.got.plt)
28 *(.got)
29 *(.dynamic)
30 }
31
32 __reloc_end = . ;
33
34 .initrd ALIGN(0x10) :
35 {
36 boot_initrd_start = . ;
37 *(.initrd)
38 boot_initrd_end = .;
39 }
40
41 . = ALIGN(0x10);
42 __image_load = . ;
43 .image 0xd0001000: AT(__image_load)
44 {
45 _image_start = .;
46 *(image)
47 . = (. + 3) & ~ 3;
48 _image_end = . ;
49 }
50
51
52 .bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
53 {
54 __bss_start = .;
55 *(.sbss)
56 *(.scommon)
57 *(.dynbss)
58 *(.bss)
59 __bss_end = .;
60 }
61 _end = .;
62 _param_start = .;
63
64
65 PROVIDE (end = .);
66}
diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S
new file mode 100644
index 000000000000..ee636b0da81c
--- /dev/null
+++ b/arch/xtensa/boot/boot-redboot/bootstrap.S
@@ -0,0 +1,246 @@
1
2#define _ASMLANGUAGE
3#include <xtensa/config/specreg.h>
4#include <xtensa/config/core.h>
5#include <xtensa/cacheasm.h>
6
7 /*
8 * RB-Data: RedBoot data/bss
9 * P: Boot-Parameters
10 * L: Kernel-Loader
11 *
12 * The Linux-Kernel image including the loader must be loaded
13 * to a position so that the kernel and the boot parameters
14 * can fit in the space before the load address.
15 * ______________________________________________________
16 * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|
17 * ^
18 * ^ Load address
19 * ______________________________________________________
20 * |___Linux-Kernel___|_P_|_L_|___________________________|
21 *
22 * The loader copies the parameter to the position that will
23 * be the end of the kernel and itself to the end of the
24 * parameter list.
25 */
26
27/* Make sure we have enough space for the 'uncompressor' */
28
29#define STACK_SIZE 32768
30#define HEAP_SIZE (131072*4)
31
32 # a2: Parameter list
33 # a3: Size of parameter list
34
35 .section .start, "ax"
36
37 .globl __start
38 /* this must be the first byte of the loader! */
39__start:
40 entry sp, 32 # we do not intend to return
41 _call0 _start
42__start_a0:
43 .align 4
44
45 .section .text, "ax"
46 .begin literal_prefix .text
47
48 /* put literals in here! */
49
50 .globl _start
51_start:
52
53 /* 'reset' window registers */
54
55 movi a4, 1
56 wsr a4, PS
57 rsync
58
59 rsr a5, WINDOWBASE
60 ssl a5
61 sll a4, a4
62 wsr a4, WINDOWSTART
63 rsync
64
65 movi a4, 0x00040000
66 wsr a4, PS
67 rsync
68
69 /* copy the loader to its address
70 * Note: The loader itself is a very small piece, so we assume we
71 * don't partially overlap. We also assume (even more important)
72 * that the kernel image is out of the way. Usually, when the
73 * load address of this image is not at an arbitrary address,
74 * but aligned to some 10K's we shouldn't overlap.
75 */
76
77 /* Note: The assembler cannot relax "addi a0, a0, ..." to an
78 l32r, so we load to a4 first. */
79
80 addi a4, a0, __start - __start_a0
81 mov a0, a4
82 movi a4, __start
83 movi a5, __reloc_end
84
85 # a0: address where this code has been loaded
86 # a4: compiled address of __start
87 # a5: compiled end address
88
89 mov.n a7, a0
90 mov.n a8, a4
91
921:
93 l32i a10, a7, 0
94 l32i a11, a7, 4
95 s32i a10, a8, 0
96 s32i a11, a8, 4
97 l32i a10, a7, 8
98 l32i a11, a7, 12
99 s32i a10, a8, 8
100 s32i a11, a8, 12
101 addi a8, a8, 16
102 addi a7, a7, 16
103 blt a8, a5, 1b
104
105
106 /* We have to flush and invalidate the caches here before we jump. */
107
108#if XCHAL_DCACHE_IS_WRITEBACK
109 dcache_writeback_all a5, a6
110#endif
111 icache_invalidate_all a5, a6
112
113 movi a11, _reloc
114 jx a11
115
116 .globl _reloc
117_reloc:
118
119 /* RedBoot is now at the end of the memory, so we don't have
120 * to copy the parameter list. Keep the code around; in case
121 * we need it again. */
122#if 0
123 # a0: load address
124 # a2: start address of parameter list
125 # a3: length of parameter list
126 # a4: __start
127
128 /* copy the parameter list out of the way */
129
130 movi a6, _param_start
131 add a3, a2, a3
1322:
133 l32i a8, a2, 0
134 s32i a8, a6, 0
135 addi a2, a2, 4
136 addi a6, a6, 4
137 blt a2, a3, 2b
138#endif
139
140 /* clear BSS section */
141 movi a6, __bss_start
142 movi a7, __bss_end
143 movi.n a5, 0
1443:
145 s32i a5, a6, 0
146 addi a6, a6, 4
147 blt a6, a7, 3b
148
149 movi a5, -16
150 movi a1, _stack + STACK_SIZE
151 and a1, a1, a5
152
153 /* Uncompress the kernel */
154
155 # a0: load address
156 # a2: boot parameter
157 # a4: __start
158
159 movi a3, __image_load
160 sub a4, a3, a4
161 add a8, a0, a4
162
163 # a1 Stack
164 # a8(a4) Load address of the image
165
166 movi a6, _image_start
167 movi a10, _image_end
168 movi a7, 0x1000000
169 sub a11, a10, a6
170 movi a9, complen
171 s32i a11, a9, 0
172
173 movi a0, 0
174
175 # a6 destination
176 # a7 maximum size of destination
177 # a8 source
178 # a9 ptr to length
179
180 .extern gunzip
181 movi a4, gunzip
182 beqz a4, 1f
183
184 callx4 a4
185
186 j 2f
187
188
189 # a6 destination start
190 # a7 maximum size of destination
191 # a8 source start
192 # a9 ptr to length
193 # a10 destination end
194
1951:
196 l32i a9, a8, 0
197 l32i a11, a8, 4
198 s32i a9, a6, 0
199 s32i a11, a6, 4
200 l32i a9, a8, 8
201 l32i a11, a8, 12
202 s32i a9, a6, 8
203 s32i a11, a6, 12
204 addi a6, a6, 16
205 addi a8, a8, 16
206 blt a6, a10, 1b
207
208
209 /* jump to the kernel */
2102:
211#if XCHAL_DCACHE_IS_WRITEBACK
212 dcache_writeback_all a5, a6
213#endif
214 icache_invalidate_all a5, a6
215
216 movi a5, __start
217 movi a3, boot_initrd_start
218 movi a4, boot_initrd_end
219 sub a3, a3, a5
220 sub a4, a4, a5
221 add a3, a0, a3
222 add a4, a0, a4
223
224 # a2 Boot parameter list
225 # a3 initrd_start (virtual load address)
226 # a4 initrd_end (virtual load address)
227
228 movi a0, _image_start
229 jx a0
230
231 .align 16
232 .data
233 .globl avail_ram
234avail_ram:
235 .long _heap
236 .globl end_avail
237end_avail:
238 .long _heap + HEAP_SIZE
239
240 .comm _stack, STACK_SIZE
241 .comm _heap, HEAP_SIZE
242
243 .globl end_avail
244 .comm complen, 4
245
246 .end literal_prefix
diff --git a/arch/xtensa/boot/include/zlib.h b/arch/xtensa/boot/include/zlib.h
new file mode 100644
index 000000000000..ea29b6237852
--- /dev/null
+++ b/arch/xtensa/boot/include/zlib.h
@@ -0,0 +1,433 @@
1/*
2 * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort
3 */
4/*
5 * This file is derived from zlib.h and zconf.h from the zlib-0.95
6 * distribution by Jean-loup Gailly and Mark Adler, with some additions
7 * by Paul Mackerras to aid in implementing Deflate compression and
8 * decompression for PPP packets.
9 */
10
11/*
12 * ==FILEVERSION 960122==
13 *
14 * This marker is used by the Linux installation script to determine
15 * whether an up-to-date version of this file is already installed.
16 */
17
18/* zlib.h -- interface of the 'zlib' general purpose compression library
19 version 0.95, Aug 16th, 1995.
20
21 Copyright (C) 1995 Jean-loup Gailly and Mark Adler
22
23 This software is provided 'as-is', without any express or implied
24 warranty. In no event will the authors be held liable for any damages
25 arising from the use of this software.
26
27 Permission is granted to anyone to use this software for any purpose,
28 including commercial applications, and to alter it and redistribute it
29 freely, subject to the following restrictions:
30
31 1. The origin of this software must not be misrepresented; you must not
32 claim that you wrote the original software. If you use this software
33 in a product, an acknowledgment in the product documentation would be
34 appreciated but is not required.
35 2. Altered source versions must be plainly marked as such, and must not be
36 misrepresented as being the original software.
37 3. This notice may not be removed or altered from any source distribution.
38
39 Jean-loup Gailly Mark Adler
40 gzip@prep.ai.mit.edu madler@alumni.caltech.edu
41 */
42
43#ifndef _ZLIB_H
44#define _ZLIB_H
45
46/* #include "zconf.h" */ /* included directly here */
47
48/* zconf.h -- configuration of the zlib compression library
49 * Copyright (C) 1995 Jean-loup Gailly.
50 * For conditions of distribution and use, see copyright notice in zlib.h
51 */
52
53/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
54
55/*
56 The library does not install any signal handler. It is recommended to
57 add at least a handler for SIGSEGV when decompressing; the library checks
58 the consistency of the input data whenever possible but may go nuts
59 for some forms of corrupted input.
60 */
61
62/*
63 * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
64 * than 64k bytes at a time (needed on systems with 16-bit int).
65 * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
66 * at addresses which are not a multiple of their size.
67 * Under DOS, -DFAR=far or -DFAR=__far may be needed.
68 */
69
70#ifndef STDC
71# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
72# define STDC
73# endif
74#endif
75
76#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
77# include <unix.h>
78#endif
79
80/* Maximum value for memLevel in deflateInit2 */
81#ifndef MAX_MEM_LEVEL
82# ifdef MAXSEG_64K
83# define MAX_MEM_LEVEL 8
84# else
85# define MAX_MEM_LEVEL 9
86# endif
87#endif
88
89#ifndef FAR
90# define FAR
91#endif
92
93/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
94#ifndef MAX_WBITS
95# define MAX_WBITS 15 /* 32K LZ77 window */
96#endif
97
98/* The memory requirements for deflate are (in bytes):
99 1 << (windowBits+2) + 1 << (memLevel+9)
100 that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
101 plus a few kilobytes for small objects. For example, if you want to reduce
102 the default memory requirements from 256K to 128K, compile with
103 make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
104 Of course this will generally degrade compression (there's no free lunch).
105
106 The memory requirements for inflate are (in bytes) 1 << windowBits
107 that is, 32K for windowBits=15 (default value) plus a few kilobytes
108 for small objects.
109*/
110
111 /* Type declarations */
112
113#ifndef OF /* function prototypes */
114# ifdef STDC
115# define OF(args) args
116# else
117# define OF(args) ()
118# endif
119#endif
120
121typedef unsigned char Byte; /* 8 bits */
122typedef unsigned int uInt; /* 16 bits or more */
123typedef unsigned long uLong; /* 32 bits or more */
124
125typedef Byte FAR Bytef;
126typedef char FAR charf;
127typedef int FAR intf;
128typedef uInt FAR uIntf;
129typedef uLong FAR uLongf;
130
131#ifdef STDC
132 typedef void FAR *voidpf;
133 typedef void *voidp;
134#else
135 typedef Byte FAR *voidpf;
136 typedef Byte *voidp;
137#endif
138
139/* end of original zconf.h */
140
141#define ZLIB_VERSION "0.95P"
142
143/*
144 The 'zlib' compression library provides in-memory compression and
145 decompression functions, including integrity checks of the uncompressed
146 data. This version of the library supports only one compression method
147 (deflation) but other algorithms may be added later and will have the same
148 stream interface.
149
150 For compression the application must provide the output buffer and
151 may optionally provide the input buffer for optimization. For decompression,
152 the application must provide the input buffer and may optionally provide
153 the output buffer for optimization.
154
155 Compression can be done in a single step if the buffers are large
156 enough (for example if an input file is mmap'ed), or can be done by
157 repeated calls of the compression function. In the latter case, the
158 application must provide more input and/or consume the output
159 (providing more output space) before each call.
160*/
161
162typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
163typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
164
165struct internal_state;
166
167typedef struct z_stream_s {
168 Bytef *next_in; /* next input byte */
169 uInt avail_in; /* number of bytes available at next_in */
170 uLong total_in; /* total nb of input bytes read so far */
171
172 Bytef *next_out; /* next output byte should be put there */
173 uInt avail_out; /* remaining free space at next_out */
174 uLong total_out; /* total nb of bytes output so far */
175
176 char *msg; /* last error message, NULL if no error */
177 struct internal_state FAR *state; /* not visible by applications */
178
179 alloc_func zalloc; /* used to allocate the internal state */
180 free_func zfree; /* used to free the internal state */
181 voidp opaque; /* private data object passed to zalloc and zfree */
182
183 Byte data_type; /* best guess about the data type: ascii or binary */
184
185} z_stream;
186
187/*
188 The application must update next_in and avail_in when avail_in has
189 dropped to zero. It must update next_out and avail_out when avail_out
190 has dropped to zero. The application must initialize zalloc, zfree and
191 opaque before calling the init function. All other fields are set by the
192 compression library and must not be updated by the application.
193
194 The opaque value provided by the application will be passed as the first
195 parameter for calls of zalloc and zfree. This can be useful for custom
196 memory management. The compression library attaches no meaning to the
197 opaque value.
198
199 zalloc must return Z_NULL if there is not enough memory for the object.
200 On 16-bit systems, the functions zalloc and zfree must be able to allocate
201 exactly 65536 bytes, but will not be required to allocate more than this
202 if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
203 pointers returned by zalloc for objects of exactly 65536 bytes *must*
204 have their offset normalized to zero. The default allocation function
205 provided by this library ensures this (see zutil.c). To reduce memory
206 requirements and avoid any allocation of 64K objects, at the expense of
207 compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
208
209 The fields total_in and total_out can be used for statistics or
210 progress reports. After compression, total_in holds the total size of
211 the uncompressed data and may be saved for use in the decompressor
212 (particularly if the decompressor wants to decompress everything in
213 a single step).
214*/
215
216 /* constants */
217
218#define Z_NO_FLUSH 0
219#define Z_PARTIAL_FLUSH 1
220#define Z_FULL_FLUSH 2
221#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
222#define Z_FINISH 4
223#define Z_PACKET_FLUSH 5
224/* See deflate() below for the usage of these constants */
225
226#define Z_OK 0
227#define Z_STREAM_END 1
228#define Z_ERRNO (-1)
229#define Z_STREAM_ERROR (-2)
230#define Z_DATA_ERROR (-3)
231#define Z_MEM_ERROR (-4)
232#define Z_BUF_ERROR (-5)
233/* error codes for the compression/decompression functions */
234
235#define Z_BEST_SPEED 1
236#define Z_BEST_COMPRESSION 9
237#define Z_DEFAULT_COMPRESSION (-1)
238/* compression levels */
239
240#define Z_FILTERED 1
241#define Z_HUFFMAN_ONLY 2
242#define Z_DEFAULT_STRATEGY 0
243
244#define Z_BINARY 0
245#define Z_ASCII 1
246#define Z_UNKNOWN 2
247/* Used to set the data_type field */
248
249#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
250
251extern char *zlib_version;
252/* The application can compare zlib_version and ZLIB_VERSION for consistency.
253 If the first character differs, the library code actually used is
254 not compatible with the zlib.h header file used by the application.
255 */
256
257 /* basic functions */
258
259extern int inflateInit OF((z_stream *strm));
260/*
261 Initializes the internal stream state for decompression. The fields
262 zalloc and zfree must be initialized before by the caller. If zalloc and
263 zfree are set to Z_NULL, inflateInit updates them to use default allocation
264 functions.
265
266 inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
267 enough memory. msg is set to null if there is no error message.
268 inflateInit does not perform any decompression: this will be done by
269 inflate().
270*/
271
272
273extern int inflate OF((z_stream *strm, int flush));
274/*
275 Performs one or both of the following actions:
276
277 - Decompress more input starting at next_in and update next_in and avail_in
278 accordingly. If not all input can be processed (because there is not
279 enough room in the output buffer), next_in is updated and processing
280 will resume at this point for the next call of inflate().
281
282 - Provide more output starting at next_out and update next_out and avail_out
283 accordingly. inflate() always provides as much output as possible
284 (until there is no more input data or no more space in the output buffer).
285
286 Before the call of inflate(), the application should ensure that at least
287 one of the actions is possible, by providing more input and/or consuming
288 more output, and updating the next_* and avail_* values accordingly.
289 The application can consume the uncompressed output when it wants, for
290 example when the output buffer is full (avail_out == 0), or after each
291 call of inflate().
292
293 If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
294 inflate flushes as much output as possible to the output buffer. The
295 flushing behavior of inflate is not specified for values of the flush
296 parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
297 current implementation actually flushes as much output as possible
298 anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
299 has been consumed, it is expecting to see the length field of a stored
300 block; if not, it returns Z_DATA_ERROR.
301
302 inflate() should normally be called until it returns Z_STREAM_END or an
303 error. However if all decompression is to be performed in a single step
304 (a single call of inflate), the parameter flush should be set to
305 Z_FINISH. In this case all pending input is processed and all pending
306 output is flushed; avail_out must be large enough to hold all the
307 uncompressed data. (The size of the uncompressed data may have been saved
308 by the compressor for this purpose.) The next operation on this stream must
309 be inflateEnd to deallocate the decompression state. The use of Z_FINISH
310 is never required, but can be used to inform inflate that a faster routine
311 may be used for the single inflate() call.
312
313 inflate() returns Z_OK if some progress has been made (more input
314 processed or more output produced), Z_STREAM_END if the end of the
315 compressed data has been reached and all uncompressed output has been
316 produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
317 the stream structure was inconsistent (for example if next_in or next_out
318 was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
319 progress is possible or if there was not enough room in the output buffer
320 when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
321 call inflateSync to look for a good compression block. */
322
323
324extern int inflateEnd OF((z_stream *strm));
325/*
326 All dynamically allocated data structures for this stream are freed.
327 This function discards any unprocessed input and does not flush any
328 pending output.
329
330 inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
331 was inconsistent. In the error case, msg may be set but then points to a
332 static string (which must not be deallocated).
333*/
334
335 /* advanced functions */
336
337extern int inflateInit2 OF((z_stream *strm,
338 int windowBits));
339/*
340 This is another version of inflateInit with more compression options. The
341 fields next_out, zalloc and zfree must be initialized before by the caller.
342
343 The windowBits parameter is the base two logarithm of the maximum window
344 size (the size of the history buffer). It should be in the range 8..15 for
345 this version of the library (the value 16 will be allowed soon). The
346 default value is 15 if inflateInit is used instead. If a compressed stream
347 with a larger window size is given as input, inflate() will return with
348 the error code Z_DATA_ERROR instead of trying to allocate a larger window.
349
350 If next_out is not null, the library will use this buffer for the history
351 buffer; the buffer must either be large enough to hold the entire output
352 data, or have at least 1<<windowBits bytes. If next_out is null, the
353 library will allocate its own buffer (and leave next_out null). next_in
354 need not be provided here but must be provided by the application for the
355 next call of inflate().
356
357 If the history buffer is provided by the application, next_out must
358 never be changed by the application since the decompressor maintains
359 history information inside this buffer from call to call; the application
360 can only reset next_out to the beginning of the history buffer when
361 avail_out is zero and all output has been consumed.
362
363 inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
364 not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
365 windowBits < 8). msg is set to null if there is no error message.
366 inflateInit2 does not perform any decompression: this will be done by
367 inflate().
368*/
369
370extern int inflateSync OF((z_stream *strm));
371/*
372 Skips invalid compressed data until the special marker (see deflate()
373 above) can be found, or until all available input is skipped. No output
374 is provided.
375
376 inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
377 if no more input was provided, Z_DATA_ERROR if no marker has been found,
378 or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
379 case, the application may save the current current value of total_in which
380 indicates where valid compressed data was found. In the error case, the
381 application may repeatedly call inflateSync, providing more input each time,
382 until success or end of the input data.
383*/
384
385extern int inflateReset OF((z_stream *strm));
386/*
387 This function is equivalent to inflateEnd followed by inflateInit,
388 but does not free and reallocate all the internal decompression state.
389 The stream will keep attributes that may have been set by inflateInit2.
390
391 inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
392 stream state was inconsistent (such as zalloc or state being NULL).
393*/
394
395extern int inflateIncomp OF((z_stream *strm));
396/*
397 This function adds the data at next_in (avail_in bytes) to the output
398 history without performing any output. There must be no pending output,
399 and the decompressor must be expecting to see the start of a block.
400 Calling this function is equivalent to decompressing a stored block
401 containing the data at next_in (except that the data is not output).
402*/
403
404 /* checksum functions */
405
406/*
407 This function is not related to compression but is exported
408 anyway because it might be useful in applications using the
409 compression library.
410*/
411
412extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
413
414/*
415 Update a running Adler-32 checksum with the bytes buf[0..len-1] and
416 return the updated checksum. If buf is NULL, this function returns
417 the required initial value for the checksum.
418 An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
419 much faster. Usage example:
420
421 uLong adler = adler32(0L, Z_NULL, 0);
422
423 while (read_buffer(buffer, length) != EOF) {
424 adler = adler32(adler, buffer, length);
425 }
426 if (adler != original_adler) error();
427*/
428
429#ifndef _Z_UTIL_H
430 struct internal_state {int dummy;}; /* hack for buggy compilers */
431#endif
432
433#endif /* _ZLIB_H */
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
new file mode 100644
index 000000000000..c0a74dc3a0df
--- /dev/null
+++ b/arch/xtensa/boot/lib/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for some libs needed by zImage.
3#
4
5
6lib-y := zlib.o zmem.o
diff --git a/arch/xtensa/boot/lib/memcpy.S b/arch/xtensa/boot/lib/memcpy.S
new file mode 100644
index 000000000000..a029f5df2d5c
--- /dev/null
+++ b/arch/xtensa/boot/lib/memcpy.S
@@ -0,0 +1,36 @@
1/*
2 * arch/xtensa/lib/memcpy.S
3 *
4 * ANSI C standard library function memcpy
5 *
6 * This file is subject to the terms and conditions of the GNU General
7 * Public License. See the file "COPYING" in the main directory of
8 * this archive for more details.
9 *
10 * Copyright (C) 2002 Tensilica Inc.
11 */
12
13#define _ASMLANGUAGE
14#include <xtensa/config/core.h>
15
16.text
17.align 4
18.global bcopy
19.type bcopy,@function
20bcopy:
21 movi a14, xthal_bcopy // a14 safe to use regardless of whether caller
22 // used call4 or call8 (can't have used call12)
23 jx a14 // let the Core HAL do the work
24
25.text
26.align 4
27.global memcpy
28.type memcpy,@function
29memcpy:
30.global memmove
31.type memmove,@function
32memmove:
33 movi a14, xthal_memcpy // a14 safe to use regardless of whether caller
34 // used call4 or call8 (can't have used call12)
35 jx a14 // let the Core HAL do the work
36
diff --git a/arch/xtensa/boot/lib/zlib.c b/arch/xtensa/boot/lib/zlib.c
new file mode 100644
index 000000000000..e3859f631077
--- /dev/null
+++ b/arch/xtensa/boot/lib/zlib.c
@@ -0,0 +1,2150 @@
1/*
2 * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort
3 */
4/*
5 * This file is derived from various .h and .c files from the zlib-0.95
6 * distribution by Jean-loup Gailly and Mark Adler, with some additions
7 * by Paul Mackerras to aid in implementing Deflate compression and
8 * decompression for PPP packets. See zlib.h for conditions of
9 * distribution and use.
10 *
11 * Changes that have been made include:
12 * - changed functions not used outside this file to "local"
13 * - added minCompression parameter to deflateInit2
14 * - added Z_PACKET_FLUSH (see zlib.h for details)
15 * - added inflateIncomp
16 *
17 */
18
19/*+++++*/
20/* zutil.h -- internal interface and configuration of the compression library
21 * Copyright (C) 1995 Jean-loup Gailly.
22 * For conditions of distribution and use, see copyright notice in zlib.h
23 */
24
25/* WARNING: this file should *not* be used by applications. It is
26 part of the implementation of the compression library and is
27 subject to change. Applications should only use zlib.h.
28 */
29
30/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
31
32#define _Z_UTIL_H
33
34#include "zlib.h"
35
36#ifndef local
37# define local static
38#endif
39/* compile with -Dlocal if your debugger can't find static symbols */
40
41#define FAR
42
43typedef unsigned char uch;
44typedef uch FAR uchf;
45typedef unsigned short ush;
46typedef ush FAR ushf;
47typedef unsigned long ulg;
48
49extern char *z_errmsg[]; /* indexed by 1-zlib_error */
50
51#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
52/* To be used only when the state is known to be valid */
53
54#ifndef NULL
55#define NULL ((void *) 0)
56#endif
57
58 /* common constants */
59
60#define DEFLATED 8
61
62#ifndef DEF_WBITS
63# define DEF_WBITS MAX_WBITS
64#endif
65/* default windowBits for decompression. MAX_WBITS is for compression only */
66
67#if MAX_MEM_LEVEL >= 8
68# define DEF_MEM_LEVEL 8
69#else
70# define DEF_MEM_LEVEL MAX_MEM_LEVEL
71#endif
72/* default memLevel */
73
74#define STORED_BLOCK 0
75#define STATIC_TREES 1
76#define DYN_TREES 2
77/* The three kinds of block type */
78
79#define MIN_MATCH 3
80#define MAX_MATCH 258
81/* The minimum and maximum match lengths */
82
83 /* functions */
84
85#include <linux/string.h>
86#define zmemcpy memcpy
87#define zmemzero(dest, len) memset(dest, 0, len)
88
89/* Diagnostic functions */
90#ifdef DEBUG_ZLIB
91# include <stdio.h>
92# ifndef verbose
93# define verbose 0
94# endif
95# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
96# define Trace(x) fprintf x
97# define Tracev(x) {if (verbose) fprintf x ;}
98# define Tracevv(x) {if (verbose>1) fprintf x ;}
99# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
100# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
101#else
102# define Assert(cond,msg)
103# define Trace(x)
104# define Tracev(x)
105# define Tracevv(x)
106# define Tracec(c,x)
107# define Tracecv(c,x)
108#endif
109
110
111typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
112
113/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
114/* void zcfree OF((voidpf opaque, voidpf ptr)); */
115
116#define ZALLOC(strm, items, size) \
117 (*((strm)->zalloc))((strm)->opaque, (items), (size))
118#define ZFREE(strm, addr, size) \
119 (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
120#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
121
122/* deflate.h -- internal compression state
123 * Copyright (C) 1995 Jean-loup Gailly
124 * For conditions of distribution and use, see copyright notice in zlib.h
125 */
126
127/* WARNING: this file should *not* be used by applications. It is
128 part of the implementation of the compression library and is
129 subject to change. Applications should only use zlib.h.
130 */
131
132/*+++++*/
133/* infblock.h -- header to use infblock.c
134 * Copyright (C) 1995 Mark Adler
135 * For conditions of distribution and use, see copyright notice in zlib.h
136 */
137
138/* WARNING: this file should *not* be used by applications. It is
139 part of the implementation of the compression library and is
140 subject to change. Applications should only use zlib.h.
141 */
142
143struct inflate_blocks_state;
144typedef struct inflate_blocks_state FAR inflate_blocks_statef;
145
146local inflate_blocks_statef * inflate_blocks_new OF((
147 z_stream *z,
148 check_func c, /* check function */
149 uInt w)); /* window size */
150
151local int inflate_blocks OF((
152 inflate_blocks_statef *,
153 z_stream *,
154 int)); /* initial return code */
155
156local void inflate_blocks_reset OF((
157 inflate_blocks_statef *,
158 z_stream *,
159 uLongf *)); /* check value on output */
160
161local int inflate_blocks_free OF((
162 inflate_blocks_statef *,
163 z_stream *,
164 uLongf *)); /* check value on output */
165
166local int inflate_addhistory OF((
167 inflate_blocks_statef *,
168 z_stream *));
169
170local int inflate_packet_flush OF((
171 inflate_blocks_statef *));
172
173/*+++++*/
174/* inftrees.h -- header to use inftrees.c
175 * Copyright (C) 1995 Mark Adler
176 * For conditions of distribution and use, see copyright notice in zlib.h
177 */
178
179/* WARNING: this file should *not* be used by applications. It is
180 part of the implementation of the compression library and is
181 subject to change. Applications should only use zlib.h.
182 */
183
184/* Huffman code lookup table entry--this entry is four bytes for machines
185 that have 16-bit pointers (e.g. PC's in the small or medium model). */
186
187typedef struct inflate_huft_s FAR inflate_huft;
188
189struct inflate_huft_s {
190 union {
191 struct {
192 Byte Exop; /* number of extra bits or operation */
193 Byte Bits; /* number of bits in this code or subcode */
194 } what;
195 uInt Nalloc; /* number of these allocated here */
196 Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
197 } word; /* 16-bit, 8 bytes for 32-bit machines) */
198 union {
199 uInt Base; /* literal, length base, or distance base */
200 inflate_huft *Next; /* pointer to next level of table */
201 } more;
202};
203
204#ifdef DEBUG_ZLIB
205 local uInt inflate_hufts;
206#endif
207
208local int inflate_trees_bits OF((
209 uIntf *, /* 19 code lengths */
210 uIntf *, /* bits tree desired/actual depth */
211 inflate_huft * FAR *, /* bits tree result */
212 z_stream *)); /* for zalloc, zfree functions */
213
214local int inflate_trees_dynamic OF((
215 uInt, /* number of literal/length codes */
216 uInt, /* number of distance codes */
217 uIntf *, /* that many (total) code lengths */
218 uIntf *, /* literal desired/actual bit depth */
219 uIntf *, /* distance desired/actual bit depth */
220 inflate_huft * FAR *, /* literal/length tree result */
221 inflate_huft * FAR *, /* distance tree result */
222 z_stream *)); /* for zalloc, zfree functions */
223
224local int inflate_trees_fixed OF((
225 uIntf *, /* literal desired/actual bit depth */
226 uIntf *, /* distance desired/actual bit depth */
227 inflate_huft * FAR *, /* literal/length tree result */
228 inflate_huft * FAR *)); /* distance tree result */
229
230local int inflate_trees_free OF((
231 inflate_huft *, /* tables to free */
232 z_stream *)); /* for zfree function */
233
234
235/*+++++*/
236/* infcodes.h -- header to use infcodes.c
237 * Copyright (C) 1995 Mark Adler
238 * For conditions of distribution and use, see copyright notice in zlib.h
239 */
240
241/* WARNING: this file should *not* be used by applications. It is
242 part of the implementation of the compression library and is
243 subject to change. Applications should only use zlib.h.
244 */
245
246struct inflate_codes_state;
247typedef struct inflate_codes_state FAR inflate_codes_statef;
248
249local inflate_codes_statef *inflate_codes_new OF((
250 uInt, uInt,
251 inflate_huft *, inflate_huft *,
252 z_stream *));
253
254local int inflate_codes OF((
255 inflate_blocks_statef *,
256 z_stream *,
257 int));
258
259local void inflate_codes_free OF((
260 inflate_codes_statef *,
261 z_stream *));
262
263
264/*+++++*/
265/* inflate.c -- zlib interface to inflate modules
266 * Copyright (C) 1995 Mark Adler
267 * For conditions of distribution and use, see copyright notice in zlib.h
268 */
269
270/* inflate private state */
271struct internal_state {
272
273 /* mode */
274 enum {
275 METHOD, /* waiting for method byte */
276 FLAG, /* waiting for flag byte */
277 BLOCKS, /* decompressing blocks */
278 CHECK4, /* four check bytes to go */
279 CHECK3, /* three check bytes to go */
280 CHECK2, /* two check bytes to go */
281 CHECK1, /* one check byte to go */
282 DONE, /* finished check, done */
283 BAD} /* got an error--stay here */
284 mode; /* current inflate mode */
285
286 /* mode dependent information */
287 union {
288 uInt method; /* if FLAGS, method byte */
289 struct {
290 uLong was; /* computed check value */
291 uLong need; /* stream check value */
292 } check; /* if CHECK, check values to compare */
293 uInt marker; /* if BAD, inflateSync's marker bytes count */
294 } sub; /* submode */
295
296 /* mode independent information */
297 int nowrap; /* flag for no wrapper */
298 uInt wbits; /* log2(window size) (8..15, defaults to 15) */
299 inflate_blocks_statef
300 *blocks; /* current inflate_blocks state */
301
302};
303
304
305int inflateReset(z)
306z_stream *z;
307{
308 uLong c;
309
310 if (z == Z_NULL || z->state == Z_NULL)
311 return Z_STREAM_ERROR;
312 z->total_in = z->total_out = 0;
313 z->msg = Z_NULL;
314 z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
315 inflate_blocks_reset(z->state->blocks, z, &c);
316 Trace((stderr, "inflate: reset\n"));
317 return Z_OK;
318}
319
320
321int inflateEnd(z)
322z_stream *z;
323{
324 uLong c;
325
326 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
327 return Z_STREAM_ERROR;
328 if (z->state->blocks != Z_NULL)
329 inflate_blocks_free(z->state->blocks, z, &c);
330 ZFREE(z, z->state, sizeof(struct internal_state));
331 z->state = Z_NULL;
332 Trace((stderr, "inflate: end\n"));
333 return Z_OK;
334}
335
336
337int inflateInit2(z, w)
338z_stream *z;
339int w;
340{
341 /* initialize state */
342 if (z == Z_NULL)
343 return Z_STREAM_ERROR;
344/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
345/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
346 if ((z->state = (struct internal_state FAR *)
347 ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
348 return Z_MEM_ERROR;
349 z->state->blocks = Z_NULL;
350
351 /* handle undocumented nowrap option (no zlib header or check) */
352 z->state->nowrap = 0;
353 if (w < 0)
354 {
355 w = - w;
356 z->state->nowrap = 1;
357 }
358
359 /* set window size */
360 if (w < 8 || w > 15)
361 {
362 inflateEnd(z);
363 return Z_STREAM_ERROR;
364 }
365 z->state->wbits = (uInt)w;
366
367 /* create inflate_blocks state */
368 if ((z->state->blocks =
369 inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
370 == Z_NULL)
371 {
372 inflateEnd(z);
373 return Z_MEM_ERROR;
374 }
375 Trace((stderr, "inflate: allocated\n"));
376
377 /* reset state */
378 inflateReset(z);
379 return Z_OK;
380}
381
382
383int inflateInit(z)
384z_stream *z;
385{
386 return inflateInit2(z, DEF_WBITS);
387}
388
389
390#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
391#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
392
393int inflate(z, f)
394z_stream *z;
395int f;
396{
397 int r;
398 uInt b;
399
400 if (z == Z_NULL || z->next_in == Z_NULL)
401 return Z_STREAM_ERROR;
402 r = Z_BUF_ERROR;
403 while (1) switch (z->state->mode)
404 {
405 case METHOD:
406 NEEDBYTE
407 if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
408 {
409 z->state->mode = BAD;
410 z->msg = "unknown compression method";
411 z->state->sub.marker = 5; /* can't try inflateSync */
412 break;
413 }
414 if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
415 {
416 z->state->mode = BAD;
417 z->msg = "invalid window size";
418 z->state->sub.marker = 5; /* can't try inflateSync */
419 break;
420 }
421 z->state->mode = FLAG;
422 case FLAG:
423 NEEDBYTE
424 if ((b = NEXTBYTE) & 0x20)
425 {
426 z->state->mode = BAD;
427 z->msg = "invalid reserved bit";
428 z->state->sub.marker = 5; /* can't try inflateSync */
429 break;
430 }
431 if (((z->state->sub.method << 8) + b) % 31)
432 {
433 z->state->mode = BAD;
434 z->msg = "incorrect header check";
435 z->state->sub.marker = 5; /* can't try inflateSync */
436 break;
437 }
438 Trace((stderr, "inflate: zlib header ok\n"));
439 z->state->mode = BLOCKS;
440 case BLOCKS:
441 r = inflate_blocks(z->state->blocks, z, r);
442 if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
443 r = inflate_packet_flush(z->state->blocks);
444 if (r == Z_DATA_ERROR)
445 {
446 z->state->mode = BAD;
447 z->state->sub.marker = 0; /* can try inflateSync */
448 break;
449 }
450 if (r != Z_STREAM_END)
451 return r;
452 r = Z_OK;
453 inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
454 if (z->state->nowrap)
455 {
456 z->state->mode = DONE;
457 break;
458 }
459 z->state->mode = CHECK4;
460 case CHECK4:
461 NEEDBYTE
462 z->state->sub.check.need = (uLong)NEXTBYTE << 24;
463 z->state->mode = CHECK3;
464 case CHECK3:
465 NEEDBYTE
466 z->state->sub.check.need += (uLong)NEXTBYTE << 16;
467 z->state->mode = CHECK2;
468 case CHECK2:
469 NEEDBYTE
470 z->state->sub.check.need += (uLong)NEXTBYTE << 8;
471 z->state->mode = CHECK1;
472 case CHECK1:
473 NEEDBYTE
474 z->state->sub.check.need += (uLong)NEXTBYTE;
475
476 if (z->state->sub.check.was != z->state->sub.check.need)
477 {
478 z->state->mode = BAD;
479 z->msg = "incorrect data check";
480 z->state->sub.marker = 5; /* can't try inflateSync */
481 break;
482 }
483 Trace((stderr, "inflate: zlib check ok\n"));
484 z->state->mode = DONE;
485 case DONE:
486 return Z_STREAM_END;
487 case BAD:
488 return Z_DATA_ERROR;
489 default:
490 return Z_STREAM_ERROR;
491 }
492
493 empty:
494 if (f != Z_PACKET_FLUSH)
495 return r;
496 z->state->mode = BAD;
497 z->state->sub.marker = 0; /* can try inflateSync */
498 return Z_DATA_ERROR;
499}
500
501/*
502 * This subroutine adds the data at next_in/avail_in to the output history
503 * without performing any output. The output buffer must be "caught up";
504 * i.e. no pending output (hence s->read equals s->write), and the state must
505 * be BLOCKS (i.e. we should be willing to see the start of a series of
506 * BLOCKS). On exit, the output will also be caught up, and the checksum
507 * will have been updated if need be.
508 */
509
510int inflateIncomp(z)
511z_stream *z;
512{
513 if (z->state->mode != BLOCKS)
514 return Z_DATA_ERROR;
515 return inflate_addhistory(z->state->blocks, z);
516}
517
518
519int inflateSync(z)
520z_stream *z;
521{
522 uInt n; /* number of bytes to look at */
523 Bytef *p; /* pointer to bytes */
524 uInt m; /* number of marker bytes found in a row */
525 uLong r, w; /* temporaries to save total_in and total_out */
526
527 /* set up */
528 if (z == Z_NULL || z->state == Z_NULL)
529 return Z_STREAM_ERROR;
530 if (z->state->mode != BAD)
531 {
532 z->state->mode = BAD;
533 z->state->sub.marker = 0;
534 }
535 if ((n = z->avail_in) == 0)
536 return Z_BUF_ERROR;
537 p = z->next_in;
538 m = z->state->sub.marker;
539
540 /* search */
541 while (n && m < 4)
542 {
543 if (*p == (Byte)(m < 2 ? 0 : 0xff))
544 m++;
545 else if (*p)
546 m = 0;
547 else
548 m = 4 - m;
549 p++, n--;
550 }
551
552 /* restore */
553 z->total_in += p - z->next_in;
554 z->next_in = p;
555 z->avail_in = n;
556 z->state->sub.marker = m;
557
558 /* return no joy or set up to restart on a new block */
559 if (m != 4)
560 return Z_DATA_ERROR;
561 r = z->total_in; w = z->total_out;
562 inflateReset(z);
563 z->total_in = r; z->total_out = w;
564 z->state->mode = BLOCKS;
565 return Z_OK;
566}
567
568#undef NEEDBYTE
569#undef NEXTBYTE
570
571/*+++++*/
572/* infutil.h -- types and macros common to blocks and codes
573 * Copyright (C) 1995 Mark Adler
574 * For conditions of distribution and use, see copyright notice in zlib.h
575 */
576
577/* WARNING: this file should *not* be used by applications. It is
578 part of the implementation of the compression library and is
579 subject to change. Applications should only use zlib.h.
580 */
581
582/* inflate blocks semi-private state */
583struct inflate_blocks_state {
584
585 /* mode */
586 enum {
587 TYPE, /* get type bits (3, including end bit) */
588 LENS, /* get lengths for stored */
589 STORED, /* processing stored block */
590 TABLE, /* get table lengths */
591 BTREE, /* get bit lengths tree for a dynamic block */
592 DTREE, /* get length, distance trees for a dynamic block */
593 CODES, /* processing fixed or dynamic block */
594 DRY, /* output remaining window bytes */
595 DONEB, /* finished last block, done */
596 BADB} /* got a data error--stuck here */
597 mode; /* current inflate_block mode */
598
599 /* mode dependent information */
600 union {
601 uInt left; /* if STORED, bytes left to copy */
602 struct {
603 uInt table; /* table lengths (14 bits) */
604 uInt index; /* index into blens (or border) */
605 uIntf *blens; /* bit lengths of codes */
606 uInt bb; /* bit length tree depth */
607 inflate_huft *tb; /* bit length decoding tree */
608 int nblens; /* # elements allocated at blens */
609 } trees; /* if DTREE, decoding info for trees */
610 struct {
611 inflate_huft *tl, *td; /* trees to free */
612 inflate_codes_statef
613 *codes;
614 } decode; /* if CODES, current state */
615 } sub; /* submode */
616 uInt last; /* true if this block is the last block */
617
618 /* mode independent information */
619 uInt bitk; /* bits in bit buffer */
620 uLong bitb; /* bit buffer */
621 Bytef *window; /* sliding window */
622 Bytef *end; /* one byte after sliding window */
623 Bytef *read; /* window read pointer */
624 Bytef *write; /* window write pointer */
625 check_func checkfn; /* check function */
626 uLong check; /* check on output */
627
628};
629
630
631/* defines for inflate input/output */
632/* update pointers and return */
633#define UPDBITS {s->bitb=b;s->bitk=k;}
634#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
635#define UPDOUT {s->write=q;}
636#define UPDATE {UPDBITS UPDIN UPDOUT}
637#define LEAVE {UPDATE return inflate_flush(s,z,r);}
638/* get bytes and bits */
639#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
640#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
641#define NEXTBYTE (n--,*p++)
642#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
643#define DUMPBITS(j) {b>>=(j);k-=(j);}
644/* output bytes */
645#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
646#define LOADOUT {q=s->write;m=WAVAIL;}
647#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
648#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
649#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
650#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
651/* load local pointers */
652#define LOAD {LOADIN LOADOUT}
653
654/*
655 * The IBM 150 firmware munges the data right after _etext[]. This
656 * protects it. -- Cort
657 */
658local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
659/* And'ing with mask[n] masks the lower n bits */
660local uInt inflate_mask[] = {
661 0x0000,
662 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
663 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
664};
665
666/* copy as much as possible from the sliding window to the output area */
667local int inflate_flush OF((
668 inflate_blocks_statef *,
669 z_stream *,
670 int));
671
672/*+++++*/
673/* inffast.h -- header to use inffast.c
674 * Copyright (C) 1995 Mark Adler
675 * For conditions of distribution and use, see copyright notice in zlib.h
676 */
677
678/* WARNING: this file should *not* be used by applications. It is
679 part of the implementation of the compression library and is
680 subject to change. Applications should only use zlib.h.
681 */
682
683local int inflate_fast OF((
684 uInt,
685 uInt,
686 inflate_huft *,
687 inflate_huft *,
688 inflate_blocks_statef *,
689 z_stream *));
690
691
692/*+++++*/
693/* infblock.c -- interpret and process block types to last block
694 * Copyright (C) 1995 Mark Adler
695 * For conditions of distribution and use, see copyright notice in zlib.h
696 */
697
698/* Table for deflate from PKZIP's appnote.txt. */
699local uInt border[] = { /* Order of the bit length code lengths */
700 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
701
702/*
703 Notes beyond the 1.93a appnote.txt:
704
705 1. Distance pointers never point before the beginning of the output
706 stream.
707 2. Distance pointers can point back across blocks, up to 32k away.
708 3. There is an implied maximum of 7 bits for the bit length table and
709 15 bits for the actual data.
710 4. If only one code exists, then it is encoded using one bit. (Zero
711 would be more efficient, but perhaps a little confusing.) If two
712 codes exist, they are coded using one bit each (0 and 1).
713 5. There is no way of sending zero distance codes--a dummy must be
714 sent if there are none. (History: a pre 2.0 version of PKZIP would
715 store blocks with no distance codes, but this was discovered to be
716 too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
717 zero distance codes, which is sent as one code of zero bits in
718 length.
719 6. There are up to 286 literal/length codes. Code 256 represents the
720 end-of-block. Note however that the static length tree defines
721 288 codes just to fill out the Huffman codes. Codes 286 and 287
722 cannot be used though, since there is no length base or extra bits
723 defined for them. Similarily, there are up to 30 distance codes.
724 However, static trees define 32 codes (all 5 bits) to fill out the
725 Huffman codes, but the last two had better not show up in the data.
726 7. Unzip can check dynamic Huffman blocks for complete code sets.
727 The exception is that a single code would not be complete (see #4).
728 8. The five bits following the block type is really the number of
729 literal codes sent minus 257.
730 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
731 (1+6+6). Therefore, to output three times the length, you output
732 three codes (1+1+1), whereas to output four times the same length,
733 you only need two codes (1+3). Hmm.
734 10. In the tree reconstruction algorithm, Code = Code + Increment
735 only if BitLength(i) is not zero. (Pretty obvious.)
736 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
737 12. Note: length code 284 can represent 227-258, but length code 285
738 really is 258. The last length deserves its own, short code
739 since it gets used a lot in very redundant files. The length
740 258 is special since 258 - 3 (the min match length) is 255.
741 13. The literal/length and distance code bit lengths are read as a
742 single stream of lengths. It is possible (and advantageous) for
743 a repeat code (16, 17, or 18) to go across the boundary between
744 the two sets of lengths.
745 */
746
747
748local void inflate_blocks_reset(s, z, c)
749inflate_blocks_statef *s;
750z_stream *z;
751uLongf *c;
752{
753 if (s->checkfn != Z_NULL)
754 *c = s->check;
755 if (s->mode == BTREE || s->mode == DTREE)
756 ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
757 if (s->mode == CODES)
758 {
759 inflate_codes_free(s->sub.decode.codes, z);
760 inflate_trees_free(s->sub.decode.td, z);
761 inflate_trees_free(s->sub.decode.tl, z);
762 }
763 s->mode = TYPE;
764 s->bitk = 0;
765 s->bitb = 0;
766 s->read = s->write = s->window;
767 if (s->checkfn != Z_NULL)
768 s->check = (*s->checkfn)(0L, Z_NULL, 0);
769 Trace((stderr, "inflate: blocks reset\n"));
770}
771
772
773local inflate_blocks_statef *inflate_blocks_new(z, c, w)
774z_stream *z;
775check_func c;
776uInt w;
777{
778 inflate_blocks_statef *s;
779
780 if ((s = (inflate_blocks_statef *)ZALLOC
781 (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
782 return s;
783 if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
784 {
785 ZFREE(z, s, sizeof(struct inflate_blocks_state));
786 return Z_NULL;
787 }
788 s->end = s->window + w;
789 s->checkfn = c;
790 s->mode = TYPE;
791 Trace((stderr, "inflate: blocks allocated\n"));
792 inflate_blocks_reset(s, z, &s->check);
793 return s;
794}
795
796
797local int inflate_blocks(s, z, r)
798inflate_blocks_statef *s;
799z_stream *z;
800int r;
801{
802 uInt t; /* temporary storage */
803 uLong b; /* bit buffer */
804 uInt k; /* bits in bit buffer */
805 Bytef *p; /* input data pointer */
806 uInt n; /* bytes available there */
807 Bytef *q; /* output window write pointer */
808 uInt m; /* bytes to end of window or read pointer */
809
810 /* copy input/output information to locals (UPDATE macro restores) */
811 LOAD
812
813 /* process input based on current state */
814 while (1) switch (s->mode)
815 {
816 case TYPE:
817 NEEDBITS(3)
818 t = (uInt)b & 7;
819 s->last = t & 1;
820 switch (t >> 1)
821 {
822 case 0: /* stored */
823 Trace((stderr, "inflate: stored block%s\n",
824 s->last ? " (last)" : ""));
825 DUMPBITS(3)
826 t = k & 7; /* go to byte boundary */
827 DUMPBITS(t)
828 s->mode = LENS; /* get length of stored block */
829 break;
830 case 1: /* fixed */
831 Trace((stderr, "inflate: fixed codes block%s\n",
832 s->last ? " (last)" : ""));
833 {
834 uInt bl, bd;
835 inflate_huft *tl, *td;
836
837 inflate_trees_fixed(&bl, &bd, &tl, &td);
838 s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
839 if (s->sub.decode.codes == Z_NULL)
840 {
841 r = Z_MEM_ERROR;
842 LEAVE
843 }
844 s->sub.decode.tl = Z_NULL; /* don't try to free these */
845 s->sub.decode.td = Z_NULL;
846 }
847 DUMPBITS(3)
848 s->mode = CODES;
849 break;
850 case 2: /* dynamic */
851 Trace((stderr, "inflate: dynamic codes block%s\n",
852 s->last ? " (last)" : ""));
853 DUMPBITS(3)
854 s->mode = TABLE;
855 break;
856 case 3: /* illegal */
857 DUMPBITS(3)
858 s->mode = BADB;
859 z->msg = "invalid block type";
860 r = Z_DATA_ERROR;
861 LEAVE
862 }
863 break;
864 case LENS:
865 NEEDBITS(32)
866 if (((~b) >> 16) != (b & 0xffff))
867 {
868 s->mode = BADB;
869 z->msg = "invalid stored block lengths";
870 r = Z_DATA_ERROR;
871 LEAVE
872 }
873 s->sub.left = (uInt)b & 0xffff;
874 b = k = 0; /* dump bits */
875 Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
876 s->mode = s->sub.left ? STORED : TYPE;
877 break;
878 case STORED:
879 if (n == 0)
880 LEAVE
881 NEEDOUT
882 t = s->sub.left;
883 if (t > n) t = n;
884 if (t > m) t = m;
885 zmemcpy(q, p, t);
886 p += t; n -= t;
887 q += t; m -= t;
888 if ((s->sub.left -= t) != 0)
889 break;
890 Tracev((stderr, "inflate: stored end, %lu total out\n",
891 z->total_out + (q >= s->read ? q - s->read :
892 (s->end - s->read) + (q - s->window))));
893 s->mode = s->last ? DRY : TYPE;
894 break;
895 case TABLE:
896 NEEDBITS(14)
897 s->sub.trees.table = t = (uInt)b & 0x3fff;
898#ifndef PKZIP_BUG_WORKAROUND
899 if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
900 {
901 s->mode = BADB;
902 z->msg = "too many length or distance symbols";
903 r = Z_DATA_ERROR;
904 LEAVE
905 }
906#endif
907 t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
908 if (t < 19)
909 t = 19;
910 if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
911 {
912 r = Z_MEM_ERROR;
913 LEAVE
914 }
915 s->sub.trees.nblens = t;
916 DUMPBITS(14)
917 s->sub.trees.index = 0;
918 Tracev((stderr, "inflate: table sizes ok\n"));
919 s->mode = BTREE;
920 case BTREE:
921 while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
922 {
923 NEEDBITS(3)
924 s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
925 DUMPBITS(3)
926 }
927 while (s->sub.trees.index < 19)
928 s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
929 s->sub.trees.bb = 7;
930 t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
931 &s->sub.trees.tb, z);
932 if (t != Z_OK)
933 {
934 r = t;
935 if (r == Z_DATA_ERROR)
936 s->mode = BADB;
937 LEAVE
938 }
939 s->sub.trees.index = 0;
940 Tracev((stderr, "inflate: bits tree ok\n"));
941 s->mode = DTREE;
942 case DTREE:
943 while (t = s->sub.trees.table,
944 s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
945 {
946 inflate_huft *h;
947 uInt i, j, c;
948
949 t = s->sub.trees.bb;
950 NEEDBITS(t)
951 h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
952 t = h->word.what.Bits;
953 c = h->more.Base;
954 if (c < 16)
955 {
956 DUMPBITS(t)
957 s->sub.trees.blens[s->sub.trees.index++] = c;
958 }
959 else /* c == 16..18 */
960 {
961 i = c == 18 ? 7 : c - 14;
962 j = c == 18 ? 11 : 3;
963 NEEDBITS(t + i)
964 DUMPBITS(t)
965 j += (uInt)b & inflate_mask[i];
966 DUMPBITS(i)
967 i = s->sub.trees.index;
968 t = s->sub.trees.table;
969 if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
970 (c == 16 && i < 1))
971 {
972 s->mode = BADB;
973 z->msg = "invalid bit length repeat";
974 r = Z_DATA_ERROR;
975 LEAVE
976 }
977 c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
978 do {
979 s->sub.trees.blens[i++] = c;
980 } while (--j);
981 s->sub.trees.index = i;
982 }
983 }
984 inflate_trees_free(s->sub.trees.tb, z);
985 s->sub.trees.tb = Z_NULL;
986 {
987 uInt bl, bd;
988 inflate_huft *tl, *td;
989 inflate_codes_statef *c;
990
991 bl = 9; /* must be <= 9 for lookahead assumptions */
992 bd = 6; /* must be <= 9 for lookahead assumptions */
993 t = s->sub.trees.table;
994 t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
995 s->sub.trees.blens, &bl, &bd, &tl, &td, z);
996 if (t != Z_OK)
997 {
998 if (t == (uInt)Z_DATA_ERROR)
999 s->mode = BADB;
1000 r = t;
1001 LEAVE
1002 }
1003 Tracev((stderr, "inflate: trees ok\n"));
1004 if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
1005 {
1006 inflate_trees_free(td, z);
1007 inflate_trees_free(tl, z);
1008 r = Z_MEM_ERROR;
1009 LEAVE
1010 }
1011 ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
1012 s->sub.decode.codes = c;
1013 s->sub.decode.tl = tl;
1014 s->sub.decode.td = td;
1015 }
1016 s->mode = CODES;
1017 case CODES:
1018 UPDATE
1019 if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
1020 return inflate_flush(s, z, r);
1021 r = Z_OK;
1022 inflate_codes_free(s->sub.decode.codes, z);
1023 inflate_trees_free(s->sub.decode.td, z);
1024 inflate_trees_free(s->sub.decode.tl, z);
1025 LOAD
1026 Tracev((stderr, "inflate: codes end, %lu total out\n",
1027 z->total_out + (q >= s->read ? q - s->read :
1028 (s->end - s->read) + (q - s->window))));
1029 if (!s->last)
1030 {
1031 s->mode = TYPE;
1032 break;
1033 }
1034 if (k > 7) /* return unused byte, if any */
1035 {
1036 Assert(k < 16, "inflate_codes grabbed too many bytes")
1037 k -= 8;
1038 n++;
1039 p--; /* can always return one */
1040 }
1041 s->mode = DRY;
1042 case DRY:
1043 FLUSH
1044 if (s->read != s->write)
1045 LEAVE
1046 s->mode = DONEB;
1047 case DONEB:
1048 r = Z_STREAM_END;
1049 LEAVE
1050 case BADB:
1051 r = Z_DATA_ERROR;
1052 LEAVE
1053 default:
1054 r = Z_STREAM_ERROR;
1055 LEAVE
1056 }
1057}
1058
1059
1060local int inflate_blocks_free(s, z, c)
1061inflate_blocks_statef *s;
1062z_stream *z;
1063uLongf *c;
1064{
1065 inflate_blocks_reset(s, z, c);
1066 ZFREE(z, s->window, s->end - s->window);
1067 ZFREE(z, s, sizeof(struct inflate_blocks_state));
1068 Trace((stderr, "inflate: blocks freed\n"));
1069 return Z_OK;
1070}
1071
1072/*
1073 * This subroutine adds the data at next_in/avail_in to the output history
1074 * without performing any output. The output buffer must be "caught up";
1075 * i.e. no pending output (hence s->read equals s->write), and the state must
1076 * be BLOCKS (i.e. we should be willing to see the start of a series of
1077 * BLOCKS). On exit, the output will also be caught up, and the checksum
1078 * will have been updated if need be.
1079 */
1080local int inflate_addhistory(s, z)
1081inflate_blocks_statef *s;
1082z_stream *z;
1083{
1084 uLong b; /* bit buffer */ /* NOT USED HERE */
1085 uInt k; /* bits in bit buffer */ /* NOT USED HERE */
1086 uInt t; /* temporary storage */
1087 Bytef *p; /* input data pointer */
1088 uInt n; /* bytes available there */
1089 Bytef *q; /* output window write pointer */
1090 uInt m; /* bytes to end of window or read pointer */
1091
1092 if (s->read != s->write)
1093 return Z_STREAM_ERROR;
1094 if (s->mode != TYPE)
1095 return Z_DATA_ERROR;
1096
1097 /* we're ready to rock */
1098 LOAD
1099 /* while there is input ready, copy to output buffer, moving
1100 * pointers as needed.
1101 */
1102 while (n) {
1103 t = n; /* how many to do */
1104 /* is there room until end of buffer? */
1105 if (t > m) t = m;
1106 /* update check information */
1107 if (s->checkfn != Z_NULL)
1108 s->check = (*s->checkfn)(s->check, q, t);
1109 zmemcpy(q, p, t);
1110 q += t;
1111 p += t;
1112 n -= t;
1113 z->total_out += t;
1114 s->read = q; /* drag read pointer forward */
1115/* WRAP */ /* expand WRAP macro by hand to handle s->read */
1116 if (q == s->end) {
1117 s->read = q = s->window;
1118 m = WAVAIL;
1119 }
1120 }
1121 UPDATE
1122 return Z_OK;
1123}
1124
1125
1126/*
1127 * At the end of a Deflate-compressed PPP packet, we expect to have seen
1128 * a `stored' block type value but not the (zero) length bytes.
1129 */
1130local int inflate_packet_flush(s)
1131 inflate_blocks_statef *s;
1132{
1133 if (s->mode != LENS)
1134 return Z_DATA_ERROR;
1135 s->mode = TYPE;
1136 return Z_OK;
1137}
1138
1139
1140/*+++++*/
1141/* inftrees.c -- generate Huffman trees for efficient decoding
1142 * Copyright (C) 1995 Mark Adler
1143 * For conditions of distribution and use, see copyright notice in zlib.h
1144 */
1145
1146/* simplify the use of the inflate_huft type with some defines */
1147#define base more.Base
1148#define next more.Next
1149#define exop word.what.Exop
1150#define bits word.what.Bits
1151
1152
1153local int huft_build OF((
1154 uIntf *, /* code lengths in bits */
1155 uInt, /* number of codes */
1156 uInt, /* number of "simple" codes */
1157 uIntf *, /* list of base values for non-simple codes */
1158 uIntf *, /* list of extra bits for non-simple codes */
1159 inflate_huft * FAR*,/* result: starting table */
1160 uIntf *, /* maximum lookup bits (returns actual) */
1161 z_stream *)); /* for zalloc function */
1162
1163local voidpf falloc OF((
1164 voidpf, /* opaque pointer (not used) */
1165 uInt, /* number of items */
1166 uInt)); /* size of item */
1167
1168local void ffree OF((
1169 voidpf q, /* opaque pointer (not used) */
1170 voidpf p, /* what to free (not used) */
1171 uInt n)); /* number of bytes (not used) */
1172
1173/* Tables for deflate from PKZIP's appnote.txt. */
1174local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
1175 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
1176 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
1177 /* actually lengths - 2; also see note #13 above about 258 */
1178local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
1179 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
1180 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
1181local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
1182 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
1183 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
1184 8193, 12289, 16385, 24577};
1185local uInt cpdext[] = { /* Extra bits for distance codes */
1186 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
1187 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
1188 12, 12, 13, 13};
1189
1190/*
1191 Huffman code decoding is performed using a multi-level table lookup.
1192 The fastest way to decode is to simply build a lookup table whose
1193 size is determined by the longest code. However, the time it takes
1194 to build this table can also be a factor if the data being decoded
1195 is not very long. The most common codes are necessarily the
1196 shortest codes, so those codes dominate the decoding time, and hence
1197 the speed. The idea is you can have a shorter table that decodes the
1198 shorter, more probable codes, and then point to subsidiary tables for
1199 the longer codes. The time it costs to decode the longer codes is
1200 then traded against the time it takes to make longer tables.
1201
1202 This results of this trade are in the variables lbits and dbits
1203 below. lbits is the number of bits the first level table for literal/
1204 length codes can decode in one step, and dbits is the same thing for
1205 the distance codes. Subsequent tables are also less than or equal to
1206 those sizes. These values may be adjusted either when all of the
1207 codes are shorter than that, in which case the longest code length in
1208 bits is used, or when the shortest code is *longer* than the requested
1209 table size, in which case the length of the shortest code in bits is
1210 used.
1211
1212 There are two different values for the two tables, since they code a
1213 different number of possibilities each. The literal/length table
1214 codes 286 possible values, or in a flat code, a little over eight
1215 bits. The distance table codes 30 possible values, or a little less
1216 than five bits, flat. The optimum values for speed end up being
1217 about one bit more than those, so lbits is 8+1 and dbits is 5+1.
1218 The optimum values may differ though from machine to machine, and
1219 possibly even between compilers. Your mileage may vary.
1220 */
1221
1222
1223/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
1224#define BMAX 15 /* maximum bit length of any code */
1225#define N_MAX 288 /* maximum number of codes in any set */
1226
1227#ifdef DEBUG_ZLIB
1228 uInt inflate_hufts;
1229#endif
1230
1231local int huft_build(b, n, s, d, e, t, m, zs)
1232uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
1233uInt n; /* number of codes (assumed <= N_MAX) */
1234uInt s; /* number of simple-valued codes (0..s-1) */
1235uIntf *d; /* list of base values for non-simple codes */
1236uIntf *e; /* list of extra bits for non-simple codes */
1237inflate_huft * FAR *t; /* result: starting table */
1238uIntf *m; /* maximum lookup bits, returns actual */
1239z_stream *zs; /* for zalloc function */
1240/* Given a list of code lengths and a maximum table size, make a set of
1241 tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
1242 if the given code set is incomplete (the tables are still built in this
1243 case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
1244 over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
1245{
1246
1247 uInt a; /* counter for codes of length k */
1248 uInt c[BMAX+1]; /* bit length count table */
1249 uInt f; /* i repeats in table every f entries */
1250 int g; /* maximum code length */
1251 int h; /* table level */
1252 register uInt i; /* counter, current code */
1253 register uInt j; /* counter */
1254 register int k; /* number of bits in current code */
1255 int l; /* bits per table (returned in m) */
1256 register uIntf *p; /* pointer into c[], b[], or v[] */
1257 inflate_huft *q; /* points to current table */
1258 struct inflate_huft_s r; /* table entry for structure assignment */
1259 inflate_huft *u[BMAX]; /* table stack */
1260 uInt v[N_MAX]; /* values in order of bit length */
1261 register int w; /* bits before this table == (l * h) */
1262 uInt x[BMAX+1]; /* bit offsets, then code stack */
1263 uIntf *xp; /* pointer into x */
1264 int y; /* number of dummy codes added */
1265 uInt z; /* number of entries in current table */
1266
1267
1268 /* Generate counts for each bit length */
1269 p = c;
1270#define C0 *p++ = 0;
1271#define C2 C0 C0 C0 C0
1272#define C4 C2 C2 C2 C2
1273 C4 /* clear c[]--assume BMAX+1 is 16 */
1274 p = b; i = n;
1275 do {
1276 c[*p++]++; /* assume all entries <= BMAX */
1277 } while (--i);
1278 if (c[0] == n) /* null input--all zero length codes */
1279 {
1280 *t = (inflate_huft *)Z_NULL;
1281 *m = 0;
1282 return Z_OK;
1283 }
1284
1285
1286 /* Find minimum and maximum length, bound *m by those */
1287 l = *m;
1288 for (j = 1; j <= BMAX; j++)
1289 if (c[j])
1290 break;
1291 k = j; /* minimum code length */
1292 if ((uInt)l < j)
1293 l = j;
1294 for (i = BMAX; i; i--)
1295 if (c[i])
1296 break;
1297 g = i; /* maximum code length */
1298 if ((uInt)l > i)
1299 l = i;
1300 *m = l;
1301
1302
1303 /* Adjust last length count to fill out codes, if needed */
1304 for (y = 1 << j; j < i; j++, y <<= 1)
1305 if ((y -= c[j]) < 0)
1306 return Z_DATA_ERROR;
1307 if ((y -= c[i]) < 0)
1308 return Z_DATA_ERROR;
1309 c[i] += y;
1310
1311
1312 /* Generate starting offsets into the value table for each length */
1313 x[1] = j = 0;
1314 p = c + 1; xp = x + 2;
1315 while (--i) { /* note that i == g from above */
1316 *xp++ = (j += *p++);
1317 }
1318
1319
1320 /* Make a table of values in order of bit lengths */
1321 p = b; i = 0;
1322 do {
1323 if ((j = *p++) != 0)
1324 v[x[j]++] = i;
1325 } while (++i < n);
1326
1327
1328 /* Generate the Huffman codes and for each, make the table entries */
1329 x[0] = i = 0; /* first Huffman code is zero */
1330 p = v; /* grab values in bit order */
1331 h = -1; /* no tables yet--level -1 */
1332 w = -l; /* bits decoded == (l * h) */
1333 u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
1334 q = (inflate_huft *)Z_NULL; /* ditto */
1335 z = 0; /* ditto */
1336
1337 /* go through the bit lengths (k already is bits in shortest code) */
1338 for (; k <= g; k++)
1339 {
1340 a = c[k];
1341 while (a--)
1342 {
1343 /* here i is the Huffman code of length k bits for value *p */
1344 /* make tables up to required level */
1345 while (k > w + l)
1346 {
1347 h++;
1348 w += l; /* previous table always l bits */
1349
1350 /* compute minimum size table less than or equal to l bits */
1351 z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
1352 if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
1353 { /* too few codes for k-w bit table */
1354 f -= a + 1; /* deduct codes from patterns left */
1355 xp = c + k;
1356 if (j < z)
1357 while (++j < z) /* try smaller tables up to z bits */
1358 {
1359 if ((f <<= 1) <= *++xp)
1360 break; /* enough codes to use up j bits */
1361 f -= *xp; /* else deduct codes from patterns */
1362 }
1363 }
1364 z = 1 << j; /* table entries for j-bit table */
1365
1366 /* allocate and link in new table */
1367 if ((q = (inflate_huft *)ZALLOC
1368 (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
1369 {
1370 if (h)
1371 inflate_trees_free(u[0], zs);
1372 return Z_MEM_ERROR; /* not enough memory */
1373 }
1374 q->word.Nalloc = z + 1;
1375#ifdef DEBUG_ZLIB
1376 inflate_hufts += z + 1;
1377#endif
1378 *t = q + 1; /* link to list for huft_free() */
1379 *(t = &(q->next)) = Z_NULL;
1380 u[h] = ++q; /* table starts after link */
1381
1382 /* connect to last table, if there is one */
1383 if (h)
1384 {
1385 x[h] = i; /* save pattern for backing up */
1386 r.bits = (Byte)l; /* bits to dump before this table */
1387 r.exop = (Byte)j; /* bits in this table */
1388 r.next = q; /* pointer to this table */
1389 j = i >> (w - l); /* (get around Turbo C bug) */
1390 u[h-1][j] = r; /* connect to last table */
1391 }
1392 }
1393
1394 /* set up table entry in r */
1395 r.bits = (Byte)(k - w);
1396 if (p >= v + n)
1397 r.exop = 128 + 64; /* out of values--invalid code */
1398 else if (*p < s)
1399 {
1400 r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
1401 r.base = *p++; /* simple code is just the value */
1402 }
1403 else
1404 {
1405 r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
1406 r.base = d[*p++ - s];
1407 }
1408
1409 /* fill code-like entries with r */
1410 f = 1 << (k - w);
1411 for (j = i >> w; j < z; j += f)
1412 q[j] = r;
1413
1414 /* backwards increment the k-bit code i */
1415 for (j = 1 << (k - 1); i & j; j >>= 1)
1416 i ^= j;
1417 i ^= j;
1418
1419 /* backup over finished tables */
1420 while ((i & ((1 << w) - 1)) != x[h])
1421 {
1422 h--; /* don't need to update q */
1423 w -= l;
1424 }
1425 }
1426 }
1427
1428
1429 /* Return Z_BUF_ERROR if we were given an incomplete table */
1430 return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
1431}
1432
1433
1434local int inflate_trees_bits(c, bb, tb, z)
1435uIntf *c; /* 19 code lengths */
1436uIntf *bb; /* bits tree desired/actual depth */
1437inflate_huft * FAR *tb; /* bits tree result */
1438z_stream *z; /* for zfree function */
1439{
1440 int r;
1441
1442 r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
1443 if (r == Z_DATA_ERROR)
1444 z->msg = "oversubscribed dynamic bit lengths tree";
1445 else if (r == Z_BUF_ERROR)
1446 {
1447 inflate_trees_free(*tb, z);
1448 z->msg = "incomplete dynamic bit lengths tree";
1449 r = Z_DATA_ERROR;
1450 }
1451 return r;
1452}
1453
1454
1455local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
1456uInt nl; /* number of literal/length codes */
1457uInt nd; /* number of distance codes */
1458uIntf *c; /* that many (total) code lengths */
1459uIntf *bl; /* literal desired/actual bit depth */
1460uIntf *bd; /* distance desired/actual bit depth */
1461inflate_huft * FAR *tl; /* literal/length tree result */
1462inflate_huft * FAR *td; /* distance tree result */
1463z_stream *z; /* for zfree function */
1464{
1465 int r;
1466
1467 /* build literal/length tree */
1468 if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
1469 {
1470 if (r == Z_DATA_ERROR)
1471 z->msg = "oversubscribed literal/length tree";
1472 else if (r == Z_BUF_ERROR)
1473 {
1474 inflate_trees_free(*tl, z);
1475 z->msg = "incomplete literal/length tree";
1476 r = Z_DATA_ERROR;
1477 }
1478 return r;
1479 }
1480
1481 /* build distance tree */
1482 if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
1483 {
1484 if (r == Z_DATA_ERROR)
1485 z->msg = "oversubscribed literal/length tree";
1486 else if (r == Z_BUF_ERROR) {
1487#ifdef PKZIP_BUG_WORKAROUND
1488 r = Z_OK;
1489 }
1490#else
1491 inflate_trees_free(*td, z);
1492 z->msg = "incomplete literal/length tree";
1493 r = Z_DATA_ERROR;
1494 }
1495 inflate_trees_free(*tl, z);
1496 return r;
1497#endif
1498 }
1499
1500 /* done */
1501 return Z_OK;
1502}
1503
1504
1505/* build fixed tables only once--keep them here */
1506local int fixed_lock = 0;
1507local int fixed_built = 0;
1508#define FIXEDH 530 /* number of hufts used by fixed tables */
1509local uInt fixed_left = FIXEDH;
1510local inflate_huft fixed_mem[FIXEDH];
1511local uInt fixed_bl;
1512local uInt fixed_bd;
1513local inflate_huft *fixed_tl;
1514local inflate_huft *fixed_td;
1515
1516
1517local voidpf falloc(q, n, s)
1518voidpf q; /* opaque pointer (not used) */
1519uInt n; /* number of items */
1520uInt s; /* size of item */
1521{
1522 Assert(s == sizeof(inflate_huft) && n <= fixed_left,
1523 "inflate_trees falloc overflow");
1524 if (q) s++; /* to make some compilers happy */
1525 fixed_left -= n;
1526 return (voidpf)(fixed_mem + fixed_left);
1527}
1528
1529
1530local void ffree(q, p, n)
1531voidpf q;
1532voidpf p;
1533uInt n;
1534{
1535 Assert(0, "inflate_trees ffree called!");
1536 if (q) q = p; /* to make some compilers happy */
1537}
1538
1539
1540local int inflate_trees_fixed(bl, bd, tl, td)
1541uIntf *bl; /* literal desired/actual bit depth */
1542uIntf *bd; /* distance desired/actual bit depth */
1543inflate_huft * FAR *tl; /* literal/length tree result */
1544inflate_huft * FAR *td; /* distance tree result */
1545{
1546 /* build fixed tables if not built already--lock out other instances */
1547 while (++fixed_lock > 1)
1548 fixed_lock--;
1549 if (!fixed_built)
1550 {
1551 int k; /* temporary variable */
1552 unsigned c[288]; /* length list for huft_build */
1553 z_stream z; /* for falloc function */
1554
1555 /* set up fake z_stream for memory routines */
1556 z.zalloc = falloc;
1557 z.zfree = ffree;
1558 z.opaque = Z_NULL;
1559
1560 /* literal table */
1561 for (k = 0; k < 144; k++)
1562 c[k] = 8;
1563 for (; k < 256; k++)
1564 c[k] = 9;
1565 for (; k < 280; k++)
1566 c[k] = 7;
1567 for (; k < 288; k++)
1568 c[k] = 8;
1569 fixed_bl = 7;
1570 huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
1571
1572 /* distance table */
1573 for (k = 0; k < 30; k++)
1574 c[k] = 5;
1575 fixed_bd = 5;
1576 huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
1577
1578 /* done */
1579 fixed_built = 1;
1580 }
1581 fixed_lock--;
1582 *bl = fixed_bl;
1583 *bd = fixed_bd;
1584 *tl = fixed_tl;
1585 *td = fixed_td;
1586 return Z_OK;
1587}
1588
1589
1590local int inflate_trees_free(t, z)
1591inflate_huft *t; /* table to free */
1592z_stream *z; /* for zfree function */
1593/* Free the malloc'ed tables built by huft_build(), which makes a linked
1594 list of the tables it made, with the links in a dummy first entry of
1595 each table. */
1596{
1597 register inflate_huft *p, *q;
1598
1599 /* Go through linked list, freeing from the malloced (t[-1]) address. */
1600 p = t;
1601 while (p != Z_NULL)
1602 {
1603 q = (--p)->next;
1604 ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
1605 p = q;
1606 }
1607 return Z_OK;
1608}
1609
1610/*+++++*/
1611/* infcodes.c -- process literals and length/distance pairs
1612 * Copyright (C) 1995 Mark Adler
1613 * For conditions of distribution and use, see copyright notice in zlib.h
1614 */
1615
1616/* simplify the use of the inflate_huft type with some defines */
1617#define base more.Base
1618#define next more.Next
1619#define exop word.what.Exop
1620#define bits word.what.Bits
1621
1622/* inflate codes private state */
1623struct inflate_codes_state {
1624
1625 /* mode */
1626 enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
1627 START, /* x: set up for LEN */
1628 LEN, /* i: get length/literal/eob next */
1629 LENEXT, /* i: getting length extra (have base) */
1630 DIST, /* i: get distance next */
1631 DISTEXT, /* i: getting distance extra */
1632 COPY, /* o: copying bytes in window, waiting for space */
1633 LIT, /* o: got literal, waiting for output space */
1634 WASH, /* o: got eob, possibly still output waiting */
1635 END, /* x: got eob and all data flushed */
1636 BADCODE} /* x: got error */
1637 mode; /* current inflate_codes mode */
1638
1639 /* mode dependent information */
1640 uInt len;
1641 union {
1642 struct {
1643 inflate_huft *tree; /* pointer into tree */
1644 uInt need; /* bits needed */
1645 } code; /* if LEN or DIST, where in tree */
1646 uInt lit; /* if LIT, literal */
1647 struct {
1648 uInt get; /* bits to get for extra */
1649 uInt dist; /* distance back to copy from */
1650 } copy; /* if EXT or COPY, where and how much */
1651 } sub; /* submode */
1652
1653 /* mode independent information */
1654 Byte lbits; /* ltree bits decoded per branch */
1655 Byte dbits; /* dtree bits decoder per branch */
1656 inflate_huft *ltree; /* literal/length/eob tree */
1657 inflate_huft *dtree; /* distance tree */
1658
1659};
1660
1661
1662local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
1663uInt bl, bd;
1664inflate_huft *tl, *td;
1665z_stream *z;
1666{
1667 inflate_codes_statef *c;
1668
1669 if ((c = (inflate_codes_statef *)
1670 ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
1671 {
1672 c->mode = START;
1673 c->lbits = (Byte)bl;
1674 c->dbits = (Byte)bd;
1675 c->ltree = tl;
1676 c->dtree = td;
1677 Tracev((stderr, "inflate: codes new\n"));
1678 }
1679 return c;
1680}
1681
1682
1683local int inflate_codes(s, z, r)
1684inflate_blocks_statef *s;
1685z_stream *z;
1686int r;
1687{
1688 uInt j; /* temporary storage */
1689 inflate_huft *t; /* temporary pointer */
1690 uInt e; /* extra bits or operation */
1691 uLong b; /* bit buffer */
1692 uInt k; /* bits in bit buffer */
1693 Bytef *p; /* input data pointer */
1694 uInt n; /* bytes available there */
1695 Bytef *q; /* output window write pointer */
1696 uInt m; /* bytes to end of window or read pointer */
1697 Bytef *f; /* pointer to copy strings from */
1698 inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
1699
1700 /* copy input/output information to locals (UPDATE macro restores) */
1701 LOAD
1702
1703 /* process input and output based on current state */
1704 while (1) switch (c->mode)
1705 { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
1706 case START: /* x: set up for LEN */
1707#ifndef SLOW
1708 if (m >= 258 && n >= 10)
1709 {
1710 UPDATE
1711 r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
1712 LOAD
1713 if (r != Z_OK)
1714 {
1715 c->mode = r == Z_STREAM_END ? WASH : BADCODE;
1716 break;
1717 }
1718 }
1719#endif /* !SLOW */
1720 c->sub.code.need = c->lbits;
1721 c->sub.code.tree = c->ltree;
1722 c->mode = LEN;
1723 case LEN: /* i: get length/literal/eob next */
1724 j = c->sub.code.need;
1725 NEEDBITS(j)
1726 t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
1727 DUMPBITS(t->bits)
1728 e = (uInt)(t->exop);
1729 if (e == 0) /* literal */
1730 {
1731 c->sub.lit = t->base;
1732 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
1733 "inflate: literal '%c'\n" :
1734 "inflate: literal 0x%02x\n", t->base));
1735 c->mode = LIT;
1736 break;
1737 }
1738 if (e & 16) /* length */
1739 {
1740 c->sub.copy.get = e & 15;
1741 c->len = t->base;
1742 c->mode = LENEXT;
1743 break;
1744 }
1745 if ((e & 64) == 0) /* next table */
1746 {
1747 c->sub.code.need = e;
1748 c->sub.code.tree = t->next;
1749 break;
1750 }
1751 if (e & 32) /* end of block */
1752 {
1753 Tracevv((stderr, "inflate: end of block\n"));
1754 c->mode = WASH;
1755 break;
1756 }
1757 c->mode = BADCODE; /* invalid code */
1758 z->msg = "invalid literal/length code";
1759 r = Z_DATA_ERROR;
1760 LEAVE
1761 case LENEXT: /* i: getting length extra (have base) */
1762 j = c->sub.copy.get;
1763 NEEDBITS(j)
1764 c->len += (uInt)b & inflate_mask[j];
1765 DUMPBITS(j)
1766 c->sub.code.need = c->dbits;
1767 c->sub.code.tree = c->dtree;
1768 Tracevv((stderr, "inflate: length %u\n", c->len));
1769 c->mode = DIST;
1770 case DIST: /* i: get distance next */
1771 j = c->sub.code.need;
1772 NEEDBITS(j)
1773 t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
1774 DUMPBITS(t->bits)
1775 e = (uInt)(t->exop);
1776 if (e & 16) /* distance */
1777 {
1778 c->sub.copy.get = e & 15;
1779 c->sub.copy.dist = t->base;
1780 c->mode = DISTEXT;
1781 break;
1782 }
1783 if ((e & 64) == 0) /* next table */
1784 {
1785 c->sub.code.need = e;
1786 c->sub.code.tree = t->next;
1787 break;
1788 }
1789 c->mode = BADCODE; /* invalid code */
1790 z->msg = "invalid distance code";
1791 r = Z_DATA_ERROR;
1792 LEAVE
1793 case DISTEXT: /* i: getting distance extra */
1794 j = c->sub.copy.get;
1795 NEEDBITS(j)
1796 c->sub.copy.dist += (uInt)b & inflate_mask[j];
1797 DUMPBITS(j)
1798 Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
1799 c->mode = COPY;
1800 case COPY: /* o: copying bytes in window, waiting for space */
1801#ifndef __TURBOC__ /* Turbo C bug for following expression */
1802 f = (uInt)(q - s->window) < c->sub.copy.dist ?
1803 s->end - (c->sub.copy.dist - (q - s->window)) :
1804 q - c->sub.copy.dist;
1805#else
1806 f = q - c->sub.copy.dist;
1807 if ((uInt)(q - s->window) < c->sub.copy.dist)
1808 f = s->end - (c->sub.copy.dist - (q - s->window));
1809#endif
1810 while (c->len)
1811 {
1812 NEEDOUT
1813 OUTBYTE(*f++)
1814 if (f == s->end)
1815 f = s->window;
1816 c->len--;
1817 }
1818 c->mode = START;
1819 break;
1820 case LIT: /* o: got literal, waiting for output space */
1821 NEEDOUT
1822 OUTBYTE(c->sub.lit)
1823 c->mode = START;
1824 break;
1825 case WASH: /* o: got eob, possibly more output */
1826 FLUSH
1827 if (s->read != s->write)
1828 LEAVE
1829 c->mode = END;
1830 case END:
1831 r = Z_STREAM_END;
1832 LEAVE
1833 case BADCODE: /* x: got error */
1834 r = Z_DATA_ERROR;
1835 LEAVE
1836 default:
1837 r = Z_STREAM_ERROR;
1838 LEAVE
1839 }
1840}
1841
1842
1843local void inflate_codes_free(c, z)
1844inflate_codes_statef *c;
1845z_stream *z;
1846{
1847 ZFREE(z, c, sizeof(struct inflate_codes_state));
1848 Tracev((stderr, "inflate: codes free\n"));
1849}
1850
1851/*+++++*/
1852/* inflate_util.c -- data and routines common to blocks and codes
1853 * Copyright (C) 1995 Mark Adler
1854 * For conditions of distribution and use, see copyright notice in zlib.h
1855 */
1856
1857/* copy as much as possible from the sliding window to the output area */
1858local int inflate_flush(s, z, r)
1859inflate_blocks_statef *s;
1860z_stream *z;
1861int r;
1862{
1863 uInt n;
1864 Bytef *p, *q;
1865
1866 /* local copies of source and destination pointers */
1867 p = z->next_out;
1868 q = s->read;
1869
1870 /* compute number of bytes to copy as far as end of window */
1871 n = (uInt)((q <= s->write ? s->write : s->end) - q);
1872 if (n > z->avail_out) n = z->avail_out;
1873 if (n && r == Z_BUF_ERROR) r = Z_OK;
1874
1875 /* update counters */
1876 z->avail_out -= n;
1877 z->total_out += n;
1878
1879 /* update check information */
1880 if (s->checkfn != Z_NULL)
1881 s->check = (*s->checkfn)(s->check, q, n);
1882
1883 /* copy as far as end of window */
1884 zmemcpy(p, q, n);
1885 p += n;
1886 q += n;
1887
1888 /* see if more to copy at beginning of window */
1889 if (q == s->end)
1890 {
1891 /* wrap pointers */
1892 q = s->window;
1893 if (s->write == s->end)
1894 s->write = s->window;
1895
1896 /* compute bytes to copy */
1897 n = (uInt)(s->write - q);
1898 if (n > z->avail_out) n = z->avail_out;
1899 if (n && r == Z_BUF_ERROR) r = Z_OK;
1900
1901 /* update counters */
1902 z->avail_out -= n;
1903 z->total_out += n;
1904
1905 /* update check information */
1906 if (s->checkfn != Z_NULL)
1907 s->check = (*s->checkfn)(s->check, q, n);
1908
1909 /* copy */
1910 zmemcpy(p, q, n);
1911 p += n;
1912 q += n;
1913 }
1914
1915 /* update pointers */
1916 z->next_out = p;
1917 s->read = q;
1918
1919 /* done */
1920 return r;
1921}
1922
1923
1924/*+++++*/
1925/* inffast.c -- process literals and length/distance pairs fast
1926 * Copyright (C) 1995 Mark Adler
1927 * For conditions of distribution and use, see copyright notice in zlib.h
1928 */
1929
1930/* simplify the use of the inflate_huft type with some defines */
1931#define base more.Base
1932#define next more.Next
1933#define exop word.what.Exop
1934#define bits word.what.Bits
1935
1936/* macros for bit input with no checking and for returning unused bytes */
1937#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
1938#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
1939
1940/* Called with number of bytes left to write in window at least 258
1941 (the maximum string length) and number of input bytes available
1942 at least ten. The ten bytes are six bytes for the longest length/
1943 distance pair plus four bytes for overloading the bit buffer. */
1944
1945local int inflate_fast(bl, bd, tl, td, s, z)
1946uInt bl, bd;
1947inflate_huft *tl, *td;
1948inflate_blocks_statef *s;
1949z_stream *z;
1950{
1951 inflate_huft *t; /* temporary pointer */
1952 uInt e; /* extra bits or operation */
1953 uLong b; /* bit buffer */
1954 uInt k; /* bits in bit buffer */
1955 Bytef *p; /* input data pointer */
1956 uInt n; /* bytes available there */
1957 Bytef *q; /* output window write pointer */
1958 uInt m; /* bytes to end of window or read pointer */
1959 uInt ml; /* mask for literal/length tree */
1960 uInt md; /* mask for distance tree */
1961 uInt c; /* bytes to copy */
1962 uInt d; /* distance back to copy from */
1963 Bytef *r; /* copy source pointer */
1964
1965 /* load input, output, bit values */
1966 LOAD
1967
1968 /* initialize masks */
1969 ml = inflate_mask[bl];
1970 md = inflate_mask[bd];
1971
1972 /* do until not enough input or output space for fast loop */
1973 do { /* assume called with m >= 258 && n >= 10 */
1974 /* get literal/length code */
1975 GRABBITS(20) /* max bits for literal/length code */
1976 if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
1977 {
1978 DUMPBITS(t->bits)
1979 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
1980 "inflate: * literal '%c'\n" :
1981 "inflate: * literal 0x%02x\n", t->base));
1982 *q++ = (Byte)t->base;
1983 m--;
1984 continue;
1985 }
1986 do {
1987 DUMPBITS(t->bits)
1988 if (e & 16)
1989 {
1990 /* get extra bits for length */
1991 e &= 15;
1992 c = t->base + ((uInt)b & inflate_mask[e]);
1993 DUMPBITS(e)
1994 Tracevv((stderr, "inflate: * length %u\n", c));
1995
1996 /* decode distance base of block to copy */
1997 GRABBITS(15); /* max bits for distance code */
1998 e = (t = td + ((uInt)b & md))->exop;
1999 do {
2000 DUMPBITS(t->bits)
2001 if (e & 16)
2002 {
2003 /* get extra bits to add to distance base */
2004 e &= 15;
2005 GRABBITS(e) /* get extra bits (up to 13) */
2006 d = t->base + ((uInt)b & inflate_mask[e]);
2007 DUMPBITS(e)
2008 Tracevv((stderr, "inflate: * distance %u\n", d));
2009
2010 /* do the copy */
2011 m -= c;
2012 if ((uInt)(q - s->window) >= d) /* offset before dest */
2013 { /* just copy */
2014 r = q - d;
2015 *q++ = *r++; c--; /* minimum count is three, */
2016 *q++ = *r++; c--; /* so unroll loop a little */
2017 }
2018 else /* else offset after destination */
2019 {
2020 e = d - (q - s->window); /* bytes from offset to end */
2021 r = s->end - e; /* pointer to offset */
2022 if (c > e) /* if source crosses, */
2023 {
2024 c -= e; /* copy to end of window */
2025 do {
2026 *q++ = *r++;
2027 } while (--e);
2028 r = s->window; /* copy rest from start of window */
2029 }
2030 }
2031 do { /* copy all or what's left */
2032 *q++ = *r++;
2033 } while (--c);
2034 break;
2035 }
2036 else if ((e & 64) == 0)
2037 e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
2038 else
2039 {
2040 z->msg = "invalid distance code";
2041 UNGRAB
2042 UPDATE
2043 return Z_DATA_ERROR;
2044 }
2045 } while (1);
2046 break;
2047 }
2048 if ((e & 64) == 0)
2049 {
2050 if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
2051 {
2052 DUMPBITS(t->bits)
2053 Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
2054 "inflate: * literal '%c'\n" :
2055 "inflate: * literal 0x%02x\n", t->base));
2056 *q++ = (Byte)t->base;
2057 m--;
2058 break;
2059 }
2060 }
2061 else if (e & 32)
2062 {
2063 Tracevv((stderr, "inflate: * end of block\n"));
2064 UNGRAB
2065 UPDATE
2066 return Z_STREAM_END;
2067 }
2068 else
2069 {
2070 z->msg = "invalid literal/length code";
2071 UNGRAB
2072 UPDATE
2073 return Z_DATA_ERROR;
2074 }
2075 } while (1);
2076 } while (m >= 258 && n >= 10);
2077
2078 /* not enough input or output--restore pointers and return */
2079 UNGRAB
2080 UPDATE
2081 return Z_OK;
2082}
2083
2084
2085/*+++++*/
2086/* zutil.c -- target dependent utility functions for the compression library
2087 * Copyright (C) 1995 Jean-loup Gailly.
2088 * For conditions of distribution and use, see copyright notice in zlib.h
2089 */
2090
2091/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
2092
2093char *zlib_version = ZLIB_VERSION;
2094
2095char *z_errmsg[] = {
2096"stream end", /* Z_STREAM_END 1 */
2097"", /* Z_OK 0 */
2098"file error", /* Z_ERRNO (-1) */
2099"stream error", /* Z_STREAM_ERROR (-2) */
2100"data error", /* Z_DATA_ERROR (-3) */
2101"insufficient memory", /* Z_MEM_ERROR (-4) */
2102"buffer error", /* Z_BUF_ERROR (-5) */
2103""};
2104
2105
2106/*+++++*/
2107/* adler32.c -- compute the Adler-32 checksum of a data stream
2108 * Copyright (C) 1995 Mark Adler
2109 * For conditions of distribution and use, see copyright notice in zlib.h
2110 */
2111
2112/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
2113
2114#define BASE 65521L /* largest prime smaller than 65536 */
2115#define NMAX 5552
2116/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
2117
2118#define DO1(buf) {s1 += *buf++; s2 += s1;}
2119#define DO2(buf) DO1(buf); DO1(buf);
2120#define DO4(buf) DO2(buf); DO2(buf);
2121#define DO8(buf) DO4(buf); DO4(buf);
2122#define DO16(buf) DO8(buf); DO8(buf);
2123
2124/* ========================================================================= */
2125uLong adler32(adler, buf, len)
2126 uLong adler;
2127 Bytef *buf;
2128 uInt len;
2129{
2130 unsigned long s1 = adler & 0xffff;
2131 unsigned long s2 = (adler >> 16) & 0xffff;
2132 int k;
2133
2134 if (buf == Z_NULL) return 1L;
2135
2136 while (len > 0) {
2137 k = len < NMAX ? len : NMAX;
2138 len -= k;
2139 while (k >= 16) {
2140 DO16(buf);
2141 k -= 16;
2142 }
2143 if (k != 0) do {
2144 DO1(buf);
2145 } while (--k);
2146 s1 %= BASE;
2147 s2 %= BASE;
2148 }
2149 return (s2 << 16) | s1;
2150}
diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c
new file mode 100644
index 000000000000..7848f126d67d
--- /dev/null
+++ b/arch/xtensa/boot/lib/zmem.c
@@ -0,0 +1,87 @@
1#include "zlib.h"
2
3/* bits taken from ppc */
4
5extern void *avail_ram, *end_avail;
6
7void exit (void)
8{
9 for (;;);
10}
11
12void *zalloc(void *x, unsigned items, unsigned size)
13{
14 void *p = avail_ram;
15
16 size *= items;
17 size = (size + 7) & -8;
18 avail_ram += size;
19 if (avail_ram > end_avail) {
20 //puts("oops... out of memory\n");
21 //pause();
22 exit ();
23 }
24 return p;
25}
26
27void zfree(void *x, void *addr, unsigned nb)
28{
29}
30
31
32#define HEAD_CRC 2
33#define EXTRA_FIELD 4
34#define ORIG_NAME 8
35#define COMMENT 0x10
36#define RESERVED 0xe0
37
38#define DEFLATED 8
39
40void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp)
41{
42 z_stream s;
43 int r, i, flags;
44
45 /* skip header */
46
47 i = 10;
48 flags = src[3];
49 if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
50 //puts("bad gzipped data\n");
51 exit();
52 }
53 if ((flags & EXTRA_FIELD) != 0)
54 i = 12 + src[10] + (src[11] << 8);
55 if ((flags & ORIG_NAME) != 0)
56 while (src[i++] != 0)
57 ;
58 if ((flags & COMMENT) != 0)
59 while (src[i++] != 0)
60 ;
61 if ((flags & HEAD_CRC) != 0)
62 i += 2;
63 if (i >= *lenp) {
64 //puts("gunzip: ran out of data in header\n");
65 exit();
66 }
67
68 s.zalloc = zalloc;
69 s.zfree = zfree;
70 r = inflateInit2(&s, -MAX_WBITS);
71 if (r != Z_OK) {
72 //puts("inflateInit2 returned "); puthex(r); puts("\n");
73 exit();
74 }
75 s.next_in = src + i;
76 s.avail_in = *lenp - i;
77 s.next_out = dst;
78 s.avail_out = dstlen;
79 r = inflate(&s, Z_FINISH);
80 if (r != Z_OK && r != Z_STREAM_END) {
81 //puts("inflate returned "); puthex(r); puts("\n");
82 exit();
83 }
84 *lenp = s.next_out - (unsigned char *) dst;
85 inflateEnd(&s);
86}
87
diff --git a/arch/xtensa/boot/ramdisk/Makefile b/arch/xtensa/boot/ramdisk/Makefile
new file mode 100644
index 000000000000..b12f76352438
--- /dev/null
+++ b/arch/xtensa/boot/ramdisk/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile for a ramdisk image
3#
4
5BIG_ENDIAN := $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big)
6
7ifeq ($(BIG_ENDIAN),1)
8OBJCOPY_ARGS := -O elf32-xtensa-be
9else
10OBJCOPY_ARGS := -O elf32-xtensa-le
11endif
12
13obj-y = ramdisk.o
14
15RAMDISK_IMAGE = arch/$(ARCH)/boot/ramdisk/$(CONFIG_EMBEDDED_RAMDISK_IMAGE)
16
17arch/$(ARCH)/boot/ramdisk/ramdisk.o:
18 $(Q)echo -e "dummy:" | $(AS) -o $@;
19 $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) \
20 --add-section .initrd=$(RAMDISK_IMAGE) \
21 --set-section-flags .initrd=contents,alloc,load,load,data \
22 arch/$(ARCH)/boot/ramdisk/ramdisk.o $@
23
diff --git a/arch/xtensa/configs/common_defconfig b/arch/xtensa/configs/common_defconfig
new file mode 100644
index 000000000000..1d230ee081b4
--- /dev/null
+++ b/arch/xtensa/configs/common_defconfig
@@ -0,0 +1,662 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc2
4# Tue Mar 1 16:36:53 2005
5#
6# CONFIG_FRAME_POINTER is not set
7CONFIG_XTENSA=y
8# CONFIG_UID16 is not set
9CONFIG_RWSEM_XCHGADD_ALGORITHM=y
10CONFIG_HAVE_DEC_LOCK=y
11CONFIG_GENERIC_HARDIRQS=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25CONFIG_SYSVIPC=y
26# CONFIG_POSIX_MQUEUE is not set
27CONFIG_BSD_PROCESS_ACCT=y
28# CONFIG_BSD_PROCESS_ACCT_V3 is not set
29CONFIG_SYSCTL=y
30# CONFIG_AUDIT is not set
31CONFIG_LOG_BUF_SHIFT=14
32# CONFIG_HOTPLUG is not set
33CONFIG_KOBJECT_UEVENT=y
34# CONFIG_IKCONFIG is not set
35# CONFIG_EMBEDDED is not set
36CONFIG_KALLSYMS=y
37# CONFIG_KALLSYMS_ALL is not set
38# CONFIG_KALLSYMS_EXTRA_PASS is not set
39CONFIG_FUTEX=y
40CONFIG_EPOLL=y
41# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
42CONFIG_SHMEM=y
43CONFIG_CC_ALIGN_FUNCTIONS=0
44CONFIG_CC_ALIGN_LABELS=0
45CONFIG_CC_ALIGN_LOOPS=0
46CONFIG_CC_ALIGN_JUMPS=0
47# CONFIG_TINY_SHMEM is not set
48
49#
50# Loadable module support
51#
52CONFIG_MODULES=y
53# CONFIG_MODULE_UNLOAD is not set
54CONFIG_OBSOLETE_MODPARM=y
55CONFIG_MODVERSIONS=y
56# CONFIG_MODULE_SRCVERSION_ALL is not set
57CONFIG_KMOD=y
58
59#
60# Processor type and features
61#
62CONFIG_XTENSA_ARCH_LINUX_BE=y
63# CONFIG_XTENSA_ARCH_LINUX_LE is not set
64# CONFIG_XTENSA_ARCH_LINUX_TEST is not set
65# CONFIG_XTENSA_ARCH_S5 is not set
66# CONFIG_XTENSA_CUSTOM is not set
67CONFIG_MMU=y
68# CONFIG_XTENSA_UNALIGNED_USER is not set
69# CONFIG_PREEMPT is not set
70# CONFIG_MATH_EMULATION is not set
71# CONFIG_HIGHMEM is not set
72
73#
74# Platform options
75#
76# CONFIG_XTENSA_PLATFORM_ISS is not set
77CONFIG_XTENSA_PLATFORM_XT2000=y
78CONFIG_XTENSA_CALIBRATE_CCOUNT=y
79CONFIG_GENERIC_CALIBRATE_DELAY=y
80CONFIG_CMDLINE_BOOL=y
81CONFIG_CMDLINE="console=ttyS0,38400 ip=bootp root=nfs nfsroot=/opt/montavista/pro/devkit/xtensa/linux_be/target"
82
83#
84# Bus options
85#
86CONFIG_PCI=y
87# CONFIG_PCI_LEGACY_PROC is not set
88# CONFIG_PCI_NAMES is not set
89
90#
91# PCCARD (PCMCIA/CardBus) support
92#
93# CONFIG_PCCARD is not set
94
95#
96# PC-card bridges
97#
98
99#
100# PCI Hotplug Support
101#
102# CONFIG_HOTPLUG_PCI is not set
103
104#
105# Exectuable file formats
106#
107CONFIG_KCORE_ELF=y
108CONFIG_BINFMT_ELF=y
109CONFIG_BINFMT_MISC=y
110
111#
112# Device Drivers
113#
114
115#
116# Generic Driver Options
117#
118CONFIG_STANDALONE=y
119CONFIG_PREVENT_FIRMWARE_BUILD=y
120# CONFIG_FW_LOADER is not set
121# CONFIG_DEBUG_DRIVER is not set
122
123#
124# Memory Technology Devices (MTD)
125#
126# CONFIG_MTD is not set
127
128#
129# Parallel port support
130#
131# CONFIG_PARPORT is not set
132
133#
134# Plug and Play support
135#
136
137#
138# Block devices
139#
140# CONFIG_BLK_DEV_FD is not set
141# CONFIG_BLK_CPQ_DA is not set
142# CONFIG_BLK_CPQ_CISS_DA is not set
143# CONFIG_BLK_DEV_DAC960 is not set
144# CONFIG_BLK_DEV_UMEM is not set
145# CONFIG_BLK_DEV_COW_COMMON is not set
146# CONFIG_BLK_DEV_LOOP is not set
147# CONFIG_BLK_DEV_NBD is not set
148# CONFIG_BLK_DEV_SX8 is not set
149# CONFIG_BLK_DEV_RAM is not set
150CONFIG_BLK_DEV_RAM_COUNT=16
151CONFIG_INITRAMFS_SOURCE=""
152# CONFIG_CDROM_PKTCDVD is not set
153
154#
155# IO Schedulers
156#
157CONFIG_IOSCHED_NOOP=y
158CONFIG_IOSCHED_AS=y
159CONFIG_IOSCHED_DEADLINE=y
160CONFIG_IOSCHED_CFQ=y
161# CONFIG_ATA_OVER_ETH is not set
162
163#
164# ATA/ATAPI/MFM/RLL support
165#
166# CONFIG_IDE is not set
167
168#
169# SCSI device support
170#
171# CONFIG_SCSI is not set
172
173#
174# Multi-device support (RAID and LVM)
175#
176# CONFIG_MD is not set
177
178#
179# Fusion MPT device support
180#
181
182#
183# IEEE 1394 (FireWire) support
184#
185# CONFIG_IEEE1394 is not set
186
187#
188# I2O device support
189#
190# CONFIG_I2O is not set
191
192#
193# Networking support
194#
195CONFIG_NET=y
196
197#
198# Networking options
199#
200# CONFIG_PACKET is not set
201# CONFIG_NETLINK_DEV is not set
202CONFIG_UNIX=y
203# CONFIG_NET_KEY is not set
204CONFIG_INET=y
205CONFIG_IP_MULTICAST=y
206CONFIG_IP_ADVANCED_ROUTER=y
207CONFIG_IP_MULTIPLE_TABLES=y
208CONFIG_IP_ROUTE_MULTIPATH=y
209CONFIG_IP_ROUTE_VERBOSE=y
210CONFIG_IP_PNP=y
211CONFIG_IP_PNP_DHCP=y
212CONFIG_IP_PNP_BOOTP=y
213CONFIG_IP_PNP_RARP=y
214# CONFIG_NET_IPIP is not set
215# CONFIG_NET_IPGRE is not set
216# CONFIG_IP_MROUTE is not set
217# CONFIG_ARPD is not set
218# CONFIG_SYN_COOKIES is not set
219# CONFIG_INET_AH is not set
220# CONFIG_INET_ESP is not set
221# CONFIG_INET_IPCOMP is not set
222# CONFIG_INET_TUNNEL is not set
223# CONFIG_IP_TCPDIAG is not set
224# CONFIG_IP_TCPDIAG_IPV6 is not set
225# CONFIG_IPV6 is not set
226# CONFIG_NETFILTER is not set
227
228#
229# SCTP Configuration (EXPERIMENTAL)
230#
231# CONFIG_IP_SCTP is not set
232# CONFIG_ATM is not set
233# CONFIG_BRIDGE is not set
234# CONFIG_VLAN_8021Q is not set
235# CONFIG_DECNET is not set
236# CONFIG_LLC2 is not set
237# CONFIG_IPX is not set
238# CONFIG_ATALK is not set
239# CONFIG_X25 is not set
240# CONFIG_LAPB is not set
241# CONFIG_NET_DIVERT is not set
242# CONFIG_ECONET is not set
243# CONFIG_WAN_ROUTER is not set
244
245#
246# QoS and/or fair queueing
247#
248CONFIG_NET_SCHED=y
249CONFIG_NET_SCH_CLK_JIFFIES=y
250# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
251# CONFIG_NET_SCH_CLK_CPU is not set
252CONFIG_NET_SCH_CBQ=m
253CONFIG_NET_SCH_HTB=m
254# CONFIG_NET_SCH_HFSC is not set
255CONFIG_NET_SCH_PRIO=m
256CONFIG_NET_SCH_RED=m
257CONFIG_NET_SCH_SFQ=m
258CONFIG_NET_SCH_TEQL=m
259CONFIG_NET_SCH_TBF=m
260CONFIG_NET_SCH_GRED=m
261CONFIG_NET_SCH_DSMARK=m
262# CONFIG_NET_SCH_NETEM is not set
263CONFIG_NET_SCH_INGRESS=m
264CONFIG_NET_QOS=y
265CONFIG_NET_ESTIMATOR=y
266CONFIG_NET_CLS=y
267CONFIG_NET_CLS_TCINDEX=m
268CONFIG_NET_CLS_ROUTE4=m
269CONFIG_NET_CLS_ROUTE=y
270CONFIG_NET_CLS_FW=m
271CONFIG_NET_CLS_U32=m
272# CONFIG_CLS_U32_PERF is not set
273# CONFIG_NET_CLS_IND is not set
274CONFIG_NET_CLS_RSVP=m
275CONFIG_NET_CLS_RSVP6=m
276# CONFIG_NET_CLS_ACT is not set
277CONFIG_NET_CLS_POLICE=y
278
279#
280# Network testing
281#
282# CONFIG_NET_PKTGEN is not set
283# CONFIG_NETPOLL is not set
284# CONFIG_NET_POLL_CONTROLLER is not set
285# CONFIG_HAMRADIO is not set
286# CONFIG_IRDA is not set
287# CONFIG_BT is not set
288CONFIG_NETDEVICES=y
289CONFIG_DUMMY=y
290# CONFIG_BONDING is not set
291# CONFIG_EQUALIZER is not set
292# CONFIG_TUN is not set
293
294#
295# ARCnet devices
296#
297# CONFIG_ARCNET is not set
298
299#
300# Ethernet (10 or 100Mbit)
301#
302CONFIG_NET_ETHERNET=y
303# CONFIG_MII is not set
304CONFIG_XT2000_SONIC=y
305# CONFIG_HAPPYMEAL is not set
306# CONFIG_SUNGEM is not set
307# CONFIG_NET_VENDOR_3COM is not set
308
309#
310# Tulip family network device support
311#
312# CONFIG_NET_TULIP is not set
313# CONFIG_HP100 is not set
314# CONFIG_NET_PCI is not set
315
316#
317# Ethernet (1000 Mbit)
318#
319# CONFIG_ACENIC is not set
320# CONFIG_DL2K is not set
321# CONFIG_E1000 is not set
322# CONFIG_NS83820 is not set
323# CONFIG_HAMACHI is not set
324# CONFIG_YELLOWFIN is not set
325# CONFIG_R8169 is not set
326# CONFIG_SK98LIN is not set
327# CONFIG_TIGON3 is not set
328
329#
330# Ethernet (10000 Mbit)
331#
332# CONFIG_IXGB is not set
333# CONFIG_S2IO is not set
334
335#
336# Token Ring devices
337#
338# CONFIG_TR is not set
339
340#
341# Wireless LAN (non-hamradio)
342#
343CONFIG_NET_RADIO=y
344
345#
346# Obsolete Wireless cards support (pre-802.11)
347#
348CONFIG_STRIP=m
349
350#
351# Wireless 802.11b ISA/PCI cards support
352#
353CONFIG_HERMES=m
354# CONFIG_PLX_HERMES is not set
355# CONFIG_TMD_HERMES is not set
356# CONFIG_PCI_HERMES is not set
357# CONFIG_ATMEL is not set
358
359#
360# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
361#
362# CONFIG_PRISM54 is not set
363CONFIG_NET_WIRELESS=y
364
365#
366# Wan interfaces
367#
368# CONFIG_WAN is not set
369# CONFIG_FDDI is not set
370# CONFIG_HIPPI is not set
371# CONFIG_PPP is not set
372# CONFIG_SLIP is not set
373# CONFIG_SHAPER is not set
374# CONFIG_NETCONSOLE is not set
375
376#
377# ISDN subsystem
378#
379# CONFIG_ISDN is not set
380
381#
382# Telephony Support
383#
384# CONFIG_PHONE is not set
385
386#
387# Input device support
388#
389CONFIG_INPUT=y
390
391#
392# Userland interfaces
393#
394CONFIG_INPUT_MOUSEDEV=y
395# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
396CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
397CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
398# CONFIG_INPUT_JOYDEV is not set
399# CONFIG_INPUT_TSDEV is not set
400# CONFIG_INPUT_EVDEV is not set
401# CONFIG_INPUT_EVBUG is not set
402
403#
404# Input I/O drivers
405#
406# CONFIG_GAMEPORT is not set
407CONFIG_SOUND_GAMEPORT=y
408CONFIG_SERIO=y
409# CONFIG_SERIO_I8042 is not set
410# CONFIG_SERIO_SERPORT is not set
411# CONFIG_SERIO_CT82C710 is not set
412# CONFIG_SERIO_PCIPS2 is not set
413# CONFIG_SERIO_RAW is not set
414
415#
416# Input Device Drivers
417#
418# CONFIG_INPUT_KEYBOARD is not set
419# CONFIG_INPUT_MOUSE is not set
420# CONFIG_INPUT_JOYSTICK is not set
421# CONFIG_INPUT_TOUCHSCREEN is not set
422# CONFIG_INPUT_MISC is not set
423
424#
425# Character devices
426#
427CONFIG_VT=y
428CONFIG_VT_CONSOLE=y
429CONFIG_HW_CONSOLE=y
430# CONFIG_SERIAL_NONSTANDARD is not set
431
432#
433# Serial drivers
434#
435CONFIG_SERIAL_8250=y
436CONFIG_SERIAL_8250_CONSOLE=y
437CONFIG_SERIAL_8250_NR_UARTS=4
438# CONFIG_SERIAL_8250_EXTENDED is not set
439
440#
441# Non-8250 serial port support
442#
443CONFIG_SERIAL_CORE=y
444CONFIG_SERIAL_CORE_CONSOLE=y
445CONFIG_UNIX98_PTYS=y
446CONFIG_LEGACY_PTYS=y
447CONFIG_LEGACY_PTY_COUNT=256
448
449#
450# IPMI
451#
452# CONFIG_IPMI_HANDLER is not set
453
454#
455# Watchdog Cards
456#
457# CONFIG_WATCHDOG is not set
458# CONFIG_RTC is not set
459# CONFIG_GEN_RTC is not set
460# CONFIG_DTLK is not set
461# CONFIG_R3964 is not set
462# CONFIG_APPLICOM is not set
463
464#
465# Ftape, the floppy tape device driver
466#
467# CONFIG_DRM is not set
468# CONFIG_RAW_DRIVER is not set
469
470#
471# I2C support
472#
473# CONFIG_I2C is not set
474
475#
476# Dallas's 1-wire bus
477#
478# CONFIG_W1 is not set
479
480#
481# Misc devices
482#
483
484#
485# Multimedia devices
486#
487# CONFIG_VIDEO_DEV is not set
488
489#
490# Digital Video Broadcasting Devices
491#
492# CONFIG_DVB is not set
493
494#
495# Graphics support
496#
497# CONFIG_FB is not set
498
499#
500# Console display driver support
501#
502# CONFIG_VGA_CONSOLE is not set
503CONFIG_DUMMY_CONSOLE=y
504# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
505
506#
507# Sound
508#
509# CONFIG_SOUND is not set
510
511#
512# USB support
513#
514# CONFIG_USB is not set
515CONFIG_USB_ARCH_HAS_HCD=y
516CONFIG_USB_ARCH_HAS_OHCI=y
517
518#
519# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
520#
521
522#
523# USB Gadget Support
524#
525# CONFIG_USB_GADGET is not set
526
527#
528# MMC/SD Card support
529#
530# CONFIG_MMC is not set
531
532#
533# InfiniBand support
534#
535# CONFIG_INFINIBAND is not set
536
537#
538# File systems
539#
540# CONFIG_EXT2_FS is not set
541# CONFIG_EXT3_FS is not set
542# CONFIG_JBD is not set
543# CONFIG_REISERFS_FS is not set
544# CONFIG_JFS_FS is not set
545# CONFIG_XFS_FS is not set
546# CONFIG_MINIX_FS is not set
547# CONFIG_ROMFS_FS is not set
548# CONFIG_QUOTA is not set
549CONFIG_DNOTIFY=y
550# CONFIG_AUTOFS_FS is not set
551# CONFIG_AUTOFS4_FS is not set
552
553#
554# CD-ROM/DVD Filesystems
555#
556# CONFIG_ISO9660_FS is not set
557# CONFIG_UDF_FS is not set
558
559#
560# DOS/FAT/NT Filesystems
561#
562# CONFIG_MSDOS_FS is not set
563# CONFIG_VFAT_FS is not set
564# CONFIG_NTFS_FS is not set
565
566#
567# Pseudo filesystems
568#
569CONFIG_PROC_FS=y
570# CONFIG_PROC_KCORE is not set
571CONFIG_SYSFS=y
572CONFIG_DEVFS_FS=y
573# CONFIG_DEVFS_MOUNT is not set
574# CONFIG_DEVFS_DEBUG is not set
575# CONFIG_DEVPTS_FS_XATTR is not set
576# CONFIG_TMPFS is not set
577# CONFIG_HUGETLB_PAGE is not set
578CONFIG_RAMFS=y
579
580#
581# Miscellaneous filesystems
582#
583# CONFIG_ADFS_FS is not set
584# CONFIG_AFFS_FS is not set
585# CONFIG_HFS_FS is not set
586# CONFIG_HFSPLUS_FS is not set
587# CONFIG_BEFS_FS is not set
588# CONFIG_BFS_FS is not set
589# CONFIG_EFS_FS is not set
590# CONFIG_CRAMFS is not set
591# CONFIG_VXFS_FS is not set
592# CONFIG_HPFS_FS is not set
593# CONFIG_QNX4FS_FS is not set
594# CONFIG_SYSV_FS is not set
595# CONFIG_UFS_FS is not set
596
597#
598# Network File Systems
599#
600CONFIG_NFS_FS=y
601CONFIG_NFS_V3=y
602# CONFIG_NFS_V4 is not set
603# CONFIG_NFS_DIRECTIO is not set
604# CONFIG_NFSD is not set
605CONFIG_ROOT_NFS=y
606CONFIG_LOCKD=y
607CONFIG_LOCKD_V4=y
608# CONFIG_EXPORTFS is not set
609CONFIG_SUNRPC=y
610# CONFIG_RPCSEC_GSS_KRB5 is not set
611# CONFIG_RPCSEC_GSS_SPKM3 is not set
612# CONFIG_SMB_FS is not set
613# CONFIG_CIFS is not set
614# CONFIG_NCP_FS is not set
615# CONFIG_CODA_FS is not set
616# CONFIG_AFS_FS is not set
617
618#
619# Partition Types
620#
621# CONFIG_PARTITION_ADVANCED is not set
622CONFIG_MSDOS_PARTITION=y
623
624#
625# Native Language Support
626#
627# CONFIG_NLS is not set
628
629#
630# Kernel hacking
631#
632CONFIG_DEBUG_KERNEL=y
633# CONFIG_DEBUG_STACKOVERFLOW is not set
634# CONFIG_DEBUG_SLAB is not set
635CONFIG_MAGIC_SYSRQ=y
636# CONFIG_DEBUG_SPINLOCK is not set
637# CONFIG_DEBUG_PAGEALLOC is not set
638# CONFIG_DEBUG_INFO is not set
639# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
640# CONFIG_KGDB is not set
641
642#
643# Security options
644#
645# CONFIG_KEYS is not set
646# CONFIG_SECURITY is not set
647
648#
649# Cryptographic options
650#
651# CONFIG_CRYPTO is not set
652
653#
654# Hardware crypto devices
655#
656
657#
658# Library routines
659#
660# CONFIG_CRC_CCITT is not set
661# CONFIG_CRC32 is not set
662# CONFIG_LIBCRC32C is not set
diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig
new file mode 100644
index 000000000000..802621dd4867
--- /dev/null
+++ b/arch/xtensa/configs/iss_defconfig
@@ -0,0 +1,531 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11-rc2
4# Fri Feb 25 19:21:24 2005
5#
6CONFIG_FRAME_POINTER=y
7CONFIG_XTENSA=y
8# CONFIG_UID16 is not set
9CONFIG_RWSEM_XCHGADD_ALGORITHM=y
10CONFIG_HAVE_DEC_LOCK=y
11CONFIG_GENERIC_HARDIRQS=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION=""
24CONFIG_SWAP=y
25CONFIG_SYSVIPC=y
26# CONFIG_POSIX_MQUEUE is not set
27# CONFIG_BSD_PROCESS_ACCT is not set
28CONFIG_SYSCTL=y
29# CONFIG_AUDIT is not set
30CONFIG_LOG_BUF_SHIFT=14
31# CONFIG_HOTPLUG is not set
32# CONFIG_KOBJECT_UEVENT is not set
33# CONFIG_IKCONFIG is not set
34CONFIG_EMBEDDED=y
35CONFIG_KALLSYMS=y
36# CONFIG_KALLSYMS_ALL is not set
37# CONFIG_KALLSYMS_EXTRA_PASS is not set
38CONFIG_FUTEX=y
39CONFIG_EPOLL=y
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
41CONFIG_SHMEM=y
42CONFIG_CC_ALIGN_FUNCTIONS=0
43CONFIG_CC_ALIGN_LABELS=0
44CONFIG_CC_ALIGN_LOOPS=0
45CONFIG_CC_ALIGN_JUMPS=0
46# CONFIG_TINY_SHMEM is not set
47
48#
49# Loadable module support
50#
51# CONFIG_MODULES is not set
52
53#
54# Processor type and features
55#
56CONFIG_XTENSA_ARCH_LINUX_BE=y
57# CONFIG_XTENSA_ARCH_LINUX_LE is not set
58# CONFIG_XTENSA_ARCH_LINUX_TEST is not set
59# CONFIG_XTENSA_ARCH_S5 is not set
60# CONFIG_XTENSA_CUSTOM is not set
61CONFIG_MMU=y
62# CONFIG_XTENSA_UNALIGNED_USER is not set
63# CONFIG_PREEMPT is not set
64# CONFIG_MATH_EMULATION is not set
65# CONFIG_HIGHMEM is not set
66
67#
68# Platform options
69#
70CONFIG_XTENSA_PLATFORM_ISS=y
71# CONFIG_XTENSA_PLATFORM_XT2000 is not set
72# CONFIG_XTENSA_PLATFORM_ARUBA is not set
73# CONFIG_XTENSA_CALIBRATE_CCOUNT is not set
74CONFIG_XTENSA_CPU_CLOCK=10
75# CONFIG_GENERIC_CALIBRATE_DELAY is not set
76CONFIG_CMDLINE_BOOL=y
77CONFIG_CMDLINE="console=ttyS0,38400 eth0=tuntap,,tap0 ip=192.168.168.5:192.168.168.1 root=nfs nfsroot=192.168.168.1:/opt/montavista/pro/devkit/xtensa/linux_be/target"
78CONFIG_SERIAL_CONSOLE=y
79CONFIG_XTENSA_ISS_NETWORK=y
80
81#
82# Bus options
83#
84
85#
86# PCCARD (PCMCIA/CardBus) support
87#
88# CONFIG_PCCARD is not set
89
90#
91# PC-card bridges
92#
93
94#
95# PCI Hotplug Support
96#
97
98#
99# Exectuable file formats
100#
101CONFIG_KCORE_ELF=y
102CONFIG_BINFMT_ELF=y
103# CONFIG_BINFMT_MISC is not set
104
105#
106# Device Drivers
107#
108
109#
110# Generic Driver Options
111#
112# CONFIG_STANDALONE is not set
113CONFIG_PREVENT_FIRMWARE_BUILD=y
114# CONFIG_FW_LOADER is not set
115# CONFIG_DEBUG_DRIVER is not set
116
117#
118# Memory Technology Devices (MTD)
119#
120# CONFIG_MTD is not set
121
122#
123# Parallel port support
124#
125# CONFIG_PARPORT is not set
126
127#
128# Plug and Play support
129#
130
131#
132# Block devices
133#
134# CONFIG_BLK_DEV_FD is not set
135# CONFIG_BLK_DEV_COW_COMMON is not set
136# CONFIG_BLK_DEV_LOOP is not set
137# CONFIG_BLK_DEV_NBD is not set
138# CONFIG_BLK_DEV_RAM is not set
139CONFIG_BLK_DEV_RAM_COUNT=16
140CONFIG_INITRAMFS_SOURCE=""
141# CONFIG_CDROM_PKTCDVD is not set
142
143#
144# IO Schedulers
145#
146CONFIG_IOSCHED_NOOP=y
147# CONFIG_IOSCHED_AS is not set
148# CONFIG_IOSCHED_DEADLINE is not set
149# CONFIG_IOSCHED_CFQ is not set
150# CONFIG_ATA_OVER_ETH is not set
151
152#
153# ATA/ATAPI/MFM/RLL support
154#
155# CONFIG_IDE is not set
156
157#
158# SCSI device support
159#
160# CONFIG_SCSI is not set
161
162#
163# Multi-device support (RAID and LVM)
164#
165# CONFIG_MD is not set
166
167#
168# Fusion MPT device support
169#
170
171#
172# IEEE 1394 (FireWire) support
173#
174
175#
176# I2O device support
177#
178
179#
180# Networking support
181#
182CONFIG_NET=y
183
184#
185# Networking options
186#
187CONFIG_PACKET=y
188# CONFIG_PACKET_MMAP is not set
189# CONFIG_NETLINK_DEV is not set
190CONFIG_UNIX=y
191# CONFIG_NET_KEY is not set
192CONFIG_INET=y
193# CONFIG_IP_MULTICAST is not set
194# CONFIG_IP_ADVANCED_ROUTER is not set
195CONFIG_IP_PNP=y
196CONFIG_IP_PNP_DHCP=y
197CONFIG_IP_PNP_BOOTP=y
198CONFIG_IP_PNP_RARP=y
199# CONFIG_NET_IPIP is not set
200# CONFIG_NET_IPGRE is not set
201# CONFIG_ARPD is not set
202# CONFIG_SYN_COOKIES is not set
203# CONFIG_INET_AH is not set
204# CONFIG_INET_ESP is not set
205# CONFIG_INET_IPCOMP is not set
206# CONFIG_INET_TUNNEL is not set
207# CONFIG_IP_TCPDIAG is not set
208# CONFIG_IP_TCPDIAG_IPV6 is not set
209# CONFIG_IPV6 is not set
210# CONFIG_NETFILTER is not set
211
212#
213# SCTP Configuration (EXPERIMENTAL)
214#
215# CONFIG_IP_SCTP is not set
216# CONFIG_SCTP_HMAC_NONE is not set
217# CONFIG_SCTP_HMAC_SHA1 is not set
218# CONFIG_SCTP_HMAC_MD5 is not set
219# CONFIG_ATM is not set
220# CONFIG_BRIDGE is not set
221# CONFIG_VLAN_8021Q is not set
222# CONFIG_DECNET is not set
223# CONFIG_LLC2 is not set
224# CONFIG_IPX is not set
225# CONFIG_ATALK is not set
226# CONFIG_X25 is not set
227# CONFIG_LAPB is not set
228# CONFIG_NET_DIVERT is not set
229# CONFIG_ECONET is not set
230# CONFIG_WAN_ROUTER is not set
231
232#
233# QoS and/or fair queueing
234#
235# CONFIG_NET_SCHED is not set
236# CONFIG_NET_SCH_CLK_JIFFIES is not set
237# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
238# CONFIG_NET_SCH_CLK_CPU is not set
239# CONFIG_NET_CLS_ROUTE is not set
240
241#
242# Network testing
243#
244# CONFIG_NET_PKTGEN is not set
245# CONFIG_NETPOLL is not set
246# CONFIG_NET_POLL_CONTROLLER is not set
247# CONFIG_HAMRADIO is not set
248# CONFIG_IRDA is not set
249# CONFIG_BT is not set
250# CONFIG_NETDEVICES is not set
251
252#
253# ISDN subsystem
254#
255# CONFIG_ISDN is not set
256
257#
258# Telephony Support
259#
260# CONFIG_PHONE is not set
261
262#
263# Input device support
264#
265CONFIG_INPUT=y
266
267#
268# Userland interfaces
269#
270# CONFIG_INPUT_MOUSEDEV is not set
271# CONFIG_INPUT_JOYDEV is not set
272# CONFIG_INPUT_TSDEV is not set
273# CONFIG_INPUT_EVDEV is not set
274# CONFIG_INPUT_EVBUG is not set
275
276#
277# Input I/O drivers
278#
279# CONFIG_GAMEPORT is not set
280CONFIG_SOUND_GAMEPORT=y
281# CONFIG_SERIO is not set
282# CONFIG_SERIO_I8042 is not set
283
284#
285# Input Device Drivers
286#
287# CONFIG_INPUT_KEYBOARD is not set
288# CONFIG_INPUT_MOUSE is not set
289# CONFIG_INPUT_JOYSTICK is not set
290# CONFIG_INPUT_TOUCHSCREEN is not set
291# CONFIG_INPUT_MISC is not set
292
293#
294# Character devices
295#
296CONFIG_VT=y
297CONFIG_VT_CONSOLE=y
298CONFIG_HW_CONSOLE=y
299# CONFIG_SERIAL_NONSTANDARD is not set
300
301#
302# Serial drivers
303#
304# CONFIG_SERIAL_8250 is not set
305
306#
307# Non-8250 serial port support
308#
309CONFIG_UNIX98_PTYS=y
310CONFIG_LEGACY_PTYS=y
311CONFIG_LEGACY_PTY_COUNT=256
312
313#
314# IPMI
315#
316# CONFIG_IPMI_HANDLER is not set
317
318#
319# Watchdog Cards
320#
321CONFIG_WATCHDOG=y
322CONFIG_WATCHDOG_NOWAYOUT=y
323
324#
325# Watchdog Device Drivers
326#
327CONFIG_SOFT_WATCHDOG=y
328# CONFIG_RTC is not set
329# CONFIG_GEN_RTC is not set
330# CONFIG_DTLK is not set
331# CONFIG_R3964 is not set
332
333#
334# Ftape, the floppy tape device driver
335#
336# CONFIG_DRM is not set
337# CONFIG_RAW_DRIVER is not set
338
339#
340# I2C support
341#
342# CONFIG_I2C is not set
343
344#
345# Dallas's 1-wire bus
346#
347# CONFIG_W1 is not set
348
349#
350# Misc devices
351#
352
353#
354# Multimedia devices
355#
356# CONFIG_VIDEO_DEV is not set
357
358#
359# Digital Video Broadcasting Devices
360#
361# CONFIG_DVB is not set
362
363#
364# Graphics support
365#
366# CONFIG_FB is not set
367
368#
369# Console display driver support
370#
371# CONFIG_VGA_CONSOLE is not set
372CONFIG_DUMMY_CONSOLE=y
373# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
374
375#
376# Sound
377#
378# CONFIG_SOUND is not set
379
380#
381# USB support
382#
383# CONFIG_USB_ARCH_HAS_HCD is not set
384# CONFIG_USB_ARCH_HAS_OHCI is not set
385
386#
387# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
388#
389
390#
391# USB Gadget Support
392#
393# CONFIG_USB_GADGET is not set
394
395#
396# MMC/SD Card support
397#
398# CONFIG_MMC is not set
399
400#
401# InfiniBand support
402#
403# CONFIG_INFINIBAND is not set
404
405#
406# File systems
407#
408# CONFIG_EXT2_FS is not set
409# CONFIG_EXT3_FS is not set
410# CONFIG_JBD is not set
411# CONFIG_REISERFS_FS is not set
412# CONFIG_JFS_FS is not set
413# CONFIG_XFS_FS is not set
414# CONFIG_MINIX_FS is not set
415# CONFIG_ROMFS_FS is not set
416# CONFIG_QUOTA is not set
417# CONFIG_DNOTIFY is not set
418# CONFIG_AUTOFS_FS is not set
419# CONFIG_AUTOFS4_FS is not set
420
421#
422# CD-ROM/DVD Filesystems
423#
424# CONFIG_ISO9660_FS is not set
425# CONFIG_UDF_FS is not set
426
427#
428# DOS/FAT/NT Filesystems
429#
430# CONFIG_MSDOS_FS is not set
431# CONFIG_VFAT_FS is not set
432# CONFIG_NTFS_FS is not set
433
434#
435# Pseudo filesystems
436#
437CONFIG_PROC_FS=y
438CONFIG_PROC_KCORE=y
439CONFIG_SYSFS=y
440CONFIG_DEVFS_FS=y
441CONFIG_DEVFS_MOUNT=y
442# CONFIG_DEVFS_DEBUG is not set
443# CONFIG_DEVPTS_FS_XATTR is not set
444CONFIG_TMPFS=y
445# CONFIG_TMPFS_XATTR is not set
446# CONFIG_HUGETLB_PAGE is not set
447CONFIG_RAMFS=y
448
449#
450# Miscellaneous filesystems
451#
452# CONFIG_ADFS_FS is not set
453# CONFIG_AFFS_FS is not set
454# CONFIG_HFS_FS is not set
455# CONFIG_HFSPLUS_FS is not set
456# CONFIG_BEFS_FS is not set
457# CONFIG_BFS_FS is not set
458# CONFIG_EFS_FS is not set
459# CONFIG_CRAMFS is not set
460# CONFIG_VXFS_FS is not set
461# CONFIG_HPFS_FS is not set
462# CONFIG_QNX4FS_FS is not set
463# CONFIG_SYSV_FS is not set
464# CONFIG_UFS_FS is not set
465
466#
467# Network File Systems
468#
469CONFIG_NFS_FS=y
470CONFIG_NFS_V3=y
471# CONFIG_NFS_V4 is not set
472CONFIG_NFS_DIRECTIO=y
473# CONFIG_NFSD is not set
474CONFIG_ROOT_NFS=y
475CONFIG_LOCKD=y
476CONFIG_LOCKD_V4=y
477# CONFIG_EXPORTFS is not set
478CONFIG_SUNRPC=y
479# CONFIG_RPCSEC_GSS_KRB5 is not set
480# CONFIG_RPCSEC_GSS_SPKM3 is not set
481# CONFIG_SMB_FS is not set
482# CONFIG_CIFS is not set
483# CONFIG_NCP_FS is not set
484# CONFIG_CODA_FS is not set
485# CONFIG_AFS_FS is not set
486
487#
488# Partition Types
489#
490# CONFIG_PARTITION_ADVANCED is not set
491CONFIG_MSDOS_PARTITION=y
492
493#
494# Native Language Support
495#
496# CONFIG_NLS is not set
497
498#
499# Kernel hacking
500#
501CONFIG_DEBUG_KERNEL=y
502# CONFIG_DEBUG_STACKOVERFLOW is not set
503# CONFIG_DEBUG_SLAB is not set
504# CONFIG_MAGIC_SYSRQ is not set
505# CONFIG_DEBUG_SPINLOCK is not set
506# CONFIG_DEBUG_PAGEALLOC is not set
507# CONFIG_DEBUG_INFO is not set
508# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
509# CONFIG_KGDB is not set
510
511#
512# Security options
513#
514# CONFIG_KEYS is not set
515# CONFIG_SECURITY is not set
516
517#
518# Cryptographic options
519#
520# CONFIG_CRYPTO is not set
521
522#
523# Hardware crypto devices
524#
525
526#
527# Library routines
528#
529# CONFIG_CRC_CCITT is not set
530# CONFIG_CRC32 is not set
531# CONFIG_LIBCRC32C is not set
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
new file mode 100644
index 000000000000..d573017a5dde
--- /dev/null
+++ b/arch/xtensa/kernel/Makefile
@@ -0,0 +1,18 @@
1#
2# Makefile for the Linux/Xtensa kernel.
3#
4
5extra-y := head.o vmlinux.lds
6
7
8obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o semaphore.o \
9 setup.o signal.o syscalls.o time.o traps.o vectors.o platform.o \
10 pci-dma.o
11
12## windowspill.o
13
14obj-$(CONFIG_KGDB) += xtensa-stub.o
15obj-$(CONFIG_PCI) += pci.o
16obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
17
18
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S
new file mode 100644
index 000000000000..74b1e90ef08c
--- /dev/null
+++ b/arch/xtensa/kernel/align.S
@@ -0,0 +1,459 @@
1/*
2 * arch/xtensa/kernel/align.S
3 *
4 * Handle unalignment exceptions in kernel space.
5 *
6 * This file is subject to the terms and conditions of the GNU General
7 * Public License. See the file "COPYING" in the main directory of
8 * this archive for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica, Inc.
11 *
12 * Rewritten by Chris Zankel <chris@zankel.net>
13 *
14 * Based on work from Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
15 * and Marc Gauthier <marc@tensilica.com, marc@alimni.uwaterloo.ca>
16 */
17
18#include <linux/linkage.h>
19#include <asm/ptrace.h>
20#include <asm/ptrace.h>
21#include <asm/current.h>
22#include <asm/offsets.h>
23#include <asm/pgtable.h>
24#include <asm/processor.h>
25#include <asm/page.h>
26#include <asm/thread_info.h>
27
28#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
29
30/* First-level exception handler for unaligned exceptions.
31 *
32 * Note: This handler works only for kernel exceptions. Unaligned user
33 * access should get a seg fault.
34 */
35
36/* Big and little endian 16-bit values are located in
37 * different halves of a register. HWORD_START helps to
38 * abstract the notion of extracting a 16-bit value from a
39 * register.
40 * We also have to define new shifting instructions because
41 * lsb and msb are on 'opposite' ends in a register for
42 * different endian machines.
43 *
44 * Assume a memory region in ascending address:
45 * 0 1 2 3|4 5 6 7
46 *
47 * When loading one word into a register, the content of that register is:
48 * LE 3 2 1 0, 7 6 5 4
49 * BE 0 1 2 3, 4 5 6 7
50 *
51 * Masking the bits of the higher/lower address means:
52 * LE X X 0 0, 0 0 X X
53 * BE 0 0 X X, X X 0 0
54 *
55 * Shifting to higher/lower addresses, means:
56 * LE shift left / shift right
57 * BE shift right / shift left
58 *
59 * Extracting 16 bits from a 32 bit reg. value to higher/lower address means:
60 * LE mask 0 0 X X / shift left
61 * BE shift left / mask 0 0 X X
62 */
63
64#define UNALIGNED_USER_EXCEPTION
65
66#if XCHAL_HAVE_BE
67
68#define HWORD_START 16
69#define INSN_OP0 28
70#define INSN_T 24
71#define INSN_OP1 16
72
73.macro __src_b r, w0, w1; src \r, \w0, \w1; .endm
74.macro __ssa8 r; ssa8b \r; .endm
75.macro __ssa8r r; ssa8l \r; .endm
76.macro __sh r, s; srl \r, \s; .endm
77.macro __sl r, s; sll \r, \s; .endm
78.macro __exth r, s; extui \r, \s, 0, 16; .endm
79.macro __extl r, s; slli \r, \s, 16; .endm
80
81#else
82
83#define HWORD_START 0
84#define INSN_OP0 0
85#define INSN_T 4
86#define INSN_OP1 12
87
88.macro __src_b r, w0, w1; src \r, \w1, \w0; .endm
89.macro __ssa8 r; ssa8l \r; .endm
90.macro __ssa8r r; ssa8b \r; .endm
91.macro __sh r, s; sll \r, \s; .endm
92.macro __sl r, s; srl \r, \s; .endm
93.macro __exth r, s; slli \r, \s, 16; .endm
94.macro __extl r, s; extui \r, \s, 0, 16; .endm
95
96#endif
97
98/*
99 * xxxx xxxx = imm8 field
100 * yyyy = imm4 field
101 * ssss = s field
102 * tttt = t field
103 *
104 * 16 0
105 * -------------------
106 * L32I.N yyyy ssss tttt 1000
107 * S32I.N yyyy ssss tttt 1001
108 *
109 * 23 0
110 * -----------------------------
111 * res 0000 0010
112 * L16UI xxxx xxxx 0001 ssss tttt 0010
113 * L32I xxxx xxxx 0010 ssss tttt 0010
114 * XXX 0011 ssss tttt 0010
115 * XXX 0100 ssss tttt 0010
116 * S16I xxxx xxxx 0101 ssss tttt 0010
117 * S32I xxxx xxxx 0110 ssss tttt 0010
118 * XXX 0111 ssss tttt 0010
119 * XXX 1000 ssss tttt 0010
120 * L16SI xxxx xxxx 1001 ssss tttt 0010
121 * XXX 1010 0010
122 * **L32AI xxxx xxxx 1011 ssss tttt 0010 unsupported
123 * XXX 1100 0010
124 * XXX 1101 0010
125 * XXX 1110 0010
126 * **S32RI xxxx xxxx 1111 ssss tttt 0010 unsupported
127 * -----------------------------
128 * ^ ^ ^
129 * sub-opcode (NIBBLE_R) -+ | |
130 * t field (NIBBLE_T) -----------+ |
131 * major opcode (NIBBLE_OP0) --------------+
132 */
133
134#define OP0_L32I_N 0x8 /* load immediate narrow */
135#define OP0_S32I_N 0x9 /* store immediate narrow */
136#define OP1_SI_MASK 0x4 /* OP1 bit set for stores */
137#define OP1_SI_BIT 2 /* OP1 bit number for stores */
138
139#define OP1_L32I 0x2
140#define OP1_L16UI 0x1
141#define OP1_L16SI 0x9
142#define OP1_L32AI 0xb
143
144#define OP1_S32I 0x6
145#define OP1_S16I 0x5
146#define OP1_S32RI 0xf
147
148/*
149 * Entry condition:
150 *
151 * a0: trashed, original value saved on stack (PT_AREG0)
152 * a1: a1
153 * a2: new stack pointer, original in DEPC
154 * a3: dispatch table
155 * depc: a2, original value saved on stack (PT_DEPC)
156 * excsave_1: a3
157 *
158 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
159 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
160 */
161
162
163ENTRY(fast_unaligned)
164
165 /* Note: We don't expect the address to be aligned on a word
166 * boundary. After all, the processor generated that exception
167 * and it would be a hardware fault.
168 */
169
170 /* Save some working register */
171
172 s32i a4, a2, PT_AREG4
173 s32i a5, a2, PT_AREG5
174 s32i a6, a2, PT_AREG6
175 s32i a7, a2, PT_AREG7
176 s32i a8, a2, PT_AREG8
177
178 rsr a0, DEPC
179 xsr a3, EXCSAVE_1
180 s32i a0, a2, PT_AREG2
181 s32i a3, a2, PT_AREG3
182
183 /* Keep value of SAR in a0 */
184
185 rsr a0, SAR
186 rsr a8, EXCVADDR # load unaligned memory address
187
188 /* Now, identify one of the following load/store instructions.
189 *
190 * The only possible danger of a double exception on the
191 * following l32i instructions is kernel code in vmalloc
192 * memory. The processor was just executing at the EPC_1
193 * address, and indeed, already fetched the instruction. That
194 * guarantees a TLB mapping, which hasn't been replaced by
195 * this unaligned exception handler that uses only static TLB
196 * mappings. However, high-level interrupt handlers might
197 * modify TLB entries, so for the generic case, we register a
198 * TABLE_FIXUP handler here, too.
199 */
200
201 /* a3...a6 saved on stack, a2 = SP */
202
203 /* Extract the instruction that caused the unaligned access. */
204
205 rsr a7, EPC_1 # load exception address
206 movi a3, ~3
207 and a3, a3, a7 # mask lower bits
208
209 l32i a4, a3, 0 # load 2 words
210 l32i a5, a3, 4
211
212 __ssa8 a7
213 __src_b a4, a4, a5 # a4 has the instruction
214
215 /* Analyze the instruction (load or store?). */
216
217 extui a5, a4, INSN_OP0, 4 # get insn.op0 nibble
218
219#if XCHAL_HAVE_NARROW
220 _beqi a5, OP0_L32I_N, .Lload # L32I.N, jump
221 addi a6, a5, -OP0_S32I_N
222 _beqz a6, .Lstore # S32I.N, do a store
223#endif
224 /* 'store indicator bit' not set, jump */
225 _bbci.l a4, OP1_SI_BIT + INSN_OP1, .Lload
226
227 /* Store: Jump to table entry to get the value in the source register.*/
228
229.Lstore:movi a5, .Lstore_table # table
230 extui a6, a4, INSN_T, 4 # get source register
231 addx8 a5, a6, a5
232 jx a5 # jump into table
233
234 /* Invalid instruction, CRITICAL! */
235.Linvalid_instruction_load:
236 j .Linvalid_instruction
237
238 /* Load: Load memory address. */
239
240.Lload: movi a3, ~3
241 and a3, a3, a8 # align memory address
242
243 __ssa8 a8
244#ifdef UNALIGNED_USER_EXCEPTION
245 addi a3, a3, 8
246 l32e a5, a3, -8
247 l32e a6, a3, -4
248#else
249 l32i a5, a3, 0
250 l32i a6, a3, 4
251#endif
252 __src_b a3, a5, a6 # a3 has the data word
253
254#if XCHAL_HAVE_NARROW
255 addi a7, a7, 2 # increment PC (assume 16-bit insn)
256
257 extui a5, a4, INSN_OP0, 4
258 _beqi a5, OP0_L32I_N, 1f # l32i.n: jump
259
260 addi a7, a7, 1
261#else
262 addi a7, a7, 3
263#endif
264
265 extui a5, a4, INSN_OP1, 4
266 _beqi a5, OP1_L32I, 1f # l32i: jump
267
268 extui a3, a3, 0, 16 # extract lower 16 bits
269 _beqi a5, OP1_L16UI, 1f
270 addi a5, a5, -OP1_L16SI
271 _bnez a5, .Linvalid_instruction_load
272
273 /* sign extend value */
274
275 slli a3, a3, 16
276 srai a3, a3, 16
277
278 /* Set target register. */
279
2801:
281
282#if XCHAL_HAVE_LOOP
283 rsr a3, LEND # check if we reached LEND
284 bne a7, a3, 1f
285 rsr a3, LCOUNT # and LCOUNT != 0
286 beqz a3, 1f
287 addi a3, a3, -1 # decrement LCOUNT and set
288 rsr a7, LBEG # set PC to LBEGIN
289 wsr a3, LCOUNT
290#endif
291
2921: wsr a7, EPC_1 # skip load instruction
293 extui a4, a4, INSN_T, 4 # extract target register
294 movi a5, .Lload_table
295 addx8 a4, a4, a5
296 jx a4 # jump to entry for target register
297
298 .align 8
299.Lload_table:
300 s32i a3, a2, PT_AREG0; _j .Lexit; .align 8
301 mov a1, a3; _j .Lexit; .align 8 # fishy??
302 s32i a3, a2, PT_AREG2; _j .Lexit; .align 8
303 s32i a3, a2, PT_AREG3; _j .Lexit; .align 8
304 s32i a3, a2, PT_AREG4; _j .Lexit; .align 8
305 s32i a3, a2, PT_AREG5; _j .Lexit; .align 8
306 s32i a3, a2, PT_AREG6; _j .Lexit; .align 8
307 s32i a3, a2, PT_AREG7; _j .Lexit; .align 8
308 s32i a3, a2, PT_AREG8; _j .Lexit; .align 8
309 mov a9, a3 ; _j .Lexit; .align 8
310 mov a10, a3 ; _j .Lexit; .align 8
311 mov a11, a3 ; _j .Lexit; .align 8
312 mov a12, a3 ; _j .Lexit; .align 8
313 mov a13, a3 ; _j .Lexit; .align 8
314 mov a14, a3 ; _j .Lexit; .align 8
315 mov a15, a3 ; _j .Lexit; .align 8
316
317.Lstore_table:
318 l32i a3, a2, PT_AREG0; _j 1f; .align 8
319 mov a3, a1; _j 1f; .align 8 # fishy??
320 l32i a3, a2, PT_AREG2; _j 1f; .align 8
321 l32i a3, a2, PT_AREG3; _j 1f; .align 8
322 l32i a3, a2, PT_AREG4; _j 1f; .align 8
323 l32i a3, a2, PT_AREG5; _j 1f; .align 8
324 l32i a3, a2, PT_AREG6; _j 1f; .align 8
325 l32i a3, a2, PT_AREG7; _j 1f; .align 8
326 l32i a3, a2, PT_AREG8; _j 1f; .align 8
327 mov a3, a9 ; _j 1f; .align 8
328 mov a3, a10 ; _j 1f; .align 8
329 mov a3, a11 ; _j 1f; .align 8
330 mov a3, a12 ; _j 1f; .align 8
331 mov a3, a13 ; _j 1f; .align 8
332 mov a3, a14 ; _j 1f; .align 8
333 mov a3, a15 ; _j 1f; .align 8
334
3351: # a7: instruction pointer, a4: instruction, a3: value
336
337 movi a6, 0 # mask: ffffffff:00000000
338
339#if XCHAL_HAVE_NARROW
340 addi a7, a7, 2 # incr. PC,assume 16-bit instruction
341
342 extui a5, a4, INSN_OP0, 4 # extract OP0
343 addi a5, a5, -OP0_S32I_N
344 _beqz a5, 1f # s32i.n: jump
345
346 addi a7, a7, 1 # increment PC, 32-bit instruction
347#else
348 addi a7, a7, 3 # increment PC, 32-bit instruction
349#endif
350
351 extui a5, a4, INSN_OP1, 4 # extract OP1
352 _beqi a5, OP1_S32I, 1f # jump if 32 bit store
353 _bnei a5, OP1_S16I, .Linvalid_instruction_store
354
355 movi a5, -1
356 __extl a3, a3 # get 16-bit value
357 __exth a6, a5 # get 16-bit mask ffffffff:ffff0000
358
359 /* Get memory address */
360
3611:
362#if XCHAL_HAVE_LOOP
363 rsr a3, LEND # check if we reached LEND
364 bne a7, a3, 1f
365 rsr a3, LCOUNT # and LCOUNT != 0
366 beqz a3, 1f
367 addi a3, a3, -1 # decrement LCOUNT and set
368 rsr a7, LBEG # set PC to LBEGIN
369 wsr a3, LCOUNT
370#endif
371
3721: wsr a7, EPC_1 # skip store instruction
373 movi a4, ~3
374 and a4, a4, a8 # align memory address
375
376 /* Insert value into memory */
377
378 movi a5, -1 # mask: ffffffff:XXXX0000
379#ifdef UNALIGNED_USER_EXCEPTION
380 addi a4, a4, 8
381#endif
382
383 __ssa8r a8
384 __src_b a7, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE)
385 __src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE)
386#ifdef UNALIGNED_USER_EXCEPTION
387 l32e a5, a4, -8
388#else
389 l32i a5, a4, 0 # load lower address word
390#endif
391 and a5, a5, a7 # mask
392 __sh a7, a3 # shift value
393 or a5, a5, a7 # or with original value
394#ifdef UNALIGNED_USER_EXCEPTION
395 s32e a5, a4, -8
396 l32e a7, a4, -4
397#else
398 s32i a5, a4, 0 # store
399 l32i a7, a4, 4 # same for upper address word
400#endif
401 __sl a5, a3
402 and a6, a7, a6
403 or a6, a6, a5
404#ifdef UNALIGNED_USER_EXCEPTION
405 s32e a6, a4, -4
406#else
407 s32i a6, a4, 4
408#endif
409
410 /* Done. restore stack and return */
411
412.Lexit:
413 movi a4, 0
414 rsr a3, EXCSAVE_1
415 s32i a4, a3, EXC_TABLE_FIXUP
416
417 /* Restore working register */
418
419 l32i a7, a2, PT_AREG7
420 l32i a6, a2, PT_AREG6
421 l32i a5, a2, PT_AREG5
422 l32i a4, a2, PT_AREG4
423 l32i a3, a2, PT_AREG3
424
425 /* restore SAR and return */
426
427 wsr a0, SAR
428 l32i a0, a2, PT_AREG0
429 l32i a2, a2, PT_AREG2
430 rfe
431
432 /* We cannot handle this exception. */
433
434 .extern _kernel_exception
435.Linvalid_instruction_store:
436.Linvalid_instruction:
437
438 /* Restore a4...a8 and SAR, set SP, and jump to default exception. */
439
440 l32i a8, a2, PT_AREG8
441 l32i a7, a2, PT_AREG7
442 l32i a6, a2, PT_AREG6
443 l32i a5, a2, PT_AREG5
444 l32i a4, a2, PT_AREG4
445 wsr a0, SAR
446 mov a1, a2
447
448 rsr a0, PS
449 bbsi.l a2, PS_UM_SHIFT, 1f # jump if user mode
450
451 movi a0, _kernel_exception
452 jx a0
453
4541: movi a0, _user_exception
455 jx a0
456
457
458#endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */
459
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
new file mode 100644
index 000000000000..840cd9a1d3d2
--- /dev/null
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -0,0 +1,94 @@
1/*
2 * arch/xtensa/kernel/asm-offsets.c
3 *
4 * Generates definitions from c-type structures used by assembly sources.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 */
14
15#include <asm/processor.h>
16
17#include <linux/types.h>
18#include <linux/sched.h>
19#include <linux/stddef.h>
20#include <linux/thread_info.h>
21#include <linux/ptrace.h>
22#include <asm/ptrace.h>
23#include <asm/processor.h>
24#include <asm/uaccess.h>
25
26#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
27#define BLANK() asm volatile("\n->" : : )
28
29int main(void)
30{
31 /* struct pt_regs */
32 DEFINE(PT_PC, offsetof (struct pt_regs, pc));
33 DEFINE(PT_PS, offsetof (struct pt_regs, ps));
34 DEFINE(PT_DEPC, offsetof (struct pt_regs, depc));
35 DEFINE(PT_EXCCAUSE, offsetof (struct pt_regs, exccause));
36 DEFINE(PT_EXCVADDR, offsetof (struct pt_regs, excvaddr));
37 DEFINE(PT_DEBUGCAUSE, offsetof (struct pt_regs, debugcause));
38 DEFINE(PT_WMASK, offsetof (struct pt_regs, wmask));
39 DEFINE(PT_LBEG, offsetof (struct pt_regs, lbeg));
40 DEFINE(PT_LEND, offsetof (struct pt_regs, lend));
41 DEFINE(PT_LCOUNT, offsetof (struct pt_regs, lcount));
42 DEFINE(PT_SAR, offsetof (struct pt_regs, sar));
43 DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall));
44 DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0]));
45 DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0]));
46 DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1]));
47 DEFINE(PT_AREG2, offsetof (struct pt_regs, areg[2]));
48 DEFINE(PT_AREG3, offsetof (struct pt_regs, areg[3]));
49 DEFINE(PT_AREG4, offsetof (struct pt_regs, areg[4]));
50 DEFINE(PT_AREG5, offsetof (struct pt_regs, areg[5]));
51 DEFINE(PT_AREG6, offsetof (struct pt_regs, areg[6]));
52 DEFINE(PT_AREG7, offsetof (struct pt_regs, areg[7]));
53 DEFINE(PT_AREG8, offsetof (struct pt_regs, areg[8]));
54 DEFINE(PT_AREG9, offsetof (struct pt_regs, areg[9]));
55 DEFINE(PT_AREG10, offsetof (struct pt_regs, areg[10]));
56 DEFINE(PT_AREG11, offsetof (struct pt_regs, areg[11]));
57 DEFINE(PT_AREG12, offsetof (struct pt_regs, areg[12]));
58 DEFINE(PT_AREG13, offsetof (struct pt_regs, areg[13]));
59 DEFINE(PT_AREG14, offsetof (struct pt_regs, areg[14]));
60 DEFINE(PT_AREG15, offsetof (struct pt_regs, areg[15]));
61 DEFINE(PT_WINDOWBASE, offsetof (struct pt_regs, windowbase));
62 DEFINE(PT_WINDOWSTART, offsetof(struct pt_regs, windowstart));
63 DEFINE(PT_SIZE, sizeof(struct pt_regs));
64 DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
65 DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
66 BLANK();
67
68 /* struct task_struct */
69 DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
70 DEFINE(TASK_MM, offsetof (struct task_struct, mm));
71 DEFINE(TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm));
72 DEFINE(TASK_PID, offsetof (struct task_struct, pid));
73 DEFINE(TASK_THREAD, offsetof (struct task_struct, thread));
74 DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, thread_info));
75 DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct));
76 BLANK();
77
78 /* struct thread_info (offset from start_struct) */
79 DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
80 DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
81 DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
82 DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
83 BLANK();
84
85 /* struct mm_struct */
86 DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
87 DEFINE(MM_PGD, offsetof (struct mm_struct, pgd));
88 DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context));
89 BLANK();
90 DEFINE(PT_SINGLESTEP_BIT, PT_SINGLESTEP_BIT);
91 return 0;
92}
93
94
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
new file mode 100644
index 000000000000..356192a4d39d
--- /dev/null
+++ b/arch/xtensa/kernel/coprocessor.S
@@ -0,0 +1,201 @@
1/*
2 * arch/xtensa/kernel/coprocessor.S
3 *
4 * Xtensa processor configuration-specific table of coprocessor and
5 * other custom register layout information.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Copyright (C) 2003 - 2005 Tensilica Inc.
12 *
13 * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca>
14 */
15
16/*
17 * This module contains a table that describes the layout of the various
18 * custom registers and states associated with each coprocessor, as well
19 * as those not associated with any coprocessor ("extra state").
20 * This table is included with core dumps and is available via the ptrace
21 * interface, allowing the layout of such register/state information to
22 * be modified in the kernel without affecting the debugger. Each
23 * register or state is identified using a 32-bit "libdb target number"
24 * assigned when the Xtensa processor is generated.
25 */
26
27#include <linux/config.h>
28#include <linux/linkage.h>
29#include <asm/processor.h>
30
31#if XCHAL_HAVE_CP
32
33#define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE)
34
35ENTRY(release_coprocessors)
36
37 entry a1, 16
38 # a2: task
39 movi a3, 1 << XCHAL_CP_MAX # a3: coprocessor-bit
40 movi a4, coprocessor_info+CP_LAST # a4: owner-table
41 # a5: tmp
42 movi a6, 0 # a6: 0
43 rsil a7, LOCKLEVEL # a7: PS
44
451: /* Check if task is coprocessor owner of coprocessor[i]. */
46
47 l32i a5, a4, COPROCESSOR_INFO_OWNER
48 srli a3, a3, 1
49 beqz a3, 1f
50 addi a4, a4, -8
51 beq a2, a5, 1b
52
53 /* Found an entry: Clear entry CPENABLE bit to disable CP. */
54
55 rsr a5, CPENABLE
56 s32i a6, a4, COPROCESSOR_INFO_OWNER
57 xor a5, a3, a5
58 wsr a5, CPENABLE
59
60 bnez a3, 1b
61
621: wsr a7, PS
63 rsync
64 retw
65
66
67ENTRY(disable_coprocessor)
68 entry sp, 16
69 rsil a7, LOCKLEVEL
70 rsr a3, CPENABLE
71 movi a4, 1
72 ssl a2
73 sll a4, a4
74 and a4, a3, a4
75 xor a3, a3, a4
76 wsr a3, CPENABLE
77 wsr a7, PS
78 rsync
79 retw
80
81ENTRY(enable_coprocessor)
82 entry sp, 16
83 rsil a7, LOCKLEVEL
84 rsr a3, CPENABLE
85 movi a4, 1
86 ssl a2
87 sll a4, a4
88 or a3, a3, a4
89 wsr a3, CPENABLE
90 wsr a7, PS
91 rsync
92 retw
93
94#endif
95
96ENTRY(save_coprocessor_extra)
97 entry sp, 16
98 xchal_extra_store_funcbody
99 retw
100
101ENTRY(restore_coprocessor_extra)
102 entry sp, 16
103 xchal_extra_load_funcbody
104 retw
105
106ENTRY(save_coprocessor_registers)
107 entry sp, 16
108 xchal_cpi_store_funcbody
109 retw
110
111ENTRY(restore_coprocessor_registers)
112 entry sp, 16
113 xchal_cpi_load_funcbody
114 retw
115
116
117/*
118 * The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros
119 * describe the contents of coprocessor & extra save areas in terms of
120 * undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros. We define these
121 * latter macros here; they expand into a table of the format we want.
122 * The general format is:
123 *
124 * CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum,
125 * bitmask, rsv2, rsv3)
126 * CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum,
127 * bitmask, rsv2, rsv3)
128 * CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index,
129 * numentries, contentsize, regname_base,
130 * regfile_name, rsv2, rsv3)
131 *
132 * For this table, we only care about the <libdbnum>, <offset> and <size>
133 * fields.
134 */
135
136/* Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below: */
137
138#define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum, \
139 bitmask, rsv2, rsv3) \
140 reg_entry libdbnum, offset, size ;
141#define CONTENTS_LIBDB_UREG(libdbnum,offset,size,align,rsv1,name,uregnum, \
142 bitmask, rsv2, rsv3) \
143 reg_entry libdbnum, offset, size ;
144#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, \
145 numentries, contentsize, regname_base, \
146 regfile_name, rsv2, rsv3) \
147 reg_entry libdbnum, offset, size ;
148
149/* A single table entry: */
150 .macro reg_entry libdbnum, offset, size
151 .ifne (__last_offset-(__last_group_offset+\offset))
152 /* padding entry */
153 .word (0xFC000000+__last_offset-(__last_group_offset+\offset))
154 .endif
155 .word \libdbnum /* actual entry */
156 .set __last_offset, __last_group_offset+\offset+\size
157 .endm /* reg_entry */
158
159
160/* Table entry that marks the beginning of a group (coprocessor or "extra"): */
161 .macro reg_group cpnum, num_entries, align
162 .set __last_group_offset, (__last_offset + \align- 1) & -\align
163 .ifne \num_entries
164 .word 0xFD000000+(\cpnum<<16)+\num_entries
165 .endif
166 .endm /* reg_group */
167
168/*
169 * Register info tables.
170 */
171
172 .section .rodata, "a"
173 .globl _xtensa_reginfo_tables
174 .globl _xtensa_reginfo_table_size
175 .align 4
176_xtensa_reginfo_table_size:
177 .word _xtensa_reginfo_table_end - _xtensa_reginfo_tables
178
179_xtensa_reginfo_tables:
180 .set __last_offset, 0
181 reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN
182 XCHAL_EXTRA_SA_CONTENTS_LIBDB
183 reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN
184 XCHAL_CP0_SA_CONTENTS_LIBDB
185 reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN
186 XCHAL_CP1_SA_CONTENTS_LIBDB
187 reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN
188 XCHAL_CP2_SA_CONTENTS_LIBDB
189 reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN
190 XCHAL_CP3_SA_CONTENTS_LIBDB
191 reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN
192 XCHAL_CP4_SA_CONTENTS_LIBDB
193 reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN
194 XCHAL_CP5_SA_CONTENTS_LIBDB
195 reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN
196 XCHAL_CP6_SA_CONTENTS_LIBDB
197 reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN
198 XCHAL_CP7_SA_CONTENTS_LIBDB
199 .word 0xFC000000 /* invalid register number,marks end of table*/
200_xtensa_reginfo_table_end:
201
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
new file mode 100644
index 000000000000..c64a01f71de6
--- /dev/null
+++ b/arch/xtensa/kernel/entry.S
@@ -0,0 +1,1996 @@
1/*
2 * arch/xtensa/kernel/entry.S
3 *
4 * Low-level exception handling
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2004-2005 by Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 *
14 */
15
16#include <linux/linkage.h>
17#include <asm/offsets.h>
18#include <asm/processor.h>
19#include <asm/thread_info.h>
20#include <asm/uaccess.h>
21#include <asm/unistd.h>
22#include <asm/ptrace.h>
23#include <asm/current.h>
24#include <asm/pgtable.h>
25#include <asm/page.h>
26#include <asm/signal.h>
27#include <xtensa/coreasm.h>
28
29/* Unimplemented features. */
30
31#undef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
32#undef KERNEL_STACK_OVERFLOW_CHECK
33#undef PREEMPTIBLE_KERNEL
34#undef ALLOCA_EXCEPTION_IN_IRAM
35
36/* Not well tested.
37 *
38 * - fast_coprocessor
39 */
40
41/*
42 * Macro to find first bit set in WINDOWBASE from the left + 1
43 *
44 * 100....0 -> 1
45 * 010....0 -> 2
46 * 000....1 -> WSBITS
47 */
48
49 .macro ffs_ws bit mask
50
51#if XCHAL_HAVE_NSA
52 nsau \bit, \mask # 32-WSBITS ... 31 (32 iff 0)
53 addi \bit, \bit, WSBITS - 32 + 1 # uppest bit set -> return 1
54#else
55 movi \bit, WSBITS
56#if WSBITS > 16
57 _bltui \mask, 0x10000, 99f
58 addi \bit, \bit, -16
59 extui \mask, \mask, 16, 16
60#endif
61#if WSBITS > 8
6299: _bltui \mask, 0x100, 99f
63 addi \bit, \bit, -8
64 srli \mask, \mask, 8
65#endif
6699: _bltui \mask, 0x10, 99f
67 addi \bit, \bit, -4
68 srli \mask, \mask, 4
6999: _bltui \mask, 0x4, 99f
70 addi \bit, \bit, -2
71 srli \mask, \mask, 2
7299: _bltui \mask, 0x2, 99f
73 addi \bit, \bit, -1
7499:
75
76#endif
77 .endm
78
79/* ----------------- DEFAULT FIRST LEVEL EXCEPTION HANDLERS ----------------- */
80
81/*
82 * First-level exception handler for user exceptions.
83 * Save some special registers, extra states and all registers in the AR
84 * register file that were in use in the user task, and jump to the common
85 * exception code.
86 * We save SAR (used to calculate WMASK), and WB and WS (we don't have to
87 * save them for kernel exceptions).
88 *
89 * Entry condition for user_exception:
90 *
91 * a0: trashed, original value saved on stack (PT_AREG0)
92 * a1: a1
93 * a2: new stack pointer, original value in depc
94 * a3: dispatch table
95 * depc: a2, original value saved on stack (PT_DEPC)
96 * excsave1: a3
97 *
98 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
99 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
100 *
101 * Entry condition for _user_exception:
102 *
103 * a0-a3 and depc have been saved to PT_AREG0...PT_AREG3 and PT_DEPC
104 * excsave has been restored, and
105 * stack pointer (a1) has been set.
106 *
107 * Note: _user_exception might be at an odd adress. Don't use call0..call12
108 */
109
110ENTRY(user_exception)
111
112 /* Save a2, a3, and depc, restore excsave_1 and set SP. */
113
114 xsr a3, EXCSAVE_1
115 rsr a0, DEPC
116 s32i a1, a2, PT_AREG1
117 s32i a0, a2, PT_AREG2
118 s32i a3, a2, PT_AREG3
119 mov a1, a2
120
121 .globl _user_exception
122_user_exception:
123
124 /* Save SAR and turn off single stepping */
125
126 movi a2, 0
127 rsr a3, SAR
128 wsr a2, ICOUNTLEVEL
129 s32i a3, a1, PT_SAR
130
131 /* Rotate ws so that the current windowbase is at bit0. */
132 /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
133
134 rsr a2, WINDOWBASE
135 rsr a3, WINDOWSTART
136 ssr a2
137 s32i a2, a1, PT_WINDOWBASE
138 s32i a3, a1, PT_WINDOWSTART
139 slli a2, a3, 32-WSBITS
140 src a2, a3, a2
141 srli a2, a2, 32-WSBITS
142 s32i a2, a1, PT_WMASK # needed for restoring registers
143
144 /* Save only live registers. */
145
146 _bbsi.l a2, 1, 1f
147 s32i a4, a1, PT_AREG4
148 s32i a5, a1, PT_AREG5
149 s32i a6, a1, PT_AREG6
150 s32i a7, a1, PT_AREG7
151 _bbsi.l a2, 2, 1f
152 s32i a8, a1, PT_AREG8
153 s32i a9, a1, PT_AREG9
154 s32i a10, a1, PT_AREG10
155 s32i a11, a1, PT_AREG11
156 _bbsi.l a2, 3, 1f
157 s32i a12, a1, PT_AREG12
158 s32i a13, a1, PT_AREG13
159 s32i a14, a1, PT_AREG14
160 s32i a15, a1, PT_AREG15
161 _bnei a2, 1, 1f # only one valid frame?
162
163 /* Only one valid frame, skip saving regs. */
164
165 j 2f
166
167 /* Save the remaining registers.
168 * We have to save all registers up to the first '1' from
169 * the right, except the current frame (bit 0).
170 * Assume a2 is: 001001000110001
171 * All regiser frames starting from the top fiel to the marked '1'
172 * must be saved.
173 */
174
1751: addi a3, a2, -1 # eliminate '1' in bit 0: yyyyxxww0
176 neg a3, a3 # yyyyxxww0 -> YYYYXXWW1+1
177 and a3, a3, a2 # max. only one bit is set
178
179 /* Find number of frames to save */
180
181 ffs_ws a0, a3 # number of frames to the '1' from left
182
183 /* Store information into WMASK:
184 * bits 0..3: xxx1 masked lower 4 bits of the rotated windowstart,
185 * bits 4...: number of valid 4-register frames
186 */
187
188 slli a3, a0, 4 # number of frames to save in bits 8..4
189 extui a2, a2, 0, 4 # mask for the first 16 registers
190 or a2, a3, a2
191 s32i a2, a1, PT_WMASK # needed when we restore the reg-file
192
193 /* Save 4 registers at a time */
194
1951: rotw -1
196 s32i a0, a5, PT_AREG_END - 16
197 s32i a1, a5, PT_AREG_END - 12
198 s32i a2, a5, PT_AREG_END - 8
199 s32i a3, a5, PT_AREG_END - 4
200 addi a0, a4, -1
201 addi a1, a5, -16
202 _bnez a0, 1b
203
204 /* WINDOWBASE still in SAR! */
205
206 rsr a2, SAR # original WINDOWBASE
207 movi a3, 1
208 ssl a2
209 sll a3, a3
210 wsr a3, WINDOWSTART # set corresponding WINDOWSTART bit
211 wsr a2, WINDOWBASE # and WINDOWSTART
212 rsync
213
214 /* We are back to the original stack pointer (a1) */
215
2162:
217#if XCHAL_EXTRA_SA_SIZE
218
219 /* For user exceptions, save the extra state into the user's TCB.
220 * Note: We must assume that xchal_extra_store_funcbody destroys a2..a15
221 */
222
223 GET_CURRENT(a2,a1)
224 addi a2, a2, THREAD_CP_SAVE
225 xchal_extra_store_funcbody
226#endif
227
228 /* Now, jump to the common exception handler. */
229
230 j common_exception
231
232
233/*
234 * First-level exit handler for kernel exceptions
235 * Save special registers and the live window frame.
236 * Note: Even though we changes the stack pointer, we don't have to do a
237 * MOVSP here, as we do that when we return from the exception.
238 * (See comment in the kernel exception exit code)
239 *
240 * Entry condition for kernel_exception:
241 *
242 * a0: trashed, original value saved on stack (PT_AREG0)
243 * a1: a1
244 * a2: new stack pointer, original in DEPC
245 * a3: dispatch table
246 * depc: a2, original value saved on stack (PT_DEPC)
247 * excsave_1: a3
248 *
249 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
250 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
251 *
252 * Entry condition for _kernel_exception:
253 *
254 * a0-a3 and depc have been saved to PT_AREG0...PT_AREG3 and PT_DEPC
255 * excsave has been restored, and
256 * stack pointer (a1) has been set.
257 *
258 * Note: _kernel_exception might be at an odd adress. Don't use call0..call12
259 */
260
261ENTRY(kernel_exception)
262
263 /* Save a0, a2, a3, DEPC and set SP. */
264
265 xsr a3, EXCSAVE_1 # restore a3, excsave_1
266 rsr a0, DEPC # get a2
267 s32i a1, a2, PT_AREG1
268 s32i a0, a2, PT_AREG2
269 s32i a3, a2, PT_AREG3
270 mov a1, a2
271
272 .globl _kernel_exception
273_kernel_exception:
274
275 /* Save SAR and turn off single stepping */
276
277 movi a2, 0
278 rsr a3, SAR
279 wsr a2, ICOUNTLEVEL
280 s32i a3, a1, PT_SAR
281
282 /* Rotate ws so that the current windowbase is at bit0. */
283 /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
284
285 rsr a2, WINDOWBASE # don't need to save these, we only
286 rsr a3, WINDOWSTART # need shifted windowstart: windowmask
287 ssr a2
288 slli a2, a3, 32-WSBITS
289 src a2, a3, a2
290 srli a2, a2, 32-WSBITS
291 s32i a2, a1, PT_WMASK # needed for kernel_exception_exit
292
293 /* Save only the live window-frame */
294
295 _bbsi.l a2, 1, 1f
296 s32i a4, a1, PT_AREG4
297 s32i a5, a1, PT_AREG5
298 s32i a6, a1, PT_AREG6
299 s32i a7, a1, PT_AREG7
300 _bbsi.l a2, 2, 1f
301 s32i a8, a1, PT_AREG8
302 s32i a9, a1, PT_AREG9
303 s32i a10, a1, PT_AREG10
304 s32i a11, a1, PT_AREG11
305 _bbsi.l a2, 3, 1f
306 s32i a12, a1, PT_AREG12
307 s32i a13, a1, PT_AREG13
308 s32i a14, a1, PT_AREG14
309 s32i a15, a1, PT_AREG15
310
3111:
312
313#ifdef KERNEL_STACK_OVERFLOW_CHECK
314
315 /* Stack overflow check, for debugging */
316 extui a2, a1, TASK_SIZE_BITS,XX
317 movi a3, SIZE??
318 _bge a2, a3, out_of_stack_panic
319
320#endif
321
322/*
323 * This is the common exception handler.
324 * We get here from the user exception handler or simply by falling through
325 * from the kernel exception handler.
326 * Save the remaining special registers, switch to kernel mode, and jump
327 * to the second-level exception handler.
328 *
329 */
330
331common_exception:
332
333 /* Save EXCVADDR, DEBUGCAUSE, and PC, and clear LCOUNT */
334
335 rsr a2, DEBUGCAUSE
336 rsr a3, EPC_1
337 s32i a2, a1, PT_DEBUGCAUSE
338 s32i a3, a1, PT_PC
339
340 rsr a3, EXCVADDR
341 movi a2, 0
342 s32i a3, a1, PT_EXCVADDR
343 xsr a2, LCOUNT
344 s32i a2, a1, PT_LCOUNT
345
346 /* It is now save to restore the EXC_TABLE_FIXUP variable. */
347
348 rsr a0, EXCCAUSE
349 movi a3, 0
350 rsr a2, EXCSAVE_1
351 s32i a0, a1, PT_EXCCAUSE
352 s32i a3, a2, EXC_TABLE_FIXUP
353
354 /* All unrecoverable states are saved on stack, now, and a1 is valid,
355 * so we can allow exceptions and interrupts (*) again.
356 * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X)
357 *
358 * (*) We only allow interrupts if PS.INTLEVEL was not set to 1 before
359 * (interrupts disabled) and if this exception is not an interrupt.
360 */
361
362 rsr a3, PS
363 addi a0, a0, -4
364 movi a2, 1
365 extui a3, a3, 0, 1 # a3 = PS.INTLEVEL[0]
366 moveqz a3, a2, a0 # a3 = 1 iff interrupt exception
367 movi a2, PS_WOE_MASK
368 or a3, a3, a2
369 rsr a0, EXCCAUSE
370 xsr a3, PS
371
372 s32i a3, a1, PT_PS # save ps
373
374 /* Save LBEG, LEND */
375
376 rsr a2, LBEG
377 rsr a3, LEND
378 s32i a2, a1, PT_LBEG
379 s32i a3, a1, PT_LEND
380
381 /* Go to second-level dispatcher. Set up parameters to pass to the
382 * exception handler and call the exception handler.
383 */
384
385 movi a4, exc_table
386 mov a6, a1 # pass stack frame
387 mov a7, a0 # pass EXCCAUSE
388 addx4 a4, a0, a4
389 l32i a4, a4, EXC_TABLE_DEFAULT # load handler
390
391 /* Call the second-level handler */
392
393 callx4 a4
394
395 /* Jump here for exception exit */
396
397common_exception_return:
398
399 /* Jump if we are returning from kernel exceptions. */
400
4011: l32i a3, a1, PT_PS
402 _bbsi.l a3, PS_UM_SHIFT, 2f
403 j kernel_exception_exit
404
405 /* Specific to a user exception exit:
406 * We need to check some flags for signal handling and rescheduling,
407 * and have to restore WB and WS, extra states, and all registers
408 * in the register file that were in use in the user task.
409 */
410
4112: wsr a3, PS /* disable interrupts */
412
413 /* Check for signals (keep interrupts disabled while we read TI_FLAGS)
414 * Note: PS.INTLEVEL = 0, PS.EXCM = 1
415 */
416
417 GET_THREAD_INFO(a2,a1)
418 l32i a4, a2, TI_FLAGS
419
420 /* Enable interrupts again.
421 * Note: When we get here, we certainly have handled any interrupts.
422 * (Hint: There is only one user exception frame on stack)
423 */
424
425 movi a3, PS_WOE_MASK
426
427 _bbsi.l a4, TIF_NEED_RESCHED, 3f
428 _bbci.l a4, TIF_SIGPENDING, 4f
429
430#ifndef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
431 l32i a4, a1, PT_DEPC
432 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
433#endif
434
435 /* Reenable interrupts and call do_signal() */
436
437 wsr a3, PS
438 movi a4, do_signal # int do_signal(struct pt_regs*, sigset_t*)
439 mov a6, a1
440 movi a7, 0
441 callx4 a4
442 j 1b
443
4443: /* Reenable interrupts and reschedule */
445
446 wsr a3, PS
447 movi a4, schedule # void schedule (void)
448 callx4 a4
449 j 1b
450
451 /* Restore the state of the task and return from the exception. */
452
453
454 /* If we are returning from a user exception, and the process
455 * to run next has PT_SINGLESTEP set, we want to setup
456 * ICOUNT and ICOUNTLEVEL to step one instruction.
457 * PT_SINGLESTEP is set by sys_ptrace (ptrace.c)
458 */
459
4604: /* a2 holds GET_CURRENT(a2,a1) */
461
462 l32i a3, a2, TI_TASK
463 l32i a3, a3, TASK_PTRACE
464 bbci.l a3, PT_SINGLESTEP_BIT, 1f # jump if single-step flag is not set
465
466 movi a3, -2 # PT_SINGLESTEP flag is set,
467 movi a4, 1 # icountlevel of 1 means it won't
468 wsr a3, ICOUNT # start counting until after rfe
469 wsr a4, ICOUNTLEVEL # so setup icount & icountlevel.
470 isync
471
4721:
473
474#if XCHAL_EXTRA_SA_SIZE
475
476 /* For user exceptions, restore the extra state from the user's TCB. */
477
478 /* Note: a2 still contains GET_CURRENT(a2,a1) */
479 addi a2, a2, THREAD_CP_SAVE
480 xchal_extra_load_funcbody
481
482 /* We must assume that xchal_extra_store_funcbody destroys
483 * registers a2..a15. FIXME, this list can eventually be
484 * reduced once real register requirements of the macro are
485 * finalized. */
486
487#endif /* XCHAL_EXTRA_SA_SIZE */
488
489
490 /* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */
491
492 l32i a2, a1, PT_WINDOWBASE
493 l32i a3, a1, PT_WINDOWSTART
494 wsr a1, DEPC # use DEPC as temp storage
495 wsr a3, WINDOWSTART # restore WINDOWSTART
496 ssr a2 # preserve user's WB in the SAR
497 wsr a2, WINDOWBASE # switch to user's saved WB
498 rsync
499 rsr a1, DEPC # restore stack pointer
500 l32i a2, a1, PT_WMASK # register frames saved (in bits 4...9)
501 rotw -1 # we restore a4..a7
502 _bltui a6, 16, 1f # only have to restore current window?
503
504 /* The working registers are a0 and a3. We are restoring to
505 * a4..a7. Be careful not to destroy what we have just restored.
506 * Note: wmask has the format YYYYM:
507 * Y: number of registers saved in groups of 4
508 * M: 4 bit mask of first 16 registers
509 */
510
511 mov a2, a6
512 mov a3, a5
513
5142: rotw -1 # a0..a3 become a4..a7
515 addi a3, a7, -4*4 # next iteration
516 addi a2, a6, -16 # decrementing Y in WMASK
517 l32i a4, a3, PT_AREG_END + 0
518 l32i a5, a3, PT_AREG_END + 4
519 l32i a6, a3, PT_AREG_END + 8
520 l32i a7, a3, PT_AREG_END + 12
521 _bgeui a2, 16, 2b
522
523 /* Clear unrestored registers (don't leak anything to user-land */
524
5251: rsr a0, WINDOWBASE
526 rsr a3, SAR
527 sub a3, a0, a3
528 beqz a3, 2f
529 extui a3, a3, 0, WBBITS
530
5311: rotw -1
532 addi a3, a7, -1
533 movi a4, 0
534 movi a5, 0
535 movi a6, 0
536 movi a7, 0
537 bgei a3, 1, 1b
538
539 /* We are back were we were when we started.
540 * Note: a2 still contains WMASK (if we've returned to the original
541 * frame where we had loaded a2), or at least the lower 4 bits
542 * (if we have restored WSBITS-1 frames).
543 */
544
5452: j common_exception_exit
546
547 /* This is the kernel exception exit.
548 * We avoided to do a MOVSP when we entered the exception, but we
549 * have to do it here.
550 */
551
552kernel_exception_exit:
553
554 /* Disable interrupts (a3 holds PT_PS) */
555
556 wsr a3, PS
557
558#ifdef PREEMPTIBLE_KERNEL
559
560#ifdef CONFIG_PREEMPT
561
562 /*
563 * Note: We've just returned from a call4, so we have
564 * at least 4 addt'l regs.
565 */
566
567 /* Check current_thread_info->preempt_count */
568
569 GET_THREAD_INFO(a2)
570 l32i a3, a2, TI_PREEMPT
571 bnez a3, 1f
572
573 l32i a2, a2, TI_FLAGS
574
5751:
576
577#endif
578
579#endif
580
581 /* Check if we have to do a movsp.
582 *
583 * We only have to do a movsp if the previous window-frame has
584 * been spilled to the *temporary* exception stack instead of the
585 * task's stack. This is the case if the corresponding bit in
586 * WINDOWSTART for the previous window-frame was set before
587 * (not spilled) but is zero now (spilled).
588 * If this bit is zero, all other bits except the one for the
589 * current window frame are also zero. So, we can use a simple test:
590 * 'and' WINDOWSTART and WINDOWSTART-1:
591 *
592 * (XXXXXX1[0]* - 1) AND XXXXXX1[0]* = XXXXXX0[0]*
593 *
594 * The result is zero only if one bit was set.
595 *
596 * (Note: We might have gone through several task switches before
597 * we come back to the current task, so WINDOWBASE might be
598 * different from the time the exception occurred.)
599 */
600
601 /* Test WINDOWSTART before and after the exception.
602 * We actually have WMASK, so we only have to test if it is 1 or not.
603 */
604
605 l32i a2, a1, PT_WMASK
606 _beqi a2, 1, common_exception_exit # Spilled before exception,jump
607
608 /* Test WINDOWSTART now. If spilled, do the movsp */
609
610 rsr a3, WINDOWSTART
611 addi a0, a3, -1
612 and a3, a3, a0
613 _bnez a3, common_exception_exit
614
615 /* Do a movsp (we returned from a call4, so we have at least a0..a7) */
616
617 addi a0, a1, -16
618 l32i a3, a0, 0
619 l32i a4, a0, 4
620 s32i a3, a1, PT_SIZE+0
621 s32i a4, a1, PT_SIZE+4
622 l32i a3, a0, 8
623 l32i a4, a0, 12
624 s32i a3, a1, PT_SIZE+8
625 s32i a4, a1, PT_SIZE+12
626
627 /* Common exception exit.
628 * We restore the special register and the current window frame, and
629 * return from the exception.
630 *
631 * Note: We expect a2 to hold PT_WMASK
632 */
633
634common_exception_exit:
635
636 _bbsi.l a2, 1, 1f
637 l32i a4, a1, PT_AREG4
638 l32i a5, a1, PT_AREG5
639 l32i a6, a1, PT_AREG6
640 l32i a7, a1, PT_AREG7
641 _bbsi.l a2, 2, 1f
642 l32i a8, a1, PT_AREG8
643 l32i a9, a1, PT_AREG9
644 l32i a10, a1, PT_AREG10
645 l32i a11, a1, PT_AREG11
646 _bbsi.l a2, 3, 1f
647 l32i a12, a1, PT_AREG12
648 l32i a13, a1, PT_AREG13
649 l32i a14, a1, PT_AREG14
650 l32i a15, a1, PT_AREG15
651
652 /* Restore PC, SAR */
653
6541: l32i a2, a1, PT_PC
655 l32i a3, a1, PT_SAR
656 wsr a2, EPC_1
657 wsr a3, SAR
658
659 /* Restore LBEG, LEND, LCOUNT */
660
661 l32i a2, a1, PT_LBEG
662 l32i a3, a1, PT_LEND
663 wsr a2, LBEG
664 l32i a2, a1, PT_LCOUNT
665 wsr a3, LEND
666 wsr a2, LCOUNT
667
668 /* Check if it was double exception. */
669
670 l32i a0, a1, PT_DEPC
671 l32i a3, a1, PT_AREG3
672 l32i a2, a1, PT_AREG2
673 _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
674
675 /* Restore a0...a3 and return */
676
677 l32i a0, a1, PT_AREG0
678 l32i a1, a1, PT_AREG1
679 rfe
680
6811: wsr a0, DEPC
682 l32i a0, a1, PT_AREG0
683 l32i a1, a1, PT_AREG1
684 rfde
685
686/*
687 * Debug exception handler.
688 *
689 * Currently, we don't support KGDB, so only user application can be debugged.
690 *
691 * When we get here, a0 is trashed and saved to excsave[debuglevel]
692 */
693
694ENTRY(debug_exception)
695
696 rsr a0, EPS + XCHAL_DEBUGLEVEL
697 bbsi.l a0, PS_EXCM_SHIFT, 1f # exception mode
698
699 /* Set EPC_1 and EXCCAUSE */
700
701 wsr a2, DEPC # save a2 temporarily
702 rsr a2, EPC + XCHAL_DEBUGLEVEL
703 wsr a2, EPC_1
704
705 movi a2, EXCCAUSE_MAPPED_DEBUG
706 wsr a2, EXCCAUSE
707
708 /* Restore PS to the value before the debug exc but with PS.EXCM set.*/
709
710 movi a2, 1 << PS_EXCM_SHIFT
711 or a2, a0, a2
712 movi a0, debug_exception # restore a3, debug jump vector
713 wsr a2, PS
714 xsr a0, EXCSAVE + XCHAL_DEBUGLEVEL
715
716 /* Switch to kernel/user stack, restore jump vector, and save a0 */
717
718 bbsi.l a2, PS_UM_SHIFT, 2f # jump if user mode
719
720 addi a2, a1, -16-PT_SIZE # assume kernel stack
721 s32i a0, a2, PT_AREG0
722 movi a0, 0
723 s32i a1, a2, PT_AREG1
724 s32i a0, a2, PT_DEPC # mark it as a regular exception
725 xsr a0, DEPC
726 s32i a3, a2, PT_AREG3
727 s32i a0, a2, PT_AREG2
728 mov a1, a2
729 j _kernel_exception
730
7312: rsr a2, EXCSAVE_1
732 l32i a2, a2, EXC_TABLE_KSTK # load kernel stack pointer
733 s32i a0, a2, PT_AREG0
734 movi a0, 0
735 s32i a1, a2, PT_AREG1
736 s32i a0, a2, PT_DEPC
737 xsr a0, DEPC
738 s32i a3, a2, PT_AREG3
739 s32i a0, a2, PT_AREG2
740 mov a1, a2
741 j _user_exception
742
743 /* Debug exception while in exception mode. */
7441: j 1b // FIXME!!
745
746
747/*
748 * We get here in case of an unrecoverable exception.
749 * The only thing we can do is to be nice and print a panic message.
750 * We only produce a single stack frame for panic, so ???
751 *
752 *
753 * Entry conditions:
754 *
755 * - a0 contains the caller address; original value saved in excsave1.
756 * - the original a0 contains a valid return address (backtrace) or 0.
757 * - a2 contains a valid stackpointer
758 *
759 * Notes:
760 *
761 * - If the stack pointer could be invalid, the caller has to setup a
762 * dummy stack pointer (e.g. the stack of the init_task)
763 *
764 * - If the return address could be invalid, the caller has to set it
765 * to 0, so the backtrace would stop.
766 *
767 */
768 .align 4
769unrecoverable_text:
770 .ascii "Unrecoverable error in exception handler\0"
771
772ENTRY(unrecoverable_exception)
773
774 movi a0, 1
775 movi a1, 0
776
777 wsr a0, WINDOWSTART
778 wsr a1, WINDOWBASE
779 rsync
780
781 movi a1, PS_WOE_MASK | 1
782 wsr a1, PS
783 rsync
784
785 movi a1, init_task
786 movi a0, 0
787 addi a1, a1, PT_REGS_OFFSET
788
789 movi a4, panic
790 movi a6, unrecoverable_text
791
792 callx4 a4
793
7941: j 1b
795
796
797/* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
798
799/*
800 * Fast-handler for alloca exceptions
801 *
802 * The ALLOCA handler is entered when user code executes the MOVSP
803 * instruction and the caller's frame is not in the register file.
804 * In this case, the caller frame's a0..a3 are on the stack just
805 * below sp (a1), and this handler moves them.
806 *
807 * For "MOVSP <ar>,<as>" without destination register a1, this routine
808 * simply moves the value from <as> to <ar> without moving the save area.
809 *
810 * Entry condition:
811 *
812 * a0: trashed, original value saved on stack (PT_AREG0)
813 * a1: a1
814 * a2: new stack pointer, original in DEPC
815 * a3: dispatch table
816 * depc: a2, original value saved on stack (PT_DEPC)
817 * excsave_1: a3
818 *
819 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
820 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
821 */
822
823#if XCHAL_HAVE_BE
824#define _EXTUI_MOVSP_SRC(ar) extui ar, ar, 4, 4
825#define _EXTUI_MOVSP_DST(ar) extui ar, ar, 0, 4
826#else
827#define _EXTUI_MOVSP_SRC(ar) extui ar, ar, 0, 4
828#define _EXTUI_MOVSP_DST(ar) extui ar, ar, 4, 4
829#endif
830
831ENTRY(fast_alloca)
832
833 /* We shouldn't be in a double exception. */
834
835 l32i a0, a2, PT_DEPC
836 _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lunhandled_double
837
838 rsr a0, DEPC # get a2
839 s32i a4, a2, PT_AREG4 # save a4 and
840 s32i a0, a2, PT_AREG2 # a2 to stack
841
842 /* Exit critical section. */
843
844 movi a0, 0
845 s32i a0, a3, EXC_TABLE_FIXUP
846
847 /* Restore a3, excsave_1 */
848
849 xsr a3, EXCSAVE_1 # make sure excsave_1 is valid for dbl.
850 rsr a4, EPC_1 # get exception address
851 s32i a3, a2, PT_AREG3 # save a3 to stack
852
853#ifdef ALLOCA_EXCEPTION_IN_IRAM
854#error iram not supported
855#else
856 /* Note: l8ui not allowed in IRAM/IROM!! */
857 l8ui a0, a4, 1 # read as(src) from MOVSP instruction
858#endif
859 movi a3, .Lmovsp_src
860 _EXTUI_MOVSP_SRC(a0) # extract source register number
861 addx8 a3, a0, a3
862 jx a3
863
864.Lunhandled_double:
865 wsr a0, EXCSAVE_1
866 movi a0, unrecoverable_exception
867 callx0 a0
868
869 .align 8
870.Lmovsp_src:
871 l32i a3, a2, PT_AREG0; _j 1f; .align 8
872 mov a3, a1; _j 1f; .align 8
873 l32i a3, a2, PT_AREG2; _j 1f; .align 8
874 l32i a3, a2, PT_AREG3; _j 1f; .align 8
875 l32i a3, a2, PT_AREG4; _j 1f; .align 8
876 mov a3, a5; _j 1f; .align 8
877 mov a3, a6; _j 1f; .align 8
878 mov a3, a7; _j 1f; .align 8
879 mov a3, a8; _j 1f; .align 8
880 mov a3, a9; _j 1f; .align 8
881 mov a3, a10; _j 1f; .align 8
882 mov a3, a11; _j 1f; .align 8
883 mov a3, a12; _j 1f; .align 8
884 mov a3, a13; _j 1f; .align 8
885 mov a3, a14; _j 1f; .align 8
886 mov a3, a15; _j 1f; .align 8
887
8881:
889
890#ifdef ALLOCA_EXCEPTION_IN_IRAM
891#error iram not supported
892#else
893 l8ui a0, a4, 0 # read ar(dst) from MOVSP instruction
894#endif
895 addi a4, a4, 3 # step over movsp
896 _EXTUI_MOVSP_DST(a0) # extract destination register
897 wsr a4, EPC_1 # save new epc_1
898
899 _bnei a0, 1, 1f # no 'movsp a1, ax': jump
900
901 /* Move the save area. This implies the use of the L32E
902 * and S32E instructions, because this move must be done with
903 * the user's PS.RING privilege levels, not with ring 0
904 * (kernel's) privileges currently active with PS.EXCM
905 * set. Note that we have stil registered a fixup routine with the
906 * double exception vector in case a double exception occurs.
907 */
908
909 /* a0,a4:avail a1:old user stack a2:exc. stack a3:new user stack. */
910
911 l32e a0, a1, -16
912 l32e a4, a1, -12
913 s32e a0, a3, -16
914 s32e a4, a3, -12
915 l32e a0, a1, -8
916 l32e a4, a1, -4
917 s32e a0, a3, -8
918 s32e a4, a3, -4
919
920 /* Restore stack-pointer and all the other saved registers. */
921
922 mov a1, a3
923
924 l32i a4, a2, PT_AREG4
925 l32i a3, a2, PT_AREG3
926 l32i a0, a2, PT_AREG0
927 l32i a2, a2, PT_AREG2
928 rfe
929
930 /* MOVSP <at>,<as> was invoked with <at> != a1.
931 * Because the stack pointer is not being modified,
932 * we should be able to just modify the pointer
933 * without moving any save area.
934 * The processor only traps these occurrences if the
935 * caller window isn't live, so unfortunately we can't
936 * use this as an alternate trap mechanism.
937 * So we just do the move. This requires that we
938 * resolve the destination register, not just the source,
939 * so there's some extra work.
940 * (PERHAPS NOT REALLY NEEDED, BUT CLEANER...)
941 */
942
943 /* a0 dst-reg, a1 user-stack, a2 stack, a3 value of src reg. */
944
9451: movi a4, .Lmovsp_dst
946 addx8 a4, a0, a4
947 jx a4
948
949 .align 8
950.Lmovsp_dst:
951 s32i a3, a2, PT_AREG0; _j 1f; .align 8
952 mov a1, a3; _j 1f; .align 8
953 s32i a3, a2, PT_AREG2; _j 1f; .align 8
954 s32i a3, a2, PT_AREG3; _j 1f; .align 8
955 s32i a3, a2, PT_AREG4; _j 1f; .align 8
956 mov a5, a3; _j 1f; .align 8
957 mov a6, a3; _j 1f; .align 8
958 mov a7, a3; _j 1f; .align 8
959 mov a8, a3; _j 1f; .align 8
960 mov a9, a3; _j 1f; .align 8
961 mov a10, a3; _j 1f; .align 8
962 mov a11, a3; _j 1f; .align 8
963 mov a12, a3; _j 1f; .align 8
964 mov a13, a3; _j 1f; .align 8
965 mov a14, a3; _j 1f; .align 8
966 mov a15, a3; _j 1f; .align 8
967
9681: l32i a4, a2, PT_AREG4
969 l32i a3, a2, PT_AREG3
970 l32i a0, a2, PT_AREG0
971 l32i a2, a2, PT_AREG2
972 rfe
973
974
975/*
976 * fast system calls.
977 *
978 * WARNING: The kernel doesn't save the entire user context before
979 * handling a fast system call. These functions are small and short,
980 * usually offering some functionality not available to user tasks.
981 *
982 * BE CAREFUL TO PRESERVE THE USER'S CONTEXT.
983 *
984 * Entry condition:
985 *
986 * a0: trashed, original value saved on stack (PT_AREG0)
987 * a1: a1
988 * a2: new stack pointer, original in DEPC
989 * a3: dispatch table
990 * depc: a2, original value saved on stack (PT_DEPC)
991 * excsave_1: a3
992 */
993
994ENTRY(fast_syscall_kernel)
995
996 /* Skip syscall. */
997
998 rsr a0, EPC_1
999 addi a0, a0, 3
1000 wsr a0, EPC_1
1001
1002 l32i a0, a2, PT_DEPC
1003 bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_syscall_unrecoverable
1004
1005 rsr a0, DEPC # get syscall-nr
1006 _beqz a0, fast_syscall_spill_registers
1007
1008 addi a0, a0, -__NR_sysxtensa
1009 _beqz a0, fast_syscall_sysxtensa
1010
1011 j kernel_exception
1012
1013
1014ENTRY(fast_syscall_user)
1015
1016 /* Skip syscall. */
1017
1018 rsr a0, EPC_1
1019 addi a0, a0, 3
1020 wsr a0, EPC_1
1021
1022 l32i a0, a2, PT_DEPC
1023 bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_syscall_unrecoverable
1024
1025 rsr a0, DEPC # get syscall-nr
1026 _beqz a0, fast_syscall_spill_registers
1027
1028 addi a0, a0, -__NR_sysxtensa
1029 _beqz a0, fast_syscall_sysxtensa
1030
1031 j user_exception
1032
1033ENTRY(fast_syscall_unrecoverable)
1034
1035 /* Restore all states. */
1036
1037 l32i a0, a2, PT_AREG0 # restore a0
1038 xsr a2, DEPC # restore a2, depc
1039 rsr a3, EXCSAVE_1
1040
1041 wsr a0, EXCSAVE_1
1042 movi a0, unrecoverable_exception
1043 callx0 a0
1044
1045
1046
1047/*
1048 * sysxtensa syscall handler
1049 *
1050 * int sysxtensa (XTENSA_ATOMIC_SET, ptr, val, unused);
1051 * int sysxtensa (XTENSA_ATOMIC_ADD, ptr, val, unused);
1052 * int sysxtensa (XTENSA_ATOMIC_EXG_ADD, ptr, val, unused);
1053 * int sysxtensa (XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval);
1054 * a2 a6 a3 a4 a5
1055 *
1056 * Entry condition:
1057 *
1058 * a0: trashed, original value saved on stack (PT_AREG0)
1059 * a1: a1
1060 * a2: new stack pointer, original in DEPC
1061 * a3: dispatch table
1062 * depc: a2, original value saved on stack (PT_DEPC)
1063 * excsave_1: a3
1064 *
1065 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1066 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1067 *
1068 * Note: we don't have to save a2; a2 holds the return value
1069 *
1070 * We use the two macros TRY and CATCH:
1071 *
1072 * TRY adds an entry to the __ex_table fixup table for the immediately
1073 * following instruction.
1074 *
1075 * CATCH catches any exception that occurred at one of the preceeding TRY
1076 * statements and continues from there
1077 *
1078 * Usage TRY l32i a0, a1, 0
1079 * <other code>
1080 * done: rfe
1081 * CATCH <set return code>
1082 * j done
1083 */
1084
1085#define TRY \
1086 .section __ex_table, "a"; \
1087 .word 66f, 67f; \
1088 .text; \
108966:
1090
1091#define CATCH \
109267:
1093
1094ENTRY(fast_syscall_sysxtensa)
1095
1096 _beqz a6, 1f
1097 _blti a6, SYSXTENSA_COUNT, 2f
1098
10991: j user_exception
1100
11012: xsr a3, EXCSAVE_1 # restore a3, excsave1
1102 s32i a7, a2, PT_AREG7
1103
1104 movi a7, 4 # sizeof(unsigned int)
1105 verify_area a3, a7, a0, a2, .Leac
1106
1107 _beqi a6, SYSXTENSA_ATOMIC_SET, .Lset
1108 _beqi a6, SYSXTENSA_ATOMIC_EXG_ADD, .Lexg
1109 _beqi a6, SYSXTENSA_ATOMIC_ADD, .Ladd
1110
1111 /* Fall through for SYSXTENSA_ATOMIC_CMP_SWP */
1112
1113.Lswp: /* Atomic compare and swap */
1114
1115TRY l32i a7, a3, 0 # read old value
1116 bne a7, a4, 1f # same as old value? jump
1117 s32i a5, a3, 0 # different, modify value
1118 movi a7, 1 # and return 1
1119 j .Lret
1120
11211: movi a7, 0 # same values: return 0
1122 j .Lret
1123
1124.Ladd: /* Atomic add */
1125.Lexg: /* Atomic (exchange) add */
1126
1127TRY l32i a7, a3, 0
1128 add a4, a4, a7
1129 s32i a4, a3, 0
1130 j .Lret
1131
1132.Lset: /* Atomic set */
1133
1134TRY l32i a7, a3, 0 # read old value as return value
1135 s32i a4, a3, 0 # write new value
1136
1137.Lret: mov a0, a2
1138 mov a2, a7
1139 l32i a7, a0, PT_AREG7
1140 l32i a3, a0, PT_AREG3
1141 l32i a0, a0, PT_AREG0
1142 rfe
1143
1144CATCH
1145.Leac: movi a7, -EFAULT
1146 j .Lret
1147
1148
1149
1150/* fast_syscall_spill_registers.
1151 *
1152 * Entry condition:
1153 *
1154 * a0: trashed, original value saved on stack (PT_AREG0)
1155 * a1: a1
1156 * a2: new stack pointer, original in DEPC
1157 * a3: dispatch table
1158 * depc: a2, original value saved on stack (PT_DEPC)
1159 * excsave_1: a3
1160 *
1161 * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler.
1162 * Note: We don't need to save a2 in depc (return value)
1163 */
1164
1165ENTRY(fast_syscall_spill_registers)
1166
1167 /* Register a FIXUP handler (pass current wb as a parameter) */
1168
1169 movi a0, fast_syscall_spill_registers_fixup
1170 s32i a0, a3, EXC_TABLE_FIXUP
1171 rsr a0, WINDOWBASE
1172 s32i a0, a3, EXC_TABLE_PARAM
1173
1174 /* Save a3 and SAR on stack. */
1175
1176 rsr a0, SAR
1177 xsr a3, EXCSAVE_1 # restore a3 and excsave_1
1178 s32i a0, a2, PT_AREG4 # store SAR to PT_AREG4
1179 s32i a3, a2, PT_AREG3
1180
1181 /* The spill routine might clobber a7, a11, and a15. */
1182
1183 s32i a7, a2, PT_AREG5
1184 s32i a11, a2, PT_AREG6
1185 s32i a15, a2, PT_AREG7
1186
1187 call0 _spill_registers # destroys a3, DEPC, and SAR
1188
1189 /* Advance PC, restore registers and SAR, and return from exception. */
1190
1191 l32i a3, a2, PT_AREG4
1192 l32i a0, a2, PT_AREG0
1193 wsr a3, SAR
1194 l32i a3, a2, PT_AREG3
1195
1196 /* Restore clobbered registers. */
1197
1198 l32i a7, a2, PT_AREG5
1199 l32i a11, a2, PT_AREG6
1200 l32i a15, a2, PT_AREG7
1201
1202 movi a2, 0
1203 rfe
1204
1205/* Fixup handler.
1206 *
1207 * We get here if the spill routine causes an exception, e.g. tlb miss.
1208 * We basically restore WINDOWBASE and WINDOWSTART to the condition when
1209 * we entered the spill routine and jump to the user exception handler.
1210 *
1211 * a0: value of depc, original value in depc
1212 * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
1213 * a3: exctable, original value in excsave1
1214 */
1215
1216fast_syscall_spill_registers_fixup:
1217
1218 rsr a2, WINDOWBASE # get current windowbase (a2 is saved)
1219 xsr a0, DEPC # restore depc and a0
1220 ssl a2 # set shift (32 - WB)
1221
1222 /* We need to make sure the current registers (a0-a3) are preserved.
1223 * To do this, we simply set the bit for the current window frame
1224 * in WS, so that the exception handlers save them to the task stack.
1225 */
1226
1227 rsr a3, EXCSAVE_1 # get spill-mask
1228 slli a2, a3, 1 # shift left by one
1229
1230 slli a3, a2, 32-WSBITS
1231 src a2, a2, a3 # a1 = xxwww1yyxxxwww1yy......
1232 wsr a2, WINDOWSTART # set corrected windowstart
1233
1234 movi a3, exc_table
1235 l32i a2, a3, EXC_TABLE_DOUBLE_SAVE # restore a2
1236 l32i a3, a3, EXC_TABLE_PARAM # original WB (in user task)
1237
1238 /* Return to the original (user task) WINDOWBASE.
1239 * We leave the following frame behind:
1240 * a0, a1, a2 same
1241 * a3: trashed (saved in excsave_1)
1242 * depc: depc (we have to return to that address)
1243 * excsave_1: a3
1244 */
1245
1246 wsr a3, WINDOWBASE
1247 rsync
1248
1249 /* We are now in the original frame when we entered _spill_registers:
1250 * a0: return address
1251 * a1: used, stack pointer
1252 * a2: kernel stack pointer
1253 * a3: available, saved in EXCSAVE_1
1254 * depc: exception address
1255 * excsave: a3
1256 * Note: This frame might be the same as above.
1257 */
1258
1259#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
1260 /* Restore registers we precautiously saved.
1261 * We have the value of the 'right' a3
1262 */
1263
1264 l32i a7, a2, PT_AREG5
1265 l32i a11, a2, PT_AREG6
1266 l32i a15, a2, PT_AREG7
1267#endif
1268
1269 /* Setup stack pointer. */
1270
1271 addi a2, a2, -PT_USER_SIZE
1272 s32i a0, a2, PT_AREG0
1273
1274 /* Make sure we return to this fixup handler. */
1275
1276 movi a3, fast_syscall_spill_registers_fixup_return
1277 s32i a3, a2, PT_DEPC # setup depc
1278
1279 /* Jump to the exception handler. */
1280
1281 movi a3, exc_table
1282 rsr a0, EXCCAUSE
1283 addx4 a0, a0, a3 # find entry in table
1284 l32i a0, a0, EXC_TABLE_FAST_USER # load handler
1285 jx a0
1286
1287fast_syscall_spill_registers_fixup_return:
1288
1289 /* When we return here, all registers have been restored (a2: DEPC) */
1290
1291 wsr a2, DEPC # exception address
1292
1293 /* Restore fixup handler. */
1294
1295 xsr a3, EXCSAVE_1
1296 movi a2, fast_syscall_spill_registers_fixup
1297 s32i a2, a3, EXC_TABLE_FIXUP
1298 rsr a2, WINDOWBASE
1299 s32i a2, a3, EXC_TABLE_PARAM
1300 l32i a2, a3, EXC_TABLE_KSTK
1301
1302#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
1303 /* Save registers again that might be clobbered. */
1304
1305 s32i a7, a2, PT_AREG5
1306 s32i a11, a2, PT_AREG6
1307 s32i a15, a2, PT_AREG7
1308#endif
1309
1310 /* Load WB at the time the exception occurred. */
1311
1312 rsr a3, SAR # WB is still in SAR
1313 neg a3, a3
1314 wsr a3, WINDOWBASE
1315 rsync
1316
1317 /* Restore a3 and return. */
1318
1319 movi a3, exc_table
1320 xsr a3, EXCSAVE_1
1321
1322 rfde
1323
1324
1325/*
1326 * spill all registers.
1327 *
1328 * This is not a real function. The following conditions must be met:
1329 *
1330 * - must be called with call0.
1331 * - uses DEPC, a3 and SAR.
1332 * - the last 'valid' register of each frame are clobbered.
1333 * - the caller must have registered a fixup handler
1334 * (or be inside a critical section)
1335 * - PS_EXCM must be set (PS_WOE cleared?)
1336 */
1337
1338ENTRY(_spill_registers)
1339
1340 /*
1341 * Rotate ws so that the current windowbase is at bit 0.
1342 * Assume ws = xxxwww1yy (www1 current window frame).
1343 * Rotate ws right so that a2 = yyxxxwww1.
1344 */
1345
1346 wsr a2, DEPC # preserve a2
1347 rsr a2, WINDOWBASE
1348 rsr a3, WINDOWSTART
1349 ssr a2 # holds WB
1350 slli a2, a3, WSBITS
1351 or a3, a3, a2 # a2 = xxxwww1yyxxxwww1yy
1352 srl a3, a3
1353
1354 /* We are done if there are no more than the current register frame. */
1355
1356 extui a3, a3, 1, WSBITS-2 # a3 = 0yyxxxwww
1357 movi a2, (1 << (WSBITS-1))
1358 _beqz a3, .Lnospill # only one active frame? jump
1359
1360 /* We want 1 at the top, so that we return to the current windowbase */
1361
1362 or a3, a3, a2 # 1yyxxxwww
1363
1364 /* Skip empty frames - get 'oldest' WINDOWSTART-bit. */
1365
1366 wsr a3, WINDOWSTART # save shifted windowstart
1367 neg a2, a3
1368 and a3, a2, a3 # first bit set from right: 000010000
1369
1370 ffs_ws a2, a3 # a2: shifts to skip empty frames
1371 movi a3, WSBITS
1372 sub a2, a3, a2 # WSBITS-a2:number of 0-bits from right
1373 ssr a2 # save in SAR for later.
1374
1375 rsr a3, WINDOWBASE
1376 add a3, a3, a2
1377 rsr a2, DEPC # restore a2
1378 wsr a3, WINDOWBASE
1379 rsync
1380
1381 rsr a3, WINDOWSTART
1382 srl a3, a3 # shift windowstart
1383
1384 /* WB is now just one frame below the oldest frame in the register
1385 window. WS is shifted so the oldest frame is in bit 0, thus, WB
1386 and WS differ by one 4-register frame. */
1387
1388 /* Save frames. Depending what call was used (call4, call8, call12),
1389 * we have to save 4,8. or 12 registers.
1390 */
1391
1392 _bbsi.l a3, 1, .Lc4
1393 _bbsi.l a3, 2, .Lc8
1394
1395 /* Special case: we have a call12-frame starting at a4. */
1396
1397 _bbci.l a3, 3, .Lc12 # bit 3 shouldn't be zero! (Jump to Lc12 first)
1398
1399 s32e a4, a1, -16 # a1 is valid with an empty spill area
1400 l32e a4, a5, -12
1401 s32e a8, a4, -48
1402 mov a8, a4
1403 l32e a4, a1, -16
1404 j .Lc12c
1405
1406.Lloop: _bbsi.l a3, 1, .Lc4
1407 _bbci.l a3, 2, .Lc12
1408
1409.Lc8: s32e a4, a13, -16
1410 l32e a4, a5, -12
1411 s32e a8, a4, -32
1412 s32e a5, a13, -12
1413 s32e a6, a13, -8
1414 s32e a7, a13, -4
1415 s32e a9, a4, -28
1416 s32e a10, a4, -24
1417 s32e a11, a4, -20
1418
1419 srli a11, a3, 2 # shift windowbase by 2
1420 rotw 2
1421 _bnei a3, 1, .Lloop
1422
1423.Lexit: /* Done. Do the final rotation, set WS, and return. */
1424
1425 rotw 1
1426 rsr a3, WINDOWBASE
1427 ssl a3
1428 movi a3, 1
1429 sll a3, a3
1430 wsr a3, WINDOWSTART
1431
1432.Lnospill:
1433 jx a0
1434
1435.Lc4: s32e a4, a9, -16
1436 s32e a5, a9, -12
1437 s32e a6, a9, -8
1438 s32e a7, a9, -4
1439
1440 srli a7, a3, 1
1441 rotw 1
1442 _bnei a3, 1, .Lloop
1443 j .Lexit
1444
1445.Lc12: _bbci.l a3, 3, .Linvalid_mask # bit 2 shouldn't be zero!
1446
1447 /* 12-register frame (call12) */
1448
1449 l32e a2, a5, -12
1450 s32e a8, a2, -48
1451 mov a8, a2
1452
1453.Lc12c: s32e a9, a8, -44
1454 s32e a10, a8, -40
1455 s32e a11, a8, -36
1456 s32e a12, a8, -32
1457 s32e a13, a8, -28
1458 s32e a14, a8, -24
1459 s32e a15, a8, -20
1460 srli a15, a3, 3
1461
1462 /* The stack pointer for a4..a7 is out of reach, so we rotate the
1463 * window, grab the stackpointer, and rotate back.
1464 * Alternatively, we could also use the following approach, but that
1465 * makes the fixup routine much more complicated:
1466 * rotw 1
1467 * s32e a0, a13, -16
1468 * ...
1469 * rotw 2
1470 */
1471
1472 rotw 1
1473 mov a5, a13
1474 rotw -1
1475
1476 s32e a4, a9, -16
1477 s32e a5, a9, -12
1478 s32e a6, a9, -8
1479 s32e a7, a9, -4
1480
1481 rotw 3
1482
1483 _beqi a3, 1, .Lexit
1484 j .Lloop
1485
1486.Linvalid_mask:
1487
1488 /* We get here because of an unrecoverable error in the window
1489 * registers. If we are in user space, we kill the application,
1490 * however, this condition is unrecoverable in kernel space.
1491 */
1492
1493 rsr a0, PS
1494 _bbci.l a0, PS_UM_SHIFT, 1f
1495
1496 /* User space: Setup a dummy frame and kill application.
1497 * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer.
1498 */
1499
1500 movi a0, 1
1501 movi a1, 0
1502
1503 wsr a0, WINDOWSTART
1504 wsr a1, WINDOWBASE
1505 rsync
1506
1507 movi a0, 0
1508
1509 movi a3, exc_table
1510 l32i a1, a3, EXC_TABLE_KSTK
1511 wsr a3, EXCSAVE_1
1512
1513 movi a4, PS_WOE_MASK | 1
1514 wsr a4, PS
1515 rsync
1516
1517 movi a6, SIGSEGV
1518 movi a4, do_exit
1519 callx4 a4
1520
15211: /* Kernel space: PANIC! */
1522
1523 wsr a0, EXCSAVE_1
1524 movi a0, unrecoverable_exception
1525 callx0 a0 # should not return
15261: j 1b
1527
1528/*
1529 * We should never get here. Bail out!
1530 */
1531
1532ENTRY(fast_second_level_miss_double_kernel)
1533
15341: movi a0, unrecoverable_exception
1535 callx0 a0 # should not return
15361: j 1b
1537
1538/* First-level entry handler for user, kernel, and double 2nd-level
1539 * TLB miss exceptions. Note that for now, user and kernel miss
1540 * exceptions share the same entry point and are handled identically.
1541 *
1542 * An old, less-efficient C version of this function used to exist.
1543 * We include it below, interleaved as comments, for reference.
1544 *
1545 * Entry condition:
1546 *
1547 * a0: trashed, original value saved on stack (PT_AREG0)
1548 * a1: a1
1549 * a2: new stack pointer, original in DEPC
1550 * a3: dispatch table
1551 * depc: a2, original value saved on stack (PT_DEPC)
1552 * excsave_1: a3
1553 *
1554 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1555 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1556 */
1557
1558ENTRY(fast_second_level_miss)
1559
1560 /* Save a1. Note: we don't expect a double exception. */
1561
1562 s32i a1, a2, PT_AREG1
1563
1564 /* We need to map the page of PTEs for the user task. Find
1565 * the pointer to that page. Also, it's possible for tsk->mm
1566 * to be NULL while tsk->active_mm is nonzero if we faulted on
1567 * a vmalloc address. In that rare case, we must use
1568 * active_mm instead to avoid a fault in this handler. See
1569 *
1570 * http://mail.nl.linux.org/linux-mm/2002-08/msg00258.html
1571 * (or search Internet on "mm vs. active_mm")
1572 *
1573 * if (!mm)
1574 * mm = tsk->active_mm;
1575 * pgd = pgd_offset (mm, regs->excvaddr);
1576 * pmd = pmd_offset (pgd, regs->excvaddr);
1577 * pmdval = *pmd;
1578 */
1579
1580 GET_CURRENT(a1,a2)
1581 l32i a0, a1, TASK_MM # tsk->mm
1582 beqz a0, 9f
1583
15848: rsr a1, EXCVADDR # fault address
1585 _PGD_OFFSET(a0, a1, a1)
1586 l32i a0, a0, 0 # read pmdval
1587 //beqi a0, _PAGE_USER, 2f
1588 beqz a0, 2f
1589
1590 /* Read ptevaddr and convert to top of page-table page.
1591 *
1592 * vpnval = read_ptevaddr_register() & PAGE_MASK;
1593 * vpnval += DTLB_WAY_PGTABLE;
1594 * pteval = mk_pte (virt_to_page(pmd_val(pmdval)), PAGE_KERNEL);
1595 * write_dtlb_entry (pteval, vpnval);
1596 *
1597 * The messy computation for 'pteval' above really simplifies
1598 * into the following:
1599 *
1600 * pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_KERNEL
1601 */
1602
1603 movi a1, -PAGE_OFFSET
1604 add a0, a0, a1 # pmdval - PAGE_OFFSET
1605 extui a1, a0, 0, PAGE_SHIFT # ... & PAGE_MASK
1606 xor a0, a0, a1
1607
1608
1609 movi a1, PAGE_DIRECTORY
1610 or a0, a0, a1 # ... | PAGE_DIRECTORY
1611
1612 rsr a1, PTEVADDR
1613 srli a1, a1, PAGE_SHIFT
1614 slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK
1615 addi a1, a1, DTLB_WAY_PGTABLE # ... + way_number
1616
1617 wdtlb a0, a1
1618 dsync
1619
1620 /* Exit critical section. */
1621
1622 movi a0, 0
1623 s32i a0, a3, EXC_TABLE_FIXUP
1624
1625 /* Restore the working registers, and return. */
1626
1627 l32i a0, a2, PT_AREG0
1628 l32i a1, a2, PT_AREG1
1629 l32i a2, a2, PT_DEPC
1630 xsr a3, EXCSAVE_1
1631
1632 bgeui a2, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
1633
1634 /* Restore excsave1 and return. */
1635
1636 rsr a2, DEPC
1637 rfe
1638
1639 /* Return from double exception. */
1640
16411: xsr a2, DEPC
1642 esync
1643 rfde
1644
16459: l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
1646 j 8b
1647
16482: /* Invalid PGD, default exception handling */
1649
1650 rsr a1, DEPC
1651 xsr a3, EXCSAVE_1
1652 s32i a1, a2, PT_AREG2
1653 s32i a3, a2, PT_AREG3
1654 mov a1, a2
1655
1656 rsr a2, PS
1657 bbsi.l a2, PS_UM_SHIFT, 1f
1658 j _kernel_exception
16591: j _user_exception
1660
1661
1662/*
1663 * StoreProhibitedException
1664 *
1665 * Update the pte and invalidate the itlb mapping for this pte.
1666 *
1667 * Entry condition:
1668 *
1669 * a0: trashed, original value saved on stack (PT_AREG0)
1670 * a1: a1
1671 * a2: new stack pointer, original in DEPC
1672 * a3: dispatch table
1673 * depc: a2, original value saved on stack (PT_DEPC)
1674 * excsave_1: a3
1675 *
1676 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1677 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1678 */
1679
1680ENTRY(fast_store_prohibited)
1681
1682 /* Save a1 and a4. */
1683
1684 s32i a1, a2, PT_AREG1
1685 s32i a4, a2, PT_AREG4
1686
1687 GET_CURRENT(a1,a2)
1688 l32i a0, a1, TASK_MM # tsk->mm
1689 beqz a0, 9f
1690
16918: rsr a1, EXCVADDR # fault address
1692 _PGD_OFFSET(a0, a1, a4)
1693 l32i a0, a0, 0
1694 //beqi a0, _PAGE_USER, 2f # FIXME use _PAGE_INVALID
1695 beqz a0, 2f
1696
1697 _PTE_OFFSET(a0, a1, a4)
1698 l32i a4, a0, 0 # read pteval
1699 movi a1, _PAGE_VALID | _PAGE_RW
1700 bnall a4, a1, 2f
1701
1702 movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_WRENABLE
1703 or a4, a4, a1
1704 rsr a1, EXCVADDR
1705 s32i a4, a0, 0
1706
1707 /* We need to flush the cache if we have page coloring. */
1708#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
1709 dhwb a0, 0
1710#endif
1711 pdtlb a0, a1
1712 beqz a0, 1f
1713 idtlb a0 // FIXME do we need this?
1714 wdtlb a4, a0
17151:
1716
1717 /* Exit critical section. */
1718
1719 movi a0, 0
1720 s32i a0, a3, EXC_TABLE_FIXUP
1721
1722 /* Restore the working registers, and return. */
1723
1724 l32i a4, a2, PT_AREG4
1725 l32i a1, a2, PT_AREG1
1726 l32i a0, a2, PT_AREG0
1727 l32i a2, a2, PT_DEPC
1728
1729 /* Restore excsave1 and a3. */
1730
1731 xsr a3, EXCSAVE_1
1732 bgeui a2, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
1733
1734 rsr a2, DEPC
1735 rfe
1736
1737 /* Double exception. Restore FIXUP handler and return. */
1738
17391: xsr a2, DEPC
1740 esync
1741 rfde
1742
17439: l32i a0, a1, TASK_ACTIVE_MM # unlikely case mm == 0
1744 j 8b
1745
17462: /* If there was a problem, handle fault in C */
1747
1748 rsr a4, DEPC # still holds a2
1749 xsr a3, EXCSAVE_1
1750 s32i a4, a2, PT_AREG2
1751 s32i a3, a2, PT_AREG3
1752 l32i a4, a2, PT_AREG4
1753 mov a1, a2
1754
1755 rsr a2, PS
1756 bbsi.l a2, PS_UM_SHIFT, 1f
1757 j _kernel_exception
17581: j _user_exception
1759
1760
1761#if XCHAL_EXTRA_SA_SIZE
1762
1763#warning fast_coprocessor untested
1764
1765/*
1766 * Entry condition:
1767 *
1768 * a0: trashed, original value saved on stack (PT_AREG0)
1769 * a1: a1
1770 * a2: new stack pointer, original in DEPC
1771 * a3: dispatch table
1772 * depc: a2, original value saved on stack (PT_DEPC)
1773 * excsave_1: a3
1774 *
1775 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
1776 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
1777 */
1778
1779ENTRY(fast_coprocessor_double)
1780 wsr a0, EXCSAVE_1
1781 movi a0, unrecoverable_exception
1782 callx0 a0
1783
1784ENTRY(fast_coprocessor)
1785
1786 /* Fatal if we are in a double exception. */
1787
1788 l32i a0, a2, PT_DEPC
1789 _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_coprocessor_double
1790
1791 /* Save some registers a1, a3, a4, SAR */
1792
1793 xsr a3, EXCSAVE_1
1794 s32i a3, a2, PT_AREG3
1795 rsr a3, SAR
1796 s32i a4, a2, PT_AREG4
1797 s32i a1, a2, PT_AREG1
1798 s32i a5, a1, PT_AREG5
1799 s32i a3, a2, PT_SAR
1800 mov a1, a2
1801
1802 /* Currently, the HAL macros only guarantee saving a0 and a1.
1803 * These can and will be refined in the future, but for now,
1804 * just save the remaining registers of a2...a15.
1805 */
1806 s32i a6, a1, PT_AREG6
1807 s32i a7, a1, PT_AREG7
1808 s32i a8, a1, PT_AREG8
1809 s32i a9, a1, PT_AREG9
1810 s32i a10, a1, PT_AREG10
1811 s32i a11, a1, PT_AREG11
1812 s32i a12, a1, PT_AREG12
1813 s32i a13, a1, PT_AREG13
1814 s32i a14, a1, PT_AREG14
1815 s32i a15, a1, PT_AREG15
1816
1817 /* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
1818
1819 rsr a0, EXCCAUSE
1820 addi a3, a0, -XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED
1821
1822 /* Set corresponding CPENABLE bit */
1823
1824 movi a4, 1
1825 ssl a3 # SAR: 32 - coprocessor_number
1826 rsr a5, CPENABLE
1827 sll a4, a4
1828 or a4, a5, a4
1829 wsr a4, CPENABLE
1830 rsync
1831 movi a5, coprocessor_info # list of owner and offset into cp_save
1832 addx8 a0, a4, a5 # entry for CP
1833
1834 bne a4, a5, .Lload # bit wasn't set before, cp not in use
1835
1836 /* Now compare the current task with the owner of the coprocessor.
1837 * If they are the same, there is no reason to save or restore any
1838 * coprocessor state. Having already enabled the coprocessor,
1839 * branch ahead to return.
1840 */
1841 GET_CURRENT(a5,a1)
1842 l32i a4, a0, COPROCESSOR_INFO_OWNER # a4: current owner for this CP
1843 beq a4, a5, .Ldone
1844
1845 /* Find location to dump current coprocessor state:
1846 * task_struct->task_cp_save_offset + coprocessor_offset[coprocessor]
1847 *
1848 * Note: a0 pointer to the entry in the coprocessor owner table,
1849 * a3 coprocessor number,
1850 * a4 current owner of coprocessor.
1851 */
1852 l32i a5, a0, COPROCESSOR_INFO_OFFSET
1853 addi a2, a4, THREAD_CP_SAVE
1854 add a2, a2, a5
1855
1856 /* Store current coprocessor states. (a5 still has CP number) */
1857
1858 xchal_cpi_store_funcbody
1859
1860 /* The macro might have destroyed a3 (coprocessor number), but
1861 * SAR still has 32 - coprocessor_number!
1862 */
1863 movi a3, 32
1864 rsr a4, SAR
1865 sub a3, a3, a4
1866
1867.Lload: /* A new task now owns the corpocessors. Save its TCB pointer into
1868 * the coprocessor owner table.
1869 *
1870 * Note: a0 pointer to the entry in the coprocessor owner table,
1871 * a3 coprocessor number.
1872 */
1873 GET_CURRENT(a4,a1)
1874 s32i a4, a0, 0
1875
1876 /* Find location from where to restore the current coprocessor state.*/
1877
1878 l32i a5, a0, COPROCESSOR_INFO_OFFSET
1879 addi a2, a4, THREAD_CP_SAVE
1880 add a2, a2, a4
1881
1882 xchal_cpi_load_funcbody
1883
1884 /* We must assume that the xchal_cpi_store_funcbody macro destroyed
1885 * registers a2..a15.
1886 */
1887
1888.Ldone: l32i a15, a1, PT_AREG15
1889 l32i a14, a1, PT_AREG14
1890 l32i a13, a1, PT_AREG13
1891 l32i a12, a1, PT_AREG12
1892 l32i a11, a1, PT_AREG11
1893 l32i a10, a1, PT_AREG10
1894 l32i a9, a1, PT_AREG9
1895 l32i a8, a1, PT_AREG8
1896 l32i a7, a1, PT_AREG7
1897 l32i a6, a1, PT_AREG6
1898 l32i a5, a1, PT_AREG5
1899 l32i a4, a1, PT_AREG4
1900 l32i a3, a1, PT_AREG3
1901 l32i a2, a1, PT_AREG2
1902 l32i a0, a1, PT_AREG0
1903 l32i a1, a1, PT_AREG1
1904
1905 rfe
1906
1907#endif /* XCHAL_EXTRA_SA_SIZE */
1908
1909/*
1910 * Task switch.
1911 *
1912 * struct task* _switch_to (struct task* prev, struct task* next)
1913 * a2 a2 a3
1914 */
1915
1916ENTRY(_switch_to)
1917
1918 entry a1, 16
1919
1920 mov a4, a3 # preserve a3
1921
1922 s32i a0, a2, THREAD_RA # save return address
1923 s32i a1, a2, THREAD_SP # save stack pointer
1924
1925 /* Disable ints while we manipulate the stack pointer; spill regs. */
1926
1927 movi a5, PS_EXCM_MASK | LOCKLEVEL
1928 xsr a5, PS
1929 rsr a3, EXCSAVE_1
1930 rsync
1931 s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */
1932
1933 call0 _spill_registers
1934
1935 /* Set kernel stack (and leave critical section)
1936 * Note: It's save to set it here. The stack will not be overwritten
1937 * because the kernel stack will only be loaded again after
1938 * we return from kernel space.
1939 */
1940
1941 l32i a0, a4, TASK_THREAD_INFO
1942 rsr a3, EXCSAVE_1 # exc_table
1943 movi a1, 0
1944 addi a0, a0, PT_REGS_OFFSET
1945 s32i a1, a3, EXC_TABLE_FIXUP
1946 s32i a0, a3, EXC_TABLE_KSTK
1947
1948 /* restore context of the task that 'next' addresses */
1949
1950 l32i a0, a4, THREAD_RA /* restore return address */
1951 l32i a1, a4, THREAD_SP /* restore stack pointer */
1952
1953 wsr a5, PS
1954 rsync
1955
1956 retw
1957
1958
1959ENTRY(ret_from_fork)
1960
1961 /* void schedule_tail (struct task_struct *prev)
1962 * Note: prev is still in a6 (return value from fake call4 frame)
1963 */
1964 movi a4, schedule_tail
1965 callx4 a4
1966
1967 movi a4, do_syscall_trace
1968 callx4 a4
1969
1970 j common_exception_return
1971
1972
1973
1974/*
1975 * Table of syscalls
1976 */
1977
1978.data
1979.align 4
1980.global sys_call_table
1981sys_call_table:
1982
1983#define SYSCALL(call, narg) .word call
1984#include "syscalls.h"
1985
1986/*
1987 * Number of arguments of each syscall
1988 */
1989
1990.global sys_narg_table
1991sys_narg_table:
1992
1993#undef SYSCALL
1994#define SYSCALL(call, narg) .byte narg
1995#include "syscalls.h"
1996
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
new file mode 100644
index 000000000000..6e9b5225b8f6
--- /dev/null
+++ b/arch/xtensa/kernel/head.S
@@ -0,0 +1,237 @@
1/*
2 * arch/xtensa/kernel/head.S
3 *
4 * Xtensa Processor startup code.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
15 * Kevin Chea
16 */
17
18#include <xtensa/cacheasm.h>
19#include <linux/config.h>
20#include <asm/processor.h>
21#include <asm/page.h>
22
23/*
24 * This module contains the entry code for kernel images. It performs the
25 * minimal setup needed to call the generic C routines.
26 *
27 * Prerequisites:
28 *
29 * - The kernel image has been loaded to the actual address where it was
30 * compiled to.
31 * - a2 contains either 0 or a pointer to a list of boot parameters.
32 * (see setup.c for more details)
33 *
34 */
35
36 .macro iterate from, to , cmd
37 .ifeq ((\to - \from) & ~0xfff)
38 \cmd \from
39 iterate "(\from+1)", \to, \cmd
40 .endif
41 .endm
42
43/*
44 * _start
45 *
46 * The bootloader passes a pointer to a list of boot parameters in a2.
47 */
48
49 /* The first bytes of the kernel image must be an instruction, so we
50 * manually allocate and define the literal constant we need for a jx
51 * instruction.
52 */
53
54 .section .head.text, "ax"
55 .globl _start
56_start: _j 2f
57 .align 4
581: .word _startup
592: l32r a0, 1b
60 jx a0
61
62 .text
63 .align 4
64_startup:
65
66 /* Disable interrupts and exceptions. */
67
68 movi a0, XCHAL_PS_EXCM_MASK
69 wsr a0, PS
70
71 /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
72
73 wsr a2, EXCSAVE_1
74
75 /* Start with a fresh windowbase and windowstart. */
76
77 movi a1, 1
78 movi a0, 0
79 wsr a1, WINDOWSTART
80 wsr a0, WINDOWBASE
81 rsync
82
83 /* Set a0 to 0 for the remaining initialization. */
84
85 movi a0, 0
86
87 /* Clear debugging registers. */
88
89#if XCHAL_HAVE_DEBUG
90 wsr a0, IBREAKENABLE
91 wsr a0, ICOUNT
92 movi a1, 15
93 wsr a0, ICOUNTLEVEL
94
95 .macro reset_dbreak num
96 wsr a0, DBREAKC + \num
97 .endm
98
99 iterate 0, XCHAL_NUM_IBREAK-1, reset_dbreak
100#endif
101
102 /* Clear CCOUNT (not really necessary, but nice) */
103
104 wsr a0, CCOUNT # not really necessary, but nice
105
106 /* Disable zero-loops. */
107
108#if XCHAL_HAVE_LOOPS
109 wsr a0, LCOUNT
110#endif
111
112 /* Disable all timers. */
113
114 .macro reset_timer num
115 wsr a0, CCOMPARE_0 + \num
116 .endm
117 iterate 0, XCHAL_NUM_TIMERS-1, reset_timer
118
119 /* Interrupt initialization. */
120
121 movi a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE
122 wsr a0, INTENABLE
123 wsr a2, INTCLEAR
124
125 /* Disable coprocessors. */
126
127#if XCHAL_CP_NUM > 0
128 wsr a0, CPENABLE
129#endif
130
131 /* Set PS.INTLEVEL=1, PS.WOE=0, kernel stack, PS.EXCM=0
132 *
133 * Note: PS.EXCM must be cleared before using any loop
134 * instructions; otherwise, they are silently disabled, and
135 * at most one iteration of the loop is executed.
136 */
137
138 movi a1, 1
139 wsr a1, PS
140 rsync
141
142 /* Initialize the caches.
143 * Does not include flushing writeback d-cache.
144 * a6, a7 are just working registers (clobbered).
145 */
146
147 icache_reset a2, a3
148 dcache_reset a2, a3
149
150 /* Unpack data sections
151 *
152 * The linker script used to build the Linux kernel image
153 * creates a table located at __boot_reloc_table_start
154 * that contans the information what data needs to be unpacked.
155 *
156 * Uses a2-a7.
157 */
158
159 movi a2, __boot_reloc_table_start
160 movi a3, __boot_reloc_table_end
161
1621: beq a2, a3, 3f # no more entries?
163 l32i a4, a2, 0 # start destination (in RAM)
164 l32i a5, a2, 4 # end desination (in RAM)
165 l32i a6, a2, 8 # start source (in ROM)
166 addi a2, a2, 12 # next entry
167 beq a4, a5, 1b # skip, empty entry
168 beq a4, a6, 1b # skip, source and dest. are the same
169
1702: l32i a7, a6, 0 # load word
171 addi a6, a6, 4
172 s32i a7, a4, 0 # store word
173 addi a4, a4, 4
174 bltu a4, a5, 2b
175 j 1b
176
1773:
178 /* All code and initialized data segments have been copied.
179 * Now clear the BSS segment.
180 */
181
182 movi a2, _bss_start # start of BSS
183 movi a3, _bss_end # end of BSS
184
1851: addi a2, a2, 4
186 s32i a0, a2, 0
187 blt a2, a3, 1b
188
189#if XCHAL_DCACHE_IS_WRITEBACK
190
191 /* After unpacking, flush the writeback cache to memory so the
192 * instructions/data are available.
193 */
194
195 dcache_writeback_all a2, a3
196#endif
197
198 /* Setup stack and enable window exceptions (keep irqs disabled) */
199
200 movi a1, init_thread_union
201 addi a1, a1, KERNEL_STACK_SIZE
202
203 movi a2, 0x00040001 # WOE=1, INTLEVEL=1, UM=0
204 wsr a2, PS # (enable reg-windows; progmode stack)
205 rsync
206
207 /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/
208
209 movi a2, debug_exception
210 wsr a2, EXCSAVE + XCHAL_DEBUGLEVEL
211
212 /* Set up EXCSAVE[1] to point to the exc_table. */
213
214 movi a6, exc_table
215 xsr a6, EXCSAVE_1
216
217 /* init_arch kick-starts the linux kernel */
218
219 movi a4, init_arch
220 callx4 a4
221
222 movi a4, start_kernel
223 callx4 a4
224
225should_never_return:
226 j should_never_return
227
228 /* Define some common data structures here. We define them
229 * here in this assembly file due to their unusual alignment
230 * requirements.
231 */
232
233 .comm swapper_pg_dir,PAGE_SIZE,PAGE_SIZE
234 .comm empty_bad_page_table,PAGE_SIZE,PAGE_SIZE
235 .comm empty_bad_page,PAGE_SIZE,PAGE_SIZE
236 .comm empty_zero_page,PAGE_SIZE,PAGE_SIZE
237
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
new file mode 100644
index 000000000000..4cbf6d91571f
--- /dev/null
+++ b/arch/xtensa/kernel/irq.c
@@ -0,0 +1,192 @@
1/*
2 * linux/arch/xtensa/kernel/irq.c
3 *
4 * Xtensa built-in interrupt controller and some generic functions copied
5 * from i386.
6 *
7 * Copyright (C) 2002 - 2005 Tensilica, Inc.
8 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
9 *
10 *
11 * Chris Zankel <chris@zankel.net>
12 * Kevin Chea
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/seq_file.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/kernel_stat.h>
21
22#include <asm/uaccess.h>
23#include <asm/platform.h>
24
25static void enable_xtensa_irq(unsigned int irq);
26static void disable_xtensa_irq(unsigned int irq);
27static void mask_and_ack_xtensa(unsigned int irq);
28static void end_xtensa_irq(unsigned int irq);
29
30static unsigned int cached_irq_mask;
31
32atomic_t irq_err_count;
33
34/*
35 * 'what should we do if we get a hw irq event on an illegal vector'.
36 * each architecture has to answer this themselves.
37 */
38void ack_bad_irq(unsigned int irq)
39{
40 printk("unexpected IRQ trap at vector %02x\n", irq);
41}
42
43/*
44 * do_IRQ handles all normal device IRQ's (the special
45 * SMP cross-CPU interrupts have their own specific
46 * handlers).
47 */
48
49unsigned int do_IRQ(int irq, struct pt_regs *regs)
50{
51 irq_enter();
52
53#ifdef CONFIG_DEBUG_STACKOVERFLOW
54 /* Debugging check for stack overflow: is there less than 1KB free? */
55 {
56 unsigned long sp;
57
58 __asm__ __volatile__ ("mov %0, a1\n" : "=a" (sp));
59 sp &= THREAD_SIZE - 1;
60
61 if (unlikely(sp < (sizeof(thread_info) + 1024)))
62 printk("Stack overflow in do_IRQ: %ld\n",
63 sp - sizeof(struct thread_info));
64 }
65#endif
66
67 __do_IRQ(irq, regs);
68
69 irq_exit();
70
71 return 1;
72}
73
74/*
75 * Generic, controller-independent functions:
76 */
77
78int show_interrupts(struct seq_file *p, void *v)
79{
80 int i = *(loff_t *) v, j;
81 struct irqaction * action;
82 unsigned long flags;
83
84 if (i == 0) {
85 seq_printf(p, " ");
86 for (j=0; j<NR_CPUS; j++)
87 if (cpu_online(j))
88 seq_printf(p, "CPU%d ",j);
89 seq_putc(p, '\n');
90 }
91
92 if (i < NR_IRQS) {
93 spin_lock_irqsave(&irq_desc[i].lock, flags);
94 action = irq_desc[i].action;
95 if (!action)
96 goto skip;
97 seq_printf(p, "%3d: ",i);
98#ifndef CONFIG_SMP
99 seq_printf(p, "%10u ", kstat_irqs(i));
100#else
101 for (j = 0; j < NR_CPUS; j++)
102 if (cpu_online(j))
103 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
104#endif
105 seq_printf(p, " %14s", irq_desc[i].handler->typename);
106 seq_printf(p, " %s", action->name);
107
108 for (action=action->next; action; action = action->next)
109 seq_printf(p, ", %s", action->name);
110
111 seq_putc(p, '\n');
112skip:
113 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
114 } else if (i == NR_IRQS) {
115 seq_printf(p, "NMI: ");
116 for (j = 0; j < NR_CPUS; j++)
117 if (cpu_online(j))
118 seq_printf(p, "%10u ", nmi_count(j));
119 seq_putc(p, '\n');
120 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
121 }
122 return 0;
123}
124/* shutdown is same as "disable" */
125#define shutdown_xtensa_irq disable_xtensa_irq
126
127static unsigned int startup_xtensa_irq(unsigned int irq)
128{
129 enable_xtensa_irq(irq);
130 return 0; /* never anything pending */
131}
132
133static struct hw_interrupt_type xtensa_irq_type = {
134 "Xtensa-IRQ",
135 startup_xtensa_irq,
136 shutdown_xtensa_irq,
137 enable_xtensa_irq,
138 disable_xtensa_irq,
139 mask_and_ack_xtensa,
140 end_xtensa_irq
141};
142
143static inline void mask_irq(unsigned int irq)
144{
145 cached_irq_mask &= ~(1 << irq);
146 set_sr (cached_irq_mask, INTENABLE);
147}
148
149static inline void unmask_irq(unsigned int irq)
150{
151 cached_irq_mask |= 1 << irq;
152 set_sr (cached_irq_mask, INTENABLE);
153}
154
155static void disable_xtensa_irq(unsigned int irq)
156{
157 unsigned long flags;
158 local_save_flags(flags);
159 mask_irq(irq);
160 local_irq_restore(flags);
161}
162
163static void enable_xtensa_irq(unsigned int irq)
164{
165 unsigned long flags;
166 local_save_flags(flags);
167 unmask_irq(irq);
168 local_irq_restore(flags);
169}
170
171static void mask_and_ack_xtensa(unsigned int irq)
172{
173 disable_xtensa_irq(irq);
174}
175
176static void end_xtensa_irq(unsigned int irq)
177{
178 enable_xtensa_irq(irq);
179}
180
181
182void __init init_IRQ(void)
183{
184 int i;
185
186 for (i=0; i < XTENSA_NR_IRQS; i++)
187 irq_desc[i].handler = &xtensa_irq_type;
188
189 cached_irq_mask = 0;
190
191 platform_init_irq();
192}
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c
new file mode 100644
index 000000000000..d1683cfa19a2
--- /dev/null
+++ b/arch/xtensa/kernel/module.c
@@ -0,0 +1,78 @@
1/*
2 * arch/xtensa/kernel/platform.c
3 *
4 * Module support.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/moduleloader.h>
18#include <linux/elf.h>
19#include <linux/vmalloc.h>
20#include <linux/fs.h>
21#include <linux/string.h>
22#include <linux/kernel.h>
23#include <linux/cache.h>
24
25LIST_HEAD(module_buf_list);
26
27void *module_alloc(unsigned long size)
28{
29 panic("module_alloc not implemented");
30}
31
32void module_free(struct module *mod, void *module_region)
33{
34 panic("module_free not implemented");
35}
36
37int module_frob_arch_sections(Elf32_Ehdr *hdr,
38 Elf32_Shdr *sechdrs,
39 char *secstrings,
40 struct module *me)
41{
42 panic("module_frob_arch_sections not implemented");
43}
44
45int apply_relocate(Elf32_Shdr *sechdrs,
46 const char *strtab,
47 unsigned int symindex,
48 unsigned int relsec,
49 struct module *module)
50{
51 panic ("apply_relocate not implemented");
52}
53
54int apply_relocate_add(Elf32_Shdr *sechdrs,
55 const char *strtab,
56 unsigned int symindex,
57 unsigned int relsec,
58 struct module *module)
59{
60 panic("apply_relocate_add not implemented");
61}
62
63int module_finalize(const Elf_Ehdr *hdr,
64 const Elf_Shdr *sechdrs,
65 struct module *me)
66{
67 panic ("module_finalize not implemented");
68}
69
70void module_arch_cleanup(struct module *mod)
71{
72 panic("module_arch_cleanup not implemented");
73}
74
75struct bug_entry *module_find_bug(unsigned long bugaddr)
76{
77 panic("module_find_bug not implemented");
78}
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
new file mode 100644
index 000000000000..84fde258cf85
--- /dev/null
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -0,0 +1,73 @@
1/*
2 * arch/xtensa/pci-dma.c
3 *
4 * DMA coherent memory allocation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Copyright (C) 2002 - 2005 Tensilica Inc.
12 *
13 * Based on version for i386.
14 *
15 * Chris Zankel <chris@zankel.net>
16 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
17 */
18
19#include <linux/types.h>
20#include <linux/mm.h>
21#include <linux/string.h>
22#include <linux/pci.h>
23#include <asm/io.h>
24#include <asm/cacheflush.h>
25
26/*
27 * Note: We assume that the full memory space is always mapped to 'kseg'
28 * Otherwise we have to use page attributes (not implemented).
29 */
30
31void *
32dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
33{
34 void *ret;
35
36 /* ignore region speicifiers */
37 gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
38
39 if (dev == NULL || (*dev->dma_mask < 0xffffffff))
40 gfp |= GFP_DMA;
41 ret = (void *)__get_free_pages(gfp, get_order(size));
42
43 if (ret != NULL) {
44 memset(ret, 0, size);
45 *handle = virt_to_bus(ret);
46 }
47 return (void*) BYPASS_ADDR((unsigned long)ret);
48}
49
50void dma_free_coherent(struct device *hwdev, size_t size,
51 void *vaddr, dma_addr_t dma_handle)
52{
53 free_pages(CACHED_ADDR((unsigned long)vaddr), get_order(size));
54}
55
56
57void consistent_sync(void *vaddr, size_t size, int direction)
58{
59 switch (direction) {
60 case PCI_DMA_NONE:
61 BUG();
62 case PCI_DMA_FROMDEVICE: /* invalidate only */
63 __invalidate_dcache_range((unsigned long)vaddr,
64 (unsigned long)size);
65 break;
66
67 case PCI_DMA_TODEVICE: /* writeback only */
68 case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
69 __flush_invalidate_dcache_range((unsigned long)vaddr,
70 (unsigned long)size);
71 break;
72 }
73}
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
new file mode 100644
index 000000000000..d29a81648637
--- /dev/null
+++ b/arch/xtensa/kernel/pci.c
@@ -0,0 +1,563 @@
1/*
2 * arch/xtensa/pcibios.c
3 *
4 * PCI bios-type initialisation for PCI machines
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Copyright (C) 2001-2005 Tensilica Inc.
12 *
13 * Based largely on work from Cort (ppc/kernel/pci.c)
14 * IO functions copied from sparc.
15 *
16 * Chris Zankel <chris@zankel.net>
17 *
18 */
19
20#include <linux/config.h>
21#include <linux/kernel.h>
22#include <linux/pci.h>
23#include <linux/delay.h>
24#include <linux/string.h>
25#include <linux/init.h>
26#include <linux/sched.h>
27#include <linux/errno.h>
28#include <linux/bootmem.h>
29
30#include <asm/pci-bridge.h>
31#include <asm/platform.h>
32
33#undef DEBUG
34
35#ifdef DEBUG
36#define DBG(x...) printk(x)
37#else
38#define DBG(x...)
39#endif
40
41/* PCI Controller */
42
43
44/*
45 * pcibios_alloc_controller
46 * pcibios_enable_device
47 * pcibios_fixups
48 * pcibios_align_resource
49 * pcibios_fixup_bus
50 * pcibios_setup
51 * pci_bus_add_device
52 * pci_mmap_page_range
53 */
54
55struct pci_controller* pci_ctrl_head;
56struct pci_controller** pci_ctrl_tail = &pci_ctrl_head;
57
58static int pci_bus_count;
59
60static void pcibios_fixup_resources(struct pci_dev* dev);
61
62#if 0 // FIXME
63struct pci_fixup pcibios_fixups[] = {
64 { DECLARE_PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources },
65 { 0 }
66};
67#endif
68
69void
70pcibios_update_resource(struct pci_dev *dev, struct resource *root,
71 struct resource *res, int resource)
72{
73 u32 new, check, mask;
74 int reg;
75 struct pci_controller* pci_ctrl = dev->sysdata;
76
77 new = res->start;
78 if (pci_ctrl && res->flags & IORESOURCE_IO) {
79 new -= pci_ctrl->io_space.base;
80 }
81 new |= (res->flags & PCI_REGION_FLAG_MASK);
82 if (resource < 6) {
83 reg = PCI_BASE_ADDRESS_0 + 4*resource;
84 } else if (resource == PCI_ROM_RESOURCE) {
85 res->flags |= PCI_ROM_ADDRESS_ENABLE;
86 reg = dev->rom_base_reg;
87 } else {
88 /* Somebody might have asked allocation of a non-standard resource */
89 return;
90 }
91
92 pci_write_config_dword(dev, reg, new);
93 pci_read_config_dword(dev, reg, &check);
94 mask = (new & PCI_BASE_ADDRESS_SPACE_IO) ?
95 PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK;
96
97 if ((new ^ check) & mask) {
98 printk(KERN_ERR "PCI: Error while updating region "
99 "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
100 new, check);
101 }
102}
103
104/*
105 * We need to avoid collisions with `mirrored' VGA ports
106 * and other strange ISA hardware, so we always want the
107 * addresses to be allocated in the 0x000-0x0ff region
108 * modulo 0x400.
109 *
110 * Why? Because some silly external IO cards only decode
111 * the low 10 bits of the IO address. The 0x00-0xff region
112 * is reserved for motherboard devices that decode all 16
113 * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
114 * but we want to try to avoid allocating at 0x2900-0x2bff
115 * which might have be mirrored at 0x0100-0x03ff..
116 */
117void
118pcibios_align_resource(void *data, struct resource *res, unsigned long size,
119 unsigned long align)
120{
121 struct pci_dev *dev = data;
122
123 if (res->flags & IORESOURCE_IO) {
124 unsigned long start = res->start;
125
126 if (size > 0x100) {
127 printk(KERN_ERR "PCI: I/O Region %s/%d too large"
128 " (%ld bytes)\n", dev->slot_name,
129 dev->resource - res, size);
130 }
131
132 if (start & 0x300) {
133 start = (start + 0x3ff) & ~0x3ff;
134 res->start = start;
135 }
136 }
137}
138
139int
140pcibios_enable_resources(struct pci_dev *dev, int mask)
141{
142 u16 cmd, old_cmd;
143 int idx;
144 struct resource *r;
145
146 pci_read_config_word(dev, PCI_COMMAND, &cmd);
147 old_cmd = cmd;
148 for(idx=0; idx<6; idx++) {
149 r = &dev->resource[idx];
150 if (!r->start && r->end) {
151 printk (KERN_ERR "PCI: Device %s not available because "
152 "of resource collisions\n", dev->slot_name);
153 return -EINVAL;
154 }
155 if (r->flags & IORESOURCE_IO)
156 cmd |= PCI_COMMAND_IO;
157 if (r->flags & IORESOURCE_MEM)
158 cmd |= PCI_COMMAND_MEMORY;
159 }
160 if (dev->resource[PCI_ROM_RESOURCE].start)
161 cmd |= PCI_COMMAND_MEMORY;
162 if (cmd != old_cmd) {
163 printk("PCI: Enabling device %s (%04x -> %04x)\n",
164 dev->slot_name, old_cmd, cmd);
165 pci_write_config_word(dev, PCI_COMMAND, cmd);
166 }
167 return 0;
168}
169
170struct pci_controller * __init pcibios_alloc_controller(void)
171{
172 struct pci_controller *pci_ctrl;
173
174 pci_ctrl = (struct pci_controller *)alloc_bootmem(sizeof(*pci_ctrl));
175 memset(pci_ctrl, 0, sizeof(struct pci_controller));
176
177 *pci_ctrl_tail = pci_ctrl;
178 pci_ctrl_tail = &pci_ctrl->next;
179
180 return pci_ctrl;
181}
182
183static int __init pcibios_init(void)
184{
185 struct pci_controller *pci_ctrl;
186 struct pci_bus *bus;
187 int next_busno = 0, i;
188
189 printk("PCI: Probing PCI hardware\n");
190
191 /* Scan all of the recorded PCI controllers. */
192 for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
193 pci_ctrl->last_busno = 0xff;
194 bus = pci_scan_bus(pci_ctrl->first_busno, pci_ctrl->ops,
195 pci_ctrl);
196 if (pci_ctrl->io_resource.flags) {
197 unsigned long offs;
198
199 offs = (unsigned long)pci_ctrl->io_space.base;
200 pci_ctrl->io_resource.start += offs;
201 pci_ctrl->io_resource.end += offs;
202 bus->resource[0] = &pci_ctrl->io_resource;
203 }
204 for (i = 0; i < 3; ++i)
205 if (pci_ctrl->mem_resources[i].flags)
206 bus->resource[i+1] =&pci_ctrl->mem_resources[i];
207 pci_ctrl->bus = bus;
208 pci_ctrl->last_busno = bus->subordinate;
209 if (next_busno <= pci_ctrl->last_busno)
210 next_busno = pci_ctrl->last_busno+1;
211 }
212 pci_bus_count = next_busno;
213
214 return platform_pcibios_fixup();
215}
216
217subsys_initcall(pcibios_init);
218
219void __init pcibios_fixup_bus(struct pci_bus *bus)
220{
221 struct pci_controller *pci_ctrl = bus->sysdata;
222 struct resource *res;
223 unsigned long io_offset;
224 int i;
225
226 io_offset = (unsigned long)pci_ctrl->io_space.base;
227 if (bus->parent == NULL) {
228 /* this is a host bridge - fill in its resources */
229 pci_ctrl->bus = bus;
230
231 bus->resource[0] = res = &pci_ctrl->io_resource;
232 if (!res->flags) {
233 if (io_offset)
234 printk (KERN_ERR "I/O resource not set for host"
235 " bridge %d\n", pci_ctrl->index);
236 res->start = 0;
237 res->end = IO_SPACE_LIMIT;
238 res->flags = IORESOURCE_IO;
239 }
240 res->start += io_offset;
241 res->end += io_offset;
242
243 for (i = 0; i < 3; i++) {
244 res = &pci_ctrl->mem_resources[i];
245 if (!res->flags) {
246 if (i > 0)
247 continue;
248 printk(KERN_ERR "Memory resource not set for "
249 "host bridge %d\n", pci_ctrl->index);
250 res->start = 0;
251 res->end = ~0U;
252 res->flags = IORESOURCE_MEM;
253 }
254 bus->resource[i+1] = res;
255 }
256 } else {
257 /* This is a subordinate bridge */
258 pci_read_bridge_bases(bus);
259
260 for (i = 0; i < 4; i++) {
261 if ((res = bus->resource[i]) == NULL || !res->flags)
262 continue;
263 if (io_offset && (res->flags & IORESOURCE_IO)) {
264 res->start += io_offset;
265 res->end += io_offset;
266 }
267 }
268 }
269}
270
271char __init *pcibios_setup(char *str)
272{
273 return str;
274}
275
276/* the next one is stolen from the alpha port... */
277
278void __init
279pcibios_update_irq(struct pci_dev *dev, int irq)
280{
281 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
282}
283
284int pcibios_enable_device(struct pci_dev *dev, int mask)
285{
286 u16 cmd, old_cmd;
287 int idx;
288 struct resource *r;
289
290 pci_read_config_word(dev, PCI_COMMAND, &cmd);
291 old_cmd = cmd;
292 for (idx=0; idx<6; idx++) {
293 r = &dev->resource[idx];
294 if (!r->start && r->end) {
295 printk(KERN_ERR "PCI: Device %s not available because "
296 "of resource collisions\n", dev->slot_name);
297 return -EINVAL;
298 }
299 if (r->flags & IORESOURCE_IO)
300 cmd |= PCI_COMMAND_IO;
301 if (r->flags & IORESOURCE_MEM)
302 cmd |= PCI_COMMAND_MEMORY;
303 }
304 if (cmd != old_cmd) {
305 printk("PCI: Enabling device %s (%04x -> %04x)\n",
306 dev->slot_name, old_cmd, cmd);
307 pci_write_config_word(dev, PCI_COMMAND, cmd);
308 }
309
310 return 0;
311}
312
313#ifdef CONFIG_PROC_FS
314
315/*
316 * Return the index of the PCI controller for device pdev.
317 */
318
319int
320pci_controller_num(struct pci_dev *dev)
321{
322 struct pci_controller *pci_ctrl = (struct pci_controller*) dev->sysdata;
323 return pci_ctrl->index;
324}
325
326#endif /* CONFIG_PROC_FS */
327
328
329static void
330pcibios_fixup_resources(struct pci_dev *dev)
331{
332 struct pci_controller* pci_ctrl = (struct pci_controller *)dev->sysdata;
333 int i;
334 unsigned long offset;
335
336 if (!pci_ctrl) {
337 printk(KERN_ERR "No pci_ctrl for PCI dev %s!\n",dev->slot_name);
338 return;
339 }
340 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
341 struct resource *res = dev->resource + i;
342 if (!res->start || !res->flags)
343 continue;
344 if (res->end == 0xffffffff) {
345 DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
346 dev->slot_name, i, res->start, res->end);
347 res->end -= res->start;
348 res->start = 0;
349 continue;
350 }
351 offset = 0;
352 if (res->flags & IORESOURCE_IO)
353 offset = (unsigned long) pci_ctrl->io_space.base;
354 else if (res->flags & IORESOURCE_MEM)
355 offset = (unsigned long) pci_ctrl->mem_space.base;
356
357 if (offset != 0) {
358 res->start += offset;
359 res->end += offset;
360#ifdef DEBUG
361 printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n",
362 i, res->flags, dev->slot_name,
363 res->start - offset, res->start);
364#endif
365 }
366 }
367}
368
369/*
370 * Platform support for /proc/bus/pci/X/Y mmap()s,
371 * modelled on the sparc64 implementation by Dave Miller.
372 * -- paulus.
373 */
374
375/*
376 * Adjust vm_pgoff of VMA such that it is the physical page offset
377 * corresponding to the 32-bit pci bus offset for DEV requested by the user.
378 *
379 * Basically, the user finds the base address for his device which he wishes
380 * to mmap. They read the 32-bit value from the config space base register,
381 * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
382 * offset parameter of mmap on /proc/bus/pci/XXX for that device.
383 *
384 * Returns negative error code on failure, zero on success.
385 */
386static __inline__ int
387__pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
388 enum pci_mmap_state mmap_state)
389{
390 struct pci_controller *pci_ctrl = (struct pci_controller*) dev->sysdata;
391 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
392 unsigned long io_offset = 0;
393 int i, res_bit;
394
395 if (pci_ctrl == 0)
396 return -EINVAL; /* should never happen */
397
398 /* If memory, add on the PCI bridge address offset */
399 if (mmap_state == pci_mmap_mem) {
400 res_bit = IORESOURCE_MEM;
401 } else {
402 io_offset = (unsigned long)pci_ctrl->io_space.base;
403 offset += io_offset;
404 res_bit = IORESOURCE_IO;
405 }
406
407 /*
408 * Check that the offset requested corresponds to one of the
409 * resources of the device.
410 */
411 for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
412 struct resource *rp = &dev->resource[i];
413 int flags = rp->flags;
414
415 /* treat ROM as memory (should be already) */
416 if (i == PCI_ROM_RESOURCE)
417 flags |= IORESOURCE_MEM;
418
419 /* Active and same type? */
420 if ((flags & res_bit) == 0)
421 continue;
422
423 /* In the range of this resource? */
424 if (offset < (rp->start & PAGE_MASK) || offset > rp->end)
425 continue;
426
427 /* found it! construct the final physical address */
428 if (mmap_state == pci_mmap_io)
429 offset += pci_ctrl->io_space.start - io_offset;
430 vma->vm_pgoff = offset >> PAGE_SHIFT;
431 return 0;
432 }
433
434 return -EINVAL;
435}
436
437/*
438 * Set vm_flags of VMA, as appropriate for this architecture, for a pci device
439 * mapping.
440 */
441static __inline__ void
442__pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
443 enum pci_mmap_state mmap_state)
444{
445 vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
446}
447
448/*
449 * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
450 * device mapping.
451 */
452static __inline__ void
453__pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
454 enum pci_mmap_state mmap_state, int write_combine)
455{
456 int prot = pgprot_val(vma->vm_page_prot);
457
458 /* Set to write-through */
459 prot &= ~_PAGE_NO_CACHE;
460#if 0
461 if (!write_combine)
462 prot |= _PAGE_WRITETHRU;
463#endif
464 vma->vm_page_prot = __pgprot(prot);
465}
466
467/*
468 * Perform the actual remap of the pages for a PCI device mapping, as
469 * appropriate for this architecture. The region in the process to map
470 * is described by vm_start and vm_end members of VMA, the base physical
471 * address is found in vm_pgoff.
472 * The pci device structure is provided so that architectures may make mapping
473 * decisions on a per-device or per-bus basis.
474 *
475 * Returns a negative error code on failure, zero on success.
476 */
477int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
478 enum pci_mmap_state mmap_state,
479 int write_combine)
480{
481 int ret;
482
483 ret = __pci_mmap_make_offset(dev, vma, mmap_state);
484 if (ret < 0)
485 return ret;
486
487 __pci_mmap_set_flags(dev, vma, mmap_state);
488 __pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
489
490 ret = io_remap_page_range(vma, vma->vm_start, vma->vm_pgoff<<PAGE_SHIFT,
491 vma->vm_end - vma->vm_start, vma->vm_page_prot);
492
493 return ret;
494}
495
496/*
497 * This probably belongs here rather than ioport.c because
498 * we do not want this crud linked into SBus kernels.
499 * Also, think for a moment about likes of floppy.c that
500 * include architecture specific parts. They may want to redefine ins/outs.
501 *
502 * We do not use horroble macroses here because we want to
503 * advance pointer by sizeof(size).
504 */
505void outsb(unsigned long addr, const void *src, unsigned long count) {
506 while (count) {
507 count -= 1;
508 writeb(*(const char *)src, addr);
509 src += 1;
510 addr += 1;
511 }
512}
513
514void outsw(unsigned long addr, const void *src, unsigned long count) {
515 while (count) {
516 count -= 2;
517 writew(*(const short *)src, addr);
518 src += 2;
519 addr += 2;
520 }
521}
522
523void outsl(unsigned long addr, const void *src, unsigned long count) {
524 while (count) {
525 count -= 4;
526 writel(*(const long *)src, addr);
527 src += 4;
528 addr += 4;
529 }
530}
531
532void insb(unsigned long addr, void *dst, unsigned long count) {
533 while (count) {
534 count -= 1;
535 *(unsigned char *)dst = readb(addr);
536 dst += 1;
537 addr += 1;
538 }
539}
540
541void insw(unsigned long addr, void *dst, unsigned long count) {
542 while (count) {
543 count -= 2;
544 *(unsigned short *)dst = readw(addr);
545 dst += 2;
546 addr += 2;
547 }
548}
549
550void insl(unsigned long addr, void *dst, unsigned long count) {
551 while (count) {
552 count -= 4;
553 /*
554 * XXX I am sure we are in for an unaligned trap here.
555 */
556 *(unsigned long *)dst = readl(addr);
557 dst += 4;
558 addr += 4;
559 }
560}
561
562
563
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
new file mode 100644
index 000000000000..cf1362784443
--- /dev/null
+++ b/arch/xtensa/kernel/platform.c
@@ -0,0 +1,49 @@
1/*
2 * arch/xtensa/kernel/platform.c
3 *
4 * Default platform functions.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 */
14
15#include <linux/config.h>
16#include <linux/types.h>
17#include <linux/pci.h>
18#include <linux/time.h>
19#include <asm/platform.h>
20#include <asm/timex.h>
21
22#define _F(r,f,a,b) \
23 r __platform_##f a b; \
24 r platform_##f a __attribute__((weak, alias("__platform_"#f)))
25
26/*
27 * Default functions that are used if no platform specific function is defined.
28 * (Please, refer to include/asm-xtensa/platform.h for more information)
29 */
30
31_F(void, setup, (char** cmd), { });
32_F(void, init_irq, (void), { });
33_F(void, restart, (void), { while(1); });
34_F(void, halt, (void), { while(1); });
35_F(void, power_off, (void), { while(1); });
36_F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); });
37_F(void, heartbeat, (void), { });
38_F(int, pcibios_fixup, (void), { return 0; });
39_F(int, get_rtc_time, (time_t* t), { return 0; });
40_F(int, set_rtc_time, (time_t t), { return 0; });
41
42#if CONFIG_XTENSA_CALIBRATE_CCOUNT
43_F(void, calibrate_ccount, (void),
44{
45 printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");
46 ccount_per_jiffy = 100 * (1000000UL/HZ);
47});
48#endif
49
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
new file mode 100644
index 000000000000..4099703b14be
--- /dev/null
+++ b/arch/xtensa/kernel/process.c
@@ -0,0 +1,482 @@
1// TODO verify coprocessor handling
2/*
3 * arch/xtensa/kernel/process.c
4 *
5 * Xtensa Processor version.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Copyright (C) 2001 - 2005 Tensilica Inc.
12 *
13 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
14 * Chris Zankel <chris@zankel.net>
15 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
16 * Kevin Chea
17 */
18
19#include <linux/config.h>
20#include <linux/errno.h>
21#include <linux/sched.h>
22#include <linux/kernel.h>
23#include <linux/mm.h>
24#include <linux/smp.h>
25#include <linux/smp_lock.h>
26#include <linux/stddef.h>
27#include <linux/unistd.h>
28#include <linux/ptrace.h>
29#include <linux/slab.h>
30#include <linux/elf.h>
31#include <linux/init.h>
32#include <linux/prctl.h>
33#include <linux/init_task.h>
34#include <linux/module.h>
35#include <linux/mqueue.h>
36
37#include <asm/pgtable.h>
38#include <asm/uaccess.h>
39#include <asm/system.h>
40#include <asm/io.h>
41#include <asm/processor.h>
42#include <asm/platform.h>
43#include <asm/mmu.h>
44#include <asm/irq.h>
45#include <asm/atomic.h>
46#include <asm/offsets.h>
47#include <asm/coprocessor.h>
48
49extern void ret_from_fork(void);
50
51static struct fs_struct init_fs = INIT_FS;
52static struct files_struct init_files = INIT_FILES;
53static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
54static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
55struct mm_struct init_mm = INIT_MM(init_mm);
56EXPORT_SYMBOL(init_mm);
57
58union thread_union init_thread_union
59 __attribute__((__section__(".data.init_task"))) =
60{ INIT_THREAD_INFO(init_task) };
61
62struct task_struct init_task = INIT_TASK(init_task);
63EXPORT_SYMBOL(init_task);
64
65struct task_struct *current_set[NR_CPUS] = {&init_task, };
66
67
68#if XCHAL_CP_NUM > 0
69
70/*
71 * Coprocessor ownership.
72 */
73
74coprocessor_info_t coprocessor_info[] = {
75 { 0, XTENSA_CPE_CP0_OFFSET },
76 { 0, XTENSA_CPE_CP1_OFFSET },
77 { 0, XTENSA_CPE_CP2_OFFSET },
78 { 0, XTENSA_CPE_CP3_OFFSET },
79 { 0, XTENSA_CPE_CP4_OFFSET },
80 { 0, XTENSA_CPE_CP5_OFFSET },
81 { 0, XTENSA_CPE_CP6_OFFSET },
82 { 0, XTENSA_CPE_CP7_OFFSET },
83};
84
85#endif
86
87/*
88 * Powermanagement idle function, if any is provided by the platform.
89 */
90
91void cpu_idle(void)
92{
93 local_irq_enable();
94
95 /* endless idle loop with no priority at all */
96 while (1) {
97 while (!need_resched())
98 platform_idle();
99 preempt_enable();
100 schedule();
101 }
102}
103
104/*
105 * Free current thread data structures etc..
106 */
107
108void exit_thread(void)
109{
110 release_coprocessors(current); /* Empty macro if no CPs are defined */
111}
112
113void flush_thread(void)
114{
115 release_coprocessors(current); /* Empty macro if no CPs are defined */
116}
117
118/*
119 * Copy thread.
120 *
121 * The stack layout for the new thread looks like this:
122 *
123 * +------------------------+ <- sp in childregs (= tos)
124 * | childregs |
125 * +------------------------+ <- thread.sp = sp in dummy-frame
126 * | dummy-frame | (saved in dummy-frame spill-area)
127 * +------------------------+
128 *
129 * We create a dummy frame to return to ret_from_fork:
130 * a0 points to ret_from_fork (simulating a call4)
131 * sp points to itself (thread.sp)
132 * a2, a3 are unused.
133 *
134 * Note: This is a pristine frame, so we don't need any spill region on top of
135 * childregs.
136 */
137
138int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
139 unsigned long unused,
140 struct task_struct * p, struct pt_regs * regs)
141{
142 struct pt_regs *childregs;
143 unsigned long tos;
144 int user_mode = user_mode(regs);
145
146 /* Set up new TSS. */
147 tos = (unsigned long)p->thread_info + THREAD_SIZE;
148 if (user_mode)
149 childregs = (struct pt_regs*)(tos - PT_USER_SIZE);
150 else
151 childregs = (struct pt_regs*)tos - 1;
152
153 *childregs = *regs;
154
155 /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */
156 *((int*)childregs - 3) = (unsigned long)childregs;
157 *((int*)childregs - 4) = 0;
158
159 childregs->areg[1] = tos;
160 childregs->areg[2] = 0;
161 p->set_child_tid = p->clear_child_tid = NULL;
162 p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1);
163 p->thread.sp = (unsigned long)childregs;
164 if (user_mode(regs)) {
165
166 int len = childregs->wmask & ~0xf;
167 childregs->areg[1] = usp;
168 memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
169 &regs->areg[XCHAL_NUM_AREGS - len/4], len);
170
171 if (clone_flags & CLONE_SETTLS)
172 childregs->areg[2] = childregs->areg[6];
173
174 } else {
175 /* In kernel space, we start a new thread with a new stack. */
176 childregs->wmask = 1;
177 }
178 return 0;
179}
180
181
182/*
183 * Create a kernel thread
184 */
185
186int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
187{
188 long retval;
189 __asm__ __volatile__
190 ("mov a5, %4\n\t" /* preserve fn in a5 */
191 "mov a6, %3\n\t" /* preserve and setup arg in a6 */
192 "movi a2, %1\n\t" /* load __NR_clone for syscall*/
193 "mov a3, sp\n\t" /* sp check and sys_clone */
194 "mov a4, %5\n\t" /* load flags for syscall */
195 "syscall\n\t"
196 "beq a3, sp, 1f\n\t" /* branch if parent */
197 "callx4 a5\n\t" /* call fn */
198 "movi a2, %2\n\t" /* load __NR_exit for syscall */
199 "mov a3, a6\n\t" /* load fn return value */
200 "syscall\n"
201 "1:\n\t"
202 "mov %0, a2\n\t" /* parent returns zero */
203 :"=r" (retval)
204 :"i" (__NR_clone), "i" (__NR_exit),
205 "r" (arg), "r" (fn),
206 "r" (flags | CLONE_VM)
207 : "a2", "a3", "a4", "a5", "a6" );
208 return retval;
209}
210
211
212/*
213 * These bracket the sleeping functions..
214 */
215
216unsigned long get_wchan(struct task_struct *p)
217{
218 unsigned long sp, pc;
219 unsigned long stack_page = (unsigned long) p->thread_info;
220 int count = 0;
221
222 if (!p || p == current || p->state == TASK_RUNNING)
223 return 0;
224
225 sp = p->thread.sp;
226 pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
227
228 do {
229 if (sp < stack_page + sizeof(struct task_struct) ||
230 sp >= (stack_page + THREAD_SIZE) ||
231 pc == 0)
232 return 0;
233 if (!in_sched_functions(pc))
234 return pc;
235
236 /* Stack layout: sp-4: ra, sp-3: sp' */
237
238 pc = MAKE_PC_FROM_RA(*(unsigned long*)sp - 4, sp);
239 sp = *(unsigned long *)sp - 3;
240 } while (count++ < 16);
241 return 0;
242}
243
244/*
245 * do_copy_regs() gathers information from 'struct pt_regs' and
246 * 'current->thread.areg[]' to fill in the xtensa_gregset_t
247 * structure.
248 *
249 * xtensa_gregset_t and 'struct pt_regs' are vastly different formats
250 * of processor registers. Besides different ordering,
251 * xtensa_gregset_t contains non-live register information that
252 * 'struct pt_regs' does not. Exception handling (primarily) uses
253 * 'struct pt_regs'. Core files and ptrace use xtensa_gregset_t.
254 *
255 */
256
257void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
258 struct task_struct *tsk)
259{
260 int i, n, wb_offset;
261
262 elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0;
263 elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1;
264
265 __asm__ __volatile__ ("rsr %0, 176\n" : "=a" (i));
266 elfregs->cpux = i;
267 __asm__ __volatile__ ("rsr %0, 208\n" : "=a" (i));
268 elfregs->cpuy = i;
269
270 /* Note: PS.EXCM is not set while user task is running; its
271 * being set in regs->ps is for exception handling convenience.
272 */
273
274 elfregs->pc = regs->pc;
275 elfregs->ps = (regs->ps & ~XCHAL_PS_EXCM_MASK);
276 elfregs->exccause = regs->exccause;
277 elfregs->excvaddr = regs->excvaddr;
278 elfregs->windowbase = regs->windowbase;
279 elfregs->windowstart = regs->windowstart;
280 elfregs->lbeg = regs->lbeg;
281 elfregs->lend = regs->lend;
282 elfregs->lcount = regs->lcount;
283 elfregs->sar = regs->sar;
284 elfregs->syscall = regs->syscall;
285
286 /* Copy register file.
287 * The layout looks like this:
288 *
289 * | a0 ... a15 | Z ... Z | arX ... arY |
290 * current window unused saved frames
291 */
292
293 memset (elfregs->ar, 0, sizeof(elfregs->ar));
294
295 wb_offset = regs->windowbase * 4;
296 n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
297
298 for (i = 0; i < n; i++)
299 elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
300
301 n = (regs->wmask >> 4) * 4;
302
303 for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
304 elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
305}
306
307void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
308{
309 do_copy_regs ((xtensa_gregset_t *)elfregs, regs, current);
310}
311
312
313/* The inverse of do_copy_regs(). No error or sanity checking. */
314
315void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
316 struct task_struct *tsk)
317{
318 int i, n, wb_offset;
319
320 /* Note: PS.EXCM is not set while user task is running; it
321 * needs to be set in regs->ps is for exception handling convenience.
322 */
323
324 regs->pc = elfregs->pc;
325 regs->ps = (elfregs->ps | XCHAL_PS_EXCM_MASK);
326 regs->exccause = elfregs->exccause;
327 regs->excvaddr = elfregs->excvaddr;
328 regs->windowbase = elfregs->windowbase;
329 regs->windowstart = elfregs->windowstart;
330 regs->lbeg = elfregs->lbeg;
331 regs->lend = elfregs->lend;
332 regs->lcount = elfregs->lcount;
333 regs->sar = elfregs->sar;
334 regs->syscall = elfregs->syscall;
335
336 /* Clear everything. */
337
338 memset (regs->areg, 0, sizeof(regs->areg));
339
340 /* Copy regs from live window frame. */
341
342 wb_offset = regs->windowbase * 4;
343 n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
344
345 for (i = 0; i < n; i++)
346 regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
347
348 n = (regs->wmask >> 4) * 4;
349
350 for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
351 regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
352}
353
354/*
355 * do_save_fpregs() gathers information from 'struct pt_regs' and
356 * 'current->thread' to fill in the elf_fpregset_t structure.
357 *
358 * Core files and ptrace use elf_fpregset_t.
359 */
360
361void do_save_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
362 struct task_struct *tsk)
363{
364#if XCHAL_HAVE_CP
365
366 extern unsigned char _xtensa_reginfo_tables[];
367 extern unsigned _xtensa_reginfo_table_size;
368 int i;
369 unsigned long flags;
370
371 /* Before dumping coprocessor state from memory,
372 * ensure any live coprocessor contents for this
373 * task are first saved to memory:
374 */
375 local_irq_save(flags);
376
377 for (i = 0; i < XCHAL_CP_MAX; i++) {
378 if (tsk == coprocessor_info[i].owner) {
379 enable_coprocessor(i);
380 save_coprocessor_registers(
381 tsk->thread.cp_save+coprocessor_info[i].offset,i);
382 disable_coprocessor(i);
383 }
384 }
385
386 local_irq_restore(flags);
387
388 /* Now dump coprocessor & extra state: */
389 memcpy((unsigned char*)fpregs,
390 _xtensa_reginfo_tables, _xtensa_reginfo_table_size);
391 memcpy((unsigned char*)fpregs + _xtensa_reginfo_table_size,
392 tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
393#endif
394}
395
396/*
397 * The inverse of do_save_fpregs().
398 * Copies coprocessor and extra state from fpregs into regs and tsk->thread.
399 * Returns 0 on success, non-zero if layout doesn't match.
400 */
401
402int do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
403 struct task_struct *tsk)
404{
405#if XCHAL_HAVE_CP
406
407 extern unsigned char _xtensa_reginfo_tables[];
408 extern unsigned _xtensa_reginfo_table_size;
409 int i;
410 unsigned long flags;
411
412 /* Make sure save area layouts match.
413 * FIXME: in the future we could allow restoring from
414 * a different layout of the same registers, by comparing
415 * fpregs' table with _xtensa_reginfo_tables and matching
416 * entries and copying registers one at a time.
417 * Not too sure yet whether that's very useful.
418 */
419
420 if( memcmp((unsigned char*)fpregs,
421 _xtensa_reginfo_tables, _xtensa_reginfo_table_size) ) {
422 return -1;
423 }
424
425 /* Before restoring coprocessor state from memory,
426 * ensure any live coprocessor contents for this
427 * task are first invalidated.
428 */
429
430 local_irq_save(flags);
431
432 for (i = 0; i < XCHAL_CP_MAX; i++) {
433 if (tsk == coprocessor_info[i].owner) {
434 enable_coprocessor(i);
435 save_coprocessor_registers(
436 tsk->thread.cp_save+coprocessor_info[i].offset,i);
437 coprocessor_info[i].owner = 0;
438 disable_coprocessor(i);
439 }
440 }
441
442 local_irq_restore(flags);
443
444 /* Now restore coprocessor & extra state: */
445
446 memcpy(tsk->thread.cp_save,
447 (unsigned char*)fpregs + _xtensa_reginfo_table_size,
448 XTENSA_CP_EXTRA_SIZE);
449#endif
450 return 0;
451}
452/*
453 * Fill in the CP structure for a core dump for a particular task.
454 */
455
456int
457dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
458{
459/* see asm/coprocessor.h for this magic number 16 */
460#if TOTAL_CPEXTRA_SIZE > 16
461 do_save_fpregs (r, regs, task);
462
463 /* For now, bit 16 means some extra state may be present: */
464// FIXME!! need to track to return more accurate mask
465 return 0x10000 | XCHAL_CP_MASK;
466#else
467 return 0; /* no coprocessors active on this processor */
468#endif
469}
470
471/*
472 * Fill in the CP structure for a core dump.
473 * This includes any FPU coprocessor.
474 * Here, we dump all coprocessors, and other ("extra") custom state.
475 *
476 * This function is called by elf_core_dump() in fs/binfmt_elf.c
477 * (in which case 'regs' comes from calls to do_coredump, see signals.c).
478 */
479int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
480{
481 return dump_task_fpu(regs, current, r);
482}
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
new file mode 100644
index 000000000000..9ef07a4dd2a2
--- /dev/null
+++ b/arch/xtensa/kernel/ptrace.c
@@ -0,0 +1,407 @@
1// TODO some minor issues
2/*
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 2001 - 2005 Tensilica Inc.
8 *
9 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
10 * Chris Zankel <chris@zankel.net>
11 * Scott Foehner<sfoehner@yahoo.com>,
12 * Kevin Chea
13 * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca>
14 */
15
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/mm.h>
20#include <linux/errno.h>
21#include <linux/ptrace.h>
22#include <linux/smp.h>
23#include <linux/smp_lock.h>
24#include <linux/security.h>
25
26#include <asm/pgtable.h>
27#include <asm/page.h>
28#include <asm/system.h>
29#include <asm/uaccess.h>
30#include <asm/ptrace.h>
31#include <asm/elf.h>
32
33#define TEST_KERNEL // verify kernel operations FIXME: remove
34
35
36/*
37 * Called by kernel/ptrace.c when detaching..
38 *
39 * Make sure single step bits etc are not set.
40 */
41
42void ptrace_disable(struct task_struct *child)
43{
44 /* Nothing to do.. */
45}
46
47int sys_ptrace(long request, long pid, long addr, long data)
48{
49 struct task_struct *child;
50 int ret = -EPERM;
51
52 lock_kernel();
53
54#if 0
55 if ((int)request != 1)
56 printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
57 (int) request, (int) pid, (unsigned long) addr,
58 (unsigned long) data);
59#endif
60
61 if (request == PTRACE_TRACEME) {
62
63 /* Are we already being traced? */
64
65 if (current->ptrace & PT_PTRACED)
66 goto out;
67
68 if ((ret = security_ptrace(current->parent, current)))
69 goto out;
70
71 /* Set the ptrace bit in the process flags. */
72
73 current->ptrace |= PT_PTRACED;
74 ret = 0;
75 goto out;
76 }
77
78 ret = -ESRCH;
79 read_lock(&tasklist_lock);
80 child = find_task_by_pid(pid);
81 if (child)
82 get_task_struct(child);
83 read_unlock(&tasklist_lock);
84 if (!child)
85 goto out;
86
87 ret = -EPERM;
88 if (pid == 1) /* you may not mess with init */
89 goto out;
90
91 if (request == PTRACE_ATTACH) {
92 ret = ptrace_attach(child);
93 goto out_tsk;
94 }
95
96 if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
97 goto out_tsk;
98
99 switch (request) {
100 case PTRACE_PEEKTEXT: /* read word at location addr. */
101 case PTRACE_PEEKDATA:
102 {
103 unsigned long tmp;
104 int copied;
105
106 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
107 ret = -EIO;
108 if (copied != sizeof(tmp))
109 break;
110 ret = put_user(tmp,(unsigned long *) data);
111
112 goto out;
113 }
114
115 /* Read the word at location addr in the USER area. */
116
117 case PTRACE_PEEKUSR:
118 {
119 struct pt_regs *regs;
120 unsigned long tmp;
121
122 regs = xtensa_pt_regs(child);
123 tmp = 0; /* Default return value. */
124
125 switch(addr) {
126
127 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
128 {
129 int ar = addr - REG_AR_BASE - regs->windowbase * 4;
130 ar &= (XCHAL_NUM_AREGS - 1);
131 if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
132 tmp = regs->areg[ar];
133 else
134 ret = -EIO;
135 break;
136 }
137 case REG_A_BASE ... REG_A_BASE + 15:
138 tmp = regs->areg[addr - REG_A_BASE];
139 break;
140 case REG_PC:
141 tmp = regs->pc;
142 break;
143 case REG_PS:
144 /* Note: PS.EXCM is not set while user task is running;
145 * its being set in regs is for exception handling
146 * convenience. */
147 tmp = (regs->ps & ~XCHAL_PS_EXCM_MASK);
148 break;
149 case REG_WB:
150 tmp = regs->windowbase;
151 break;
152 case REG_WS:
153 tmp = regs->windowstart;
154 break;
155 case REG_LBEG:
156 tmp = regs->lbeg;
157 break;
158 case REG_LEND:
159 tmp = regs->lend;
160 break;
161 case REG_LCOUNT:
162 tmp = regs->lcount;
163 break;
164 case REG_SAR:
165 tmp = regs->sar;
166 break;
167 case REG_DEPC:
168 tmp = regs->depc;
169 break;
170 case REG_EXCCAUSE:
171 tmp = regs->exccause;
172 break;
173 case REG_EXCVADDR:
174 tmp = regs->excvaddr;
175 break;
176 case SYSCALL_NR:
177 tmp = regs->syscall;
178 break;
179 default:
180 tmp = 0;
181 ret = -EIO;
182 goto out;
183 }
184 ret = put_user(tmp, (unsigned long *) data);
185 goto out;
186 }
187
188 case PTRACE_POKETEXT: /* write the word at location addr. */
189 case PTRACE_POKEDATA:
190 if (access_process_vm(child, addr, &data, sizeof(data), 1)
191 == sizeof(data))
192 break;
193 ret = -EIO;
194 goto out;
195
196 case PTRACE_POKEUSR:
197 {
198 struct pt_regs *regs;
199 regs = xtensa_pt_regs(child);
200
201 switch (addr) {
202 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
203 {
204 int ar = addr - REG_AR_BASE - regs->windowbase * 4;
205 if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
206 regs->areg[ar & (XCHAL_NUM_AREGS - 1)] = data;
207 else
208 ret = -EIO;
209 break;
210 }
211 case REG_A_BASE ... REG_A_BASE + 15:
212 regs->areg[addr - REG_A_BASE] = data;
213 break;
214 case REG_PC:
215 regs->pc = data;
216 break;
217 case SYSCALL_NR:
218 regs->syscall = data;
219 break;
220#ifdef TEST_KERNEL
221 case REG_WB:
222 regs->windowbase = data;
223 break;
224 case REG_WS:
225 regs->windowstart = data;
226 break;
227#endif
228
229 default:
230 /* The rest are not allowed. */
231 ret = -EIO;
232 break;
233 }
234 break;
235 }
236
237 /* continue and stop at next (return from) syscall */
238 case PTRACE_SYSCALL:
239 case PTRACE_CONT: /* restart after signal. */
240 {
241 ret = -EIO;
242 if ((unsigned long) data > _NSIG)
243 break;
244 if (request == PTRACE_SYSCALL)
245 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
246 else
247 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
248 child->exit_code = data;
249 /* Make sure the single step bit is not set. */
250 child->ptrace &= ~PT_SINGLESTEP;
251 wake_up_process(child);
252 ret = 0;
253 break;
254 }
255
256 /*
257 * make the child exit. Best I can do is send it a sigkill.
258 * perhaps it should be put in the status that it wants to
259 * exit.
260 */
261 case PTRACE_KILL:
262 ret = 0;
263 if (child->state == EXIT_ZOMBIE) /* already dead */
264 break;
265 child->exit_code = SIGKILL;
266 child->ptrace &= ~PT_SINGLESTEP;
267 wake_up_process(child);
268 break;
269
270 case PTRACE_SINGLESTEP:
271 ret = -EIO;
272 if ((unsigned long) data > _NSIG)
273 break;
274 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
275 child->ptrace |= PT_SINGLESTEP;
276 child->exit_code = data;
277 wake_up_process(child);
278 ret = 0;
279 break;
280
281 case PTRACE_GETREGS:
282 {
283 /* 'data' points to user memory in which to write.
284 * Mainly due to the non-live register values, we
285 * reformat the register values into something more
286 * standard. For convenience, we use the handy
287 * elf_gregset_t format. */
288
289 xtensa_gregset_t format;
290 struct pt_regs *regs = xtensa_pt_regs(child);
291
292 do_copy_regs (&format, regs, child);
293
294 /* Now, copy to user space nice and easy... */
295 ret = 0;
296 if (copy_to_user((void *)data, &format, sizeof(elf_gregset_t)))
297 ret = -EFAULT;
298 break;
299 }
300
301 case PTRACE_SETREGS:
302 {
303 /* 'data' points to user memory that contains the new
304 * values in the elf_gregset_t format. */
305
306 xtensa_gregset_t format;
307 struct pt_regs *regs = xtensa_pt_regs(child);
308
309 if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){
310 ret = -EFAULT;
311 break;
312 }
313
314 /* FIXME: Perhaps we want some sanity checks on
315 * these user-space values? See ARM version. Are
316 * debuggers a security concern? */
317
318 do_restore_regs (&format, regs, child);
319
320 ret = 0;
321 break;
322 }
323
324 case PTRACE_GETFPREGS:
325 {
326 /* 'data' points to user memory in which to write.
327 * For convenience, we use the handy
328 * elf_fpregset_t format. */
329
330 elf_fpregset_t fpregs;
331 struct pt_regs *regs = xtensa_pt_regs(child);
332
333 do_save_fpregs (&fpregs, regs, child);
334
335 /* Now, copy to user space nice and easy... */
336 ret = 0;
337 if (copy_to_user((void *)data, &fpregs, sizeof(elf_fpregset_t)))
338 ret = -EFAULT;
339
340 break;
341 }
342
343 case PTRACE_SETFPREGS:
344 {
345 /* 'data' points to user memory that contains the new
346 * values in the elf_fpregset_t format.
347 */
348 elf_fpregset_t fpregs;
349 struct pt_regs *regs = xtensa_pt_regs(child);
350
351 ret = 0;
352 if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) {
353 ret = -EFAULT;
354 break;
355 }
356
357 if (do_restore_fpregs (&fpregs, regs, child))
358 ret = -EIO;
359 break;
360 }
361
362 case PTRACE_GETFPREGSIZE:
363 /* 'data' points to 'unsigned long' set to the size
364 * of elf_fpregset_t
365 */
366 ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
367 break;
368
369 case PTRACE_DETACH: /* detach a process that was attached. */
370 ret = ptrace_detach(child, data);
371 break;
372
373 default:
374 ret = ptrace_request(child, request, addr, data);
375 goto out;
376 }
377out_tsk:
378 put_task_struct(child);
379out:
380 unlock_kernel();
381 return ret;
382}
383
384void do_syscall_trace(void)
385{
386 if (!test_thread_flag(TIF_SYSCALL_TRACE))
387 return;
388
389 if (!(current->ptrace & PT_PTRACED))
390 return;
391
392 /*
393 * The 0x80 provides a way for the tracing parent to distinguish
394 * between a syscall stop and SIGTRAP delivery
395 */
396 ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
397
398 /*
399 * this isn't the same as continuing with a signal, but it will do
400 * for normal use. strace only continues with a signal if the
401 * stopping signal is not SIGTRAP. -brl
402 */
403 if (current->exit_code) {
404 send_sig(current->exit_code, current, 1);
405 current->exit_code = 0;
406 }
407}
diff --git a/arch/xtensa/kernel/semaphore.c b/arch/xtensa/kernel/semaphore.c
new file mode 100644
index 000000000000..d40f4b1b75ac
--- /dev/null
+++ b/arch/xtensa/kernel/semaphore.c
@@ -0,0 +1,226 @@
1/*
2 * arch/xtensa/kernel/semaphore.c
3 *
4 * Generic semaphore code. Buyer beware. Do your own specific changes
5 * in <asm/semaphore-helper.h>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Copyright (C) 2001 - 2005 Tensilica Inc.
12 *
13 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
14 * Chris Zankel <chris@zankel.net>
15 * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca>
16 * Kevin Chea
17 */
18
19#include <linux/sched.h>
20#include <linux/wait.h>
21#include <linux/init.h>
22#include <asm/semaphore.h>
23#include <asm/errno.h>
24
25/*
26 * These two _must_ execute atomically wrt each other.
27 */
28
29static __inline__ void wake_one_more(struct semaphore * sem)
30{
31 atomic_inc((atomic_t *)&sem->sleepers);
32}
33
34static __inline__ int waking_non_zero(struct semaphore *sem)
35{
36 unsigned long flags;
37 int ret = 0;
38
39 spin_lock_irqsave(&semaphore_wake_lock, flags);
40 if (sem->sleepers > 0) {
41 sem->sleepers--;
42 ret = 1;
43 }
44 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
45 return ret;
46}
47
48/*
49 * waking_non_zero_interruptible:
50 * 1 got the lock
51 * 0 go to sleep
52 * -EINTR interrupted
53 *
54 * We must undo the sem->count down_interruptible() increment while we are
55 * protected by the spinlock in order to make atomic this atomic_inc() with the
56 * atomic_read() in wake_one_more(), otherwise we can race. -arca
57 */
58
59static __inline__ int waking_non_zero_interruptible(struct semaphore *sem,
60 struct task_struct *tsk)
61{
62 unsigned long flags;
63 int ret = 0;
64
65 spin_lock_irqsave(&semaphore_wake_lock, flags);
66 if (sem->sleepers > 0) {
67 sem->sleepers--;
68 ret = 1;
69 } else if (signal_pending(tsk)) {
70 atomic_inc(&sem->count);
71 ret = -EINTR;
72 }
73 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
74 return ret;
75}
76
77/*
78 * waking_non_zero_trylock:
79 * 1 failed to lock
80 * 0 got the lock
81 *
82 * We must undo the sem->count down_trylock() increment while we are
83 * protected by the spinlock in order to make atomic this atomic_inc() with the
84 * atomic_read() in wake_one_more(), otherwise we can race. -arca
85 */
86
87static __inline__ int waking_non_zero_trylock(struct semaphore *sem)
88{
89 unsigned long flags;
90 int ret = 1;
91
92 spin_lock_irqsave(&semaphore_wake_lock, flags);
93 if (sem->sleepers <= 0)
94 atomic_inc(&sem->count);
95 else {
96 sem->sleepers--;
97 ret = 0;
98 }
99 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
100 return ret;
101}
102
103spinlock_t semaphore_wake_lock;
104
105/*
106 * Semaphores are implemented using a two-way counter:
107 * The "count" variable is decremented for each process
108 * that tries to sleep, while the "waking" variable is
109 * incremented when the "up()" code goes to wake up waiting
110 * processes.
111 *
112 * Notably, the inline "up()" and "down()" functions can
113 * efficiently test if they need to do any extra work (up
114 * needs to do something only if count was negative before
115 * the increment operation.
116 *
117 * waking_non_zero() (from asm/semaphore.h) must execute
118 * atomically.
119 *
120 * When __up() is called, the count was negative before
121 * incrementing it, and we need to wake up somebody.
122 *
123 * This routine adds one to the count of processes that need to
124 * wake up and exit. ALL waiting processes actually wake up but
125 * only the one that gets to the "waking" field first will gate
126 * through and acquire the semaphore. The others will go back
127 * to sleep.
128 *
129 * Note that these functions are only called when there is
130 * contention on the lock, and as such all this is the
131 * "non-critical" part of the whole semaphore business. The
132 * critical part is the inline stuff in <asm/semaphore.h>
133 * where we want to avoid any extra jumps and calls.
134 */
135
136void __up(struct semaphore *sem)
137{
138 wake_one_more(sem);
139 wake_up(&sem->wait);
140}
141
142/*
143 * Perform the "down" function. Return zero for semaphore acquired,
144 * return negative for signalled out of the function.
145 *
146 * If called from __down, the return is ignored and the wait loop is
147 * not interruptible. This means that a task waiting on a semaphore
148 * using "down()" cannot be killed until someone does an "up()" on
149 * the semaphore.
150 *
151 * If called from __down_interruptible, the return value gets checked
152 * upon return. If the return value is negative then the task continues
153 * with the negative value in the return register (it can be tested by
154 * the caller).
155 *
156 * Either form may be used in conjunction with "up()".
157 *
158 */
159
160#define DOWN_VAR \
161 struct task_struct *tsk = current; \
162 wait_queue_t wait; \
163 init_waitqueue_entry(&wait, tsk);
164
165#define DOWN_HEAD(task_state) \
166 \
167 \
168 tsk->state = (task_state); \
169 add_wait_queue(&sem->wait, &wait); \
170 \
171 /* \
172 * Ok, we're set up. sem->count is known to be less than zero \
173 * so we must wait. \
174 * \
175 * We can let go the lock for purposes of waiting. \
176 * We re-acquire it after awaking so as to protect \
177 * all semaphore operations. \
178 * \
179 * If "up()" is called before we call waking_non_zero() then \
180 * we will catch it right away. If it is called later then \
181 * we will have to go through a wakeup cycle to catch it. \
182 * \
183 * Multiple waiters contend for the semaphore lock to see \
184 * who gets to gate through and who has to wait some more. \
185 */ \
186 for (;;) {
187
188#define DOWN_TAIL(task_state) \
189 tsk->state = (task_state); \
190 } \
191 tsk->state = TASK_RUNNING; \
192 remove_wait_queue(&sem->wait, &wait);
193
194void __sched __down(struct semaphore * sem)
195{
196 DOWN_VAR
197 DOWN_HEAD(TASK_UNINTERRUPTIBLE)
198 if (waking_non_zero(sem))
199 break;
200 schedule();
201 DOWN_TAIL(TASK_UNINTERRUPTIBLE)
202}
203
204int __sched __down_interruptible(struct semaphore * sem)
205{
206 int ret = 0;
207 DOWN_VAR
208 DOWN_HEAD(TASK_INTERRUPTIBLE)
209
210 ret = waking_non_zero_interruptible(sem, tsk);
211 if (ret)
212 {
213 if (ret == 1)
214 /* ret != 0 only if we get interrupted -arca */
215 ret = 0;
216 break;
217 }
218 schedule();
219 DOWN_TAIL(TASK_INTERRUPTIBLE)
220 return ret;
221}
222
223int __down_trylock(struct semaphore * sem)
224{
225 return waking_non_zero_trylock(sem);
226}
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
new file mode 100644
index 000000000000..1f5bf5d624e4
--- /dev/null
+++ b/arch/xtensa/kernel/setup.c
@@ -0,0 +1,520 @@
1/*
2 * arch/xtensa/setup.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1995 Linus Torvalds
9 * Copyright (C) 2001 - 2005 Tensilica Inc.
10 *
11 * Chris Zankel <chris@zankel.net>
12 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
13 * Kevin Chea
14 * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca>
15 */
16
17#include <linux/config.h>
18#include <linux/errno.h>
19#include <linux/init.h>
20#include <linux/proc_fs.h>
21#include <linux/tty.h>
22#include <linux/bootmem.h>
23#include <linux/kernel.h>
24
25#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
26# include <linux/console.h>
27#endif
28
29#ifdef CONFIG_RTC
30# include <linux/timex.h>
31#endif
32
33#ifdef CONFIG_PROC_FS
34# include <linux/seq_file.h>
35#endif
36
37#include <asm/system.h>
38#include <asm/bootparam.h>
39#include <asm/pgtable.h>
40#include <asm/processor.h>
41#include <asm/timex.h>
42#include <asm/platform.h>
43#include <asm/page.h>
44#include <asm/setup.h>
45
46#include <xtensa/config/system.h>
47
48#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
49struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16};
50#endif
51
52#ifdef CONFIG_BLK_DEV_FD
53extern struct fd_ops no_fd_ops;
54struct fd_ops *fd_ops;
55#endif
56
57#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
58extern struct ide_ops no_ide_ops;
59struct ide_ops *ide_ops;
60#endif
61
62extern struct rtc_ops no_rtc_ops;
63struct rtc_ops *rtc_ops;
64
65#ifdef CONFIG_PC_KEYB
66extern struct kbd_ops no_kbd_ops;
67struct kbd_ops *kbd_ops;
68#endif
69
70#ifdef CONFIG_BLK_DEV_INITRD
71extern void *initrd_start;
72extern void *initrd_end;
73extern void *__initrd_start;
74extern void *__initrd_end;
75int initrd_is_mapped = 0;
76extern int initrd_below_start_ok;
77#endif
78
79unsigned char aux_device_present;
80extern unsigned long loops_per_jiffy;
81
82/* Command line specified as configuration option. */
83
84static char command_line[COMMAND_LINE_SIZE];
85
86#ifdef CONFIG_CMDLINE_BOOL
87static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
88#endif
89
90sysmem_info_t __initdata sysmem;
91
92#ifdef CONFIG_BLK_DEV_INITRD
93int initrd_is_mapped;
94#endif
95
96extern void init_mmu(void);
97
98/*
99 * Boot parameter parsing.
100 *
101 * The Xtensa port uses a list of variable-sized tags to pass data to
102 * the kernel. The first tag must be a BP_TAG_FIRST tag for the list
103 * to be recognised. The list is terminated with a zero-sized
104 * BP_TAG_LAST tag.
105 */
106
107typedef struct tagtable {
108 u32 tag;
109 int (*parse)(const bp_tag_t*);
110} tagtable_t;
111
112#define __tagtable(tag, fn) static tagtable_t __tagtable_##fn \
113 __attribute__((unused, __section__(".taglist"))) = { tag, fn }
114
115/* parse current tag */
116
117static int __init parse_tag_mem(const bp_tag_t *tag)
118{
119 meminfo_t *mi = (meminfo_t*)(tag->data);
120
121 if (mi->type != MEMORY_TYPE_CONVENTIONAL)
122 return -1;
123
124 if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) {
125 printk(KERN_WARNING
126 "Ignoring memory bank 0x%08lx size %ldKB\n",
127 (unsigned long)mi->start,
128 (unsigned long)mi->end - (unsigned long)mi->start);
129 return -EINVAL;
130 }
131 sysmem.bank[sysmem.nr_banks].type = mi->type;
132 sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start);
133 sysmem.bank[sysmem.nr_banks].end = mi->end & PAGE_SIZE;
134 sysmem.nr_banks++;
135
136 return 0;
137}
138
139__tagtable(BP_TAG_MEMORY, parse_tag_mem);
140
141#ifdef CONFIG_BLK_DEV_INITRD
142
143static int __init parse_tag_initrd(const bp_tag_t* tag)
144{
145 meminfo_t* mi;
146 mi = (meminfo_t*)(tag->data);
147 initrd_start = (void*)(mi->start);
148 initrd_end = (void*)(mi->end);
149
150 return 0;
151}
152
153__tagtable(BP_TAG_INITRD, parse_tag_initrd);
154
155#endif /* CONFIG_BLK_DEV_INITRD */
156
157static int __init parse_tag_cmdline(const bp_tag_t* tag)
158{
159 strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE);
160 command_line[COMMAND_LINE_SIZE - 1] = '\0';
161 return 0;
162}
163
164__tagtable(BP_TAG_COMMAND_LINE, parse_tag_cmdline);
165
166static int __init parse_bootparam(const bp_tag_t* tag)
167{
168 extern tagtable_t __tagtable_begin, __tagtable_end;
169 tagtable_t *t;
170
171 /* Boot parameters must start with a BP_TAG_FIRST tag. */
172
173 if (tag->id != BP_TAG_FIRST) {
174 printk(KERN_WARNING "Invalid boot parameters!\n");
175 return 0;
176 }
177
178 tag = (bp_tag_t*)((unsigned long)tag + sizeof(bp_tag_t) + tag->size);
179
180 /* Parse all tags. */
181
182 while (tag != NULL && tag->id != BP_TAG_LAST) {
183 for (t = &__tagtable_begin; t < &__tagtable_end; t++) {
184 if (tag->id == t->tag) {
185 t->parse(tag);
186 break;
187 }
188 }
189 if (t == &__tagtable_end)
190 printk(KERN_WARNING "Ignoring tag "
191 "0x%08x\n", tag->id);
192 tag = (bp_tag_t*)((unsigned long)(tag + 1) + tag->size);
193 }
194
195 return 0;
196}
197
198/*
199 * Initialize architecture. (Early stage)
200 */
201
202void __init init_arch(bp_tag_t *bp_start)
203{
204
205#ifdef CONFIG_BLK_DEV_INITRD
206 initrd_start = &__initrd_start;
207 initrd_end = &__initrd_end;
208#endif
209
210 sysmem.nr_banks = 0;
211
212#ifdef CONFIG_CMDLINE_BOOL
213 strcpy(command_line, default_command_line);
214#endif
215
216 /* Parse boot parameters */
217
218 if (bp_start)
219 parse_bootparam(bp_start);
220
221 if (sysmem.nr_banks == 0) {
222 sysmem.nr_banks = 1;
223 sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START;
224 sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START
225 + PLATFORM_DEFAULT_MEM_SIZE;
226 }
227
228 /* Early hook for platforms */
229
230 platform_init(bp_start);
231
232 /* Initialize MMU. */
233
234 init_mmu();
235}
236
237/*
238 * Initialize system. Setup memory and reserve regions.
239 */
240
241extern char _end;
242extern char _stext;
243extern char _WindowVectors_text_start;
244extern char _WindowVectors_text_end;
245extern char _DebugInterruptVector_literal_start;
246extern char _DebugInterruptVector_text_end;
247extern char _KernelExceptionVector_literal_start;
248extern char _KernelExceptionVector_text_end;
249extern char _UserExceptionVector_literal_start;
250extern char _UserExceptionVector_text_end;
251extern char _DoubleExceptionVector_literal_start;
252extern char _DoubleExceptionVector_text_end;
253
254void __init setup_arch(char **cmdline_p)
255{
256 extern int mem_reserve(unsigned long, unsigned long, int);
257 extern void bootmem_init(void);
258
259 memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
260 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
261 *cmdline_p = command_line;
262
263 /* Reserve some memory regions */
264
265#ifdef CONFIG_BLK_DEV_INITRD
266 if (initrd_start < initrd_end) {
267 initrd_is_mapped = mem_reserve(__pa(initrd_start),
268 __pa(initrd_end), 0);
269 initrd_below_start_ok = 1;
270 } else {
271 initrd_start = 0;
272 }
273#endif
274
275 mem_reserve(__pa(&_stext),__pa(&_end), 1);
276
277 mem_reserve(__pa(&_WindowVectors_text_start),
278 __pa(&_WindowVectors_text_end), 0);
279
280 mem_reserve(__pa(&_DebugInterruptVector_literal_start),
281 __pa(&_DebugInterruptVector_text_end), 0);
282
283 mem_reserve(__pa(&_KernelExceptionVector_literal_start),
284 __pa(&_KernelExceptionVector_text_end), 0);
285
286 mem_reserve(__pa(&_UserExceptionVector_literal_start),
287 __pa(&_UserExceptionVector_text_end), 0);
288
289 mem_reserve(__pa(&_DoubleExceptionVector_literal_start),
290 __pa(&_DoubleExceptionVector_text_end), 0);
291
292 bootmem_init();
293
294 platform_setup(cmdline_p);
295
296
297 paging_init();
298
299#ifdef CONFIG_VT
300# if defined(CONFIG_VGA_CONSOLE)
301 conswitchp = &vga_con;
302# elif defined(CONFIG_DUMMY_CONSOLE)
303 conswitchp = &dummy_con;
304# endif
305#endif
306
307#if CONFIG_PCI
308 platform_pcibios_init();
309#endif
310}
311
312void machine_restart(char * cmd)
313{
314 platform_restart();
315}
316
317void machine_halt(void)
318{
319 platform_halt();
320 while (1);
321}
322
323void machine_power_off(void)
324{
325 platform_power_off();
326 while (1);
327}
328#ifdef CONFIG_PROC_FS
329
330/*
331 * Display some core information through /proc/cpuinfo.
332 */
333
334static int
335c_show(struct seq_file *f, void *slot)
336{
337 /* high-level stuff */
338 seq_printf(f,"processor\t: 0\n"
339 "vendor_id\t: Tensilica\n"
340 "model\t\t: Xtensa " XCHAL_HW_RELEASE_NAME "\n"
341 "core ID\t\t: " XCHAL_CORE_ID "\n"
342 "build ID\t: 0x%x\n"
343 "byte order\t: %s\n"
344 "cpu MHz\t\t: %lu.%02lu\n"
345 "bogomips\t: %lu.%02lu\n",
346 XCHAL_BUILD_UNIQUE_ID,
347 XCHAL_HAVE_BE ? "big" : "little",
348 CCOUNT_PER_JIFFY/(1000000/HZ),
349 (CCOUNT_PER_JIFFY/(10000/HZ)) % 100,
350 loops_per_jiffy/(500000/HZ),
351 (loops_per_jiffy/(5000/HZ)) % 100);
352
353 seq_printf(f,"flags\t\t: "
354#if XCHAL_HAVE_NMI
355 "nmi "
356#endif
357#if XCHAL_HAVE_DEBUG
358 "debug "
359# if XCHAL_HAVE_OCD
360 "ocd "
361# endif
362#endif
363#if XCHAL_HAVE_DENSITY
364 "density "
365#endif
366#if XCHAL_HAVE_BOOLEANS
367 "boolean "
368#endif
369#if XCHAL_HAVE_LOOPS
370 "loop "
371#endif
372#if XCHAL_HAVE_NSA
373 "nsa "
374#endif
375#if XCHAL_HAVE_MINMAX
376 "minmax "
377#endif
378#if XCHAL_HAVE_SEXT
379 "sext "
380#endif
381#if XCHAL_HAVE_CLAMPS
382 "clamps "
383#endif
384#if XCHAL_HAVE_MAC16
385 "mac16 "
386#endif
387#if XCHAL_HAVE_MUL16
388 "mul16 "
389#endif
390#if XCHAL_HAVE_MUL32
391 "mul32 "
392#endif
393#if XCHAL_HAVE_MUL32_HIGH
394 "mul32h "
395#endif
396#if XCHAL_HAVE_FP
397 "fpu "
398#endif
399 "\n");
400
401 /* Registers. */
402 seq_printf(f,"physical aregs\t: %d\n"
403 "misc regs\t: %d\n"
404 "ibreak\t\t: %d\n"
405 "dbreak\t\t: %d\n",
406 XCHAL_NUM_AREGS,
407 XCHAL_NUM_MISC_REGS,
408 XCHAL_NUM_IBREAK,
409 XCHAL_NUM_DBREAK);
410
411
412 /* Interrupt. */
413 seq_printf(f,"num ints\t: %d\n"
414 "ext ints\t: %d\n"
415 "int levels\t: %d\n"
416 "timers\t\t: %d\n"
417 "debug level\t: %d\n",
418 XCHAL_NUM_INTERRUPTS,
419 XCHAL_NUM_EXTINTERRUPTS,
420 XCHAL_NUM_INTLEVELS,
421 XCHAL_NUM_TIMERS,
422 XCHAL_DEBUGLEVEL);
423
424 /* Coprocessors */
425#if XCHAL_HAVE_CP
426 seq_printf(f, "coprocessors\t: %d\n", XCHAL_CP_NUM);
427#else
428 seq_printf(f, "coprocessors\t: none\n");
429#endif
430
431 /* {I,D}{RAM,ROM} and XLMI */
432 seq_printf(f,"inst ROMs\t: %d\n"
433 "inst RAMs\t: %d\n"
434 "data ROMs\t: %d\n"
435 "data RAMs\t: %d\n"
436 "XLMI ports\t: %d\n",
437 XCHAL_NUM_IROM,
438 XCHAL_NUM_IRAM,
439 XCHAL_NUM_DROM,
440 XCHAL_NUM_DRAM,
441 XCHAL_NUM_XLMI);
442
443 /* Cache */
444 seq_printf(f,"icache line size: %d\n"
445 "icache ways\t: %d\n"
446 "icache size\t: %d\n"
447 "icache flags\t: "
448#if XCHAL_ICACHE_LINE_LOCKABLE
449 "lock"
450#endif
451 "\n"
452 "dcache line size: %d\n"
453 "dcache ways\t: %d\n"
454 "dcache size\t: %d\n"
455 "dcache flags\t: "
456#if XCHAL_DCACHE_IS_WRITEBACK
457 "writeback"
458#endif
459#if XCHAL_DCACHE_LINE_LOCKABLE
460 "lock"
461#endif
462 "\n",
463 XCHAL_ICACHE_LINESIZE,
464 XCHAL_ICACHE_WAYS,
465 XCHAL_ICACHE_SIZE,
466 XCHAL_DCACHE_LINESIZE,
467 XCHAL_DCACHE_WAYS,
468 XCHAL_DCACHE_SIZE);
469
470 /* MMU */
471 seq_printf(f,"ASID bits\t: %d\n"
472 "ASID invalid\t: %d\n"
473 "ASID kernel\t: %d\n"
474 "rings\t\t: %d\n"
475 "itlb ways\t: %d\n"
476 "itlb AR ways\t: %d\n"
477 "dtlb ways\t: %d\n"
478 "dtlb AR ways\t: %d\n",
479 XCHAL_MMU_ASID_BITS,
480 XCHAL_MMU_ASID_INVALID,
481 XCHAL_MMU_ASID_KERNEL,
482 XCHAL_MMU_RINGS,
483 XCHAL_ITLB_WAYS,
484 XCHAL_ITLB_ARF_WAYS,
485 XCHAL_DTLB_WAYS,
486 XCHAL_DTLB_ARF_WAYS);
487
488 return 0;
489}
490
491/*
492 * We show only CPU #0 info.
493 */
494static void *
495c_start(struct seq_file *f, loff_t *pos)
496{
497 return (void *) ((*pos == 0) ? (void *)1 : NULL);
498}
499
500static void *
501c_next(struct seq_file *f, void *v, loff_t *pos)
502{
503 return NULL;
504}
505
506static void
507c_stop(struct seq_file *f, void *v)
508{
509}
510
511struct seq_operations cpuinfo_op =
512{
513 start: c_start,
514 next: c_next,
515 stop: c_stop,
516 show: c_show
517};
518
519#endif /* CONFIG_PROC_FS */
520
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
new file mode 100644
index 000000000000..df6e1e17b096
--- /dev/null
+++ b/arch/xtensa/kernel/signal.c
@@ -0,0 +1,713 @@
1// TODO coprocessor stuff
2/*
3 * linux/arch/xtensa/kernel/signal.c
4 *
5 * Copyright (C) 1991, 1992 Linus Torvalds
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 *
8 * Joe Taylor <joe@tensilica.com>
9 * Chris Zankel <chris@zankel.net>
10 *
11 *
12 *
13 */
14
15#include <xtensa/config/core.h>
16#include <xtensa/hal.h>
17#include <linux/sched.h>
18#include <linux/mm.h>
19#include <linux/smp.h>
20#include <linux/smp_lock.h>
21#include <linux/kernel.h>
22#include <linux/signal.h>
23#include <linux/errno.h>
24#include <linux/wait.h>
25#include <linux/ptrace.h>
26#include <linux/unistd.h>
27#include <linux/stddef.h>
28#include <linux/personality.h>
29#include <asm/ucontext.h>
30#include <asm/uaccess.h>
31#include <asm/pgtable.h>
32#include <asm/cacheflush.h>
33
34#define DEBUG_SIG 0
35
36#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37
38asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options,
39 struct rusage * ru);
40asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
41
42extern struct task_struct *coproc_owners[];
43
44
45/*
46 * Atomically swap in the new signal mask, and wait for a signal.
47 */
48
49int sys_sigsuspend(struct pt_regs *regs)
50{
51 old_sigset_t mask = (old_sigset_t) regs->areg[3];
52 sigset_t saveset;
53
54 mask &= _BLOCKABLE;
55 spin_lock_irq(&current->sighand->siglock);
56 saveset = current->blocked;
57 siginitset(&current->blocked, mask);
58 recalc_sigpending();
59 spin_unlock_irq(&current->sighand->siglock);
60
61 regs->areg[2] = -EINTR;
62 while (1) {
63 current->state = TASK_INTERRUPTIBLE;
64 schedule();
65 if (do_signal(regs, &saveset))
66 return -EINTR;
67 }
68}
69
70asmlinkage int
71sys_rt_sigsuspend(struct pt_regs *regs)
72{
73 sigset_t *unewset = (sigset_t *) regs->areg[4];
74 size_t sigsetsize = (size_t) regs->areg[3];
75 sigset_t saveset, newset;
76 /* XXX: Don't preclude handling different sized sigset_t's. */
77 if (sigsetsize != sizeof(sigset_t))
78 return -EINVAL;
79
80 if (copy_from_user(&newset, unewset, sizeof(newset)))
81 return -EFAULT;
82 sigdelsetmask(&newset, ~_BLOCKABLE);
83 spin_lock_irq(&current->sighand->siglock);
84 saveset = current->blocked;
85 current->blocked = newset;
86 recalc_sigpending();
87 spin_unlock_irq(&current->sighand->siglock);
88
89 regs->areg[2] = -EINTR;
90 while (1) {
91 current->state = TASK_INTERRUPTIBLE;
92 schedule();
93 if (do_signal(regs, &saveset))
94 return -EINTR;
95 }
96}
97
98asmlinkage int
99sys_sigaction(int sig, const struct old_sigaction *act,
100 struct old_sigaction *oact)
101{
102 struct k_sigaction new_ka, old_ka;
103 int ret;
104
105 if (act) {
106 old_sigset_t mask;
107 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
108 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
109 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
110 return -EFAULT;
111 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
112 __get_user(mask, &act->sa_mask);
113 siginitset(&new_ka.sa.sa_mask, mask);
114 }
115
116 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
117
118 if (!ret && oact) {
119 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
120 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
121 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
122 return -EFAULT;
123 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
124 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
125 }
126
127 return ret;
128}
129
130asmlinkage int
131sys_sigaltstack(struct pt_regs *regs)
132{
133 const stack_t *uss = (stack_t *) regs->areg[4];
134 stack_t *uoss = (stack_t *) regs->areg[3];
135
136 if (regs->depc > 64)
137 panic ("Double exception sys_sigreturn\n");
138
139
140 return do_sigaltstack(uss, uoss, regs->areg[1]);
141}
142
143
144/*
145 * Do a signal return; undo the signal stack.
146 */
147
148struct sigframe
149{
150 struct sigcontext sc;
151 struct _cpstate cpstate;
152 unsigned long extramask[_NSIG_WORDS-1];
153 unsigned char retcode[6];
154 unsigned int reserved[4]; /* Reserved area for chaining */
155 unsigned int window[4]; /* Window of 4 registers for initial context */
156};
157
158struct rt_sigframe
159{
160 struct siginfo info;
161 struct ucontext uc;
162 struct _cpstate cpstate;
163 unsigned char retcode[6];
164 unsigned int reserved[4]; /* Reserved area for chaining */
165 unsigned int window[4]; /* Window of 4 registers for initial context */
166};
167
168extern void release_all_cp (struct task_struct *);
169
170
171// FIXME restore_cpextra
172static inline int
173restore_cpextra (struct _cpstate *buf)
174{
175#if 0
176 /* The signal handler may have used coprocessors in which
177 * case they are still enabled. We disable them to force a
178 * reloading of the original task's CP state by the lazy
179 * context-switching mechanisms of CP exception handling.
180 * Also, we essentially discard any coprocessor state that the
181 * signal handler created. */
182
183 struct task_struct *tsk = current;
184 release_all_cp(tsk);
185 return __copy_from_user(tsk->thread.cpextra, buf, TOTAL_CPEXTRA_SIZE);
186#endif
187 return 0;
188}
189
190/* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately...
191 */
192
193
194static int
195restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
196{
197 struct thread_struct *thread;
198 unsigned int err = 0;
199 unsigned long ps;
200 struct _cpstate *buf;
201
202#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
203 COPY(pc);
204 COPY(depc);
205 COPY(wmask);
206 COPY(lbeg);
207 COPY(lend);
208 COPY(lcount);
209 COPY(sar);
210 COPY(windowbase);
211 COPY(windowstart);
212#undef COPY
213
214 /* For PS, restore only PS.CALLINC.
215 * Assume that all other bits are either the same as for the signal
216 * handler, or the user mode value doesn't matter (e.g. PS.OWB).
217 */
218 err |= __get_user(ps, &sc->sc_ps);
219 regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK)
220 | (ps & XCHAL_PS_CALLINC_MASK);
221
222 /* Additional corruption checks */
223
224 if ((regs->windowbase >= (XCHAL_NUM_AREGS/4))
225 || ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) )
226 err = 1;
227 if ((regs->lcount > 0)
228 && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
229 err = 1;
230
231 /* Restore extended register state.
232 * See struct thread_struct in processor.h.
233 */
234 thread = &current->thread;
235
236 err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4);
237 err |= __get_user(buf, &sc->sc_cpstate);
238 if (buf) {
239 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
240 goto badframe;
241 err |= restore_cpextra(buf);
242 }
243
244 regs->syscall = -1; /* disable syscall checks */
245 return err;
246
247badframe:
248 return 1;
249}
250
251static inline void
252flush_my_cpstate(struct task_struct *tsk)
253{
254 unsigned long flags;
255 local_irq_save(flags);
256
257#if 0 // FIXME
258 for (i = 0; i < XCHAL_CP_NUM; i++) {
259 if (tsk == coproc_owners[i]) {
260 xthal_validate_cp(i);
261 xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i);
262
263 /* Invalidate and "disown" the cp to allow
264 * callers the chance to reset cp state in the
265 * task_struct. */
266
267 xthal_invalidate_cp(i);
268 coproc_owners[i] = 0;
269 }
270 }
271#endif
272 local_irq_restore(flags);
273}
274
275/* Return codes:
276 0: nothing saved
277 1: stuff to save, successful
278 -1: stuff to save, error happened
279*/
280static int
281save_cpextra (struct _cpstate *buf)
282{
283#if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0)
284 return 0;
285#else
286
287 /* FIXME: If a task has never used a coprocessor, there is
288 * no need to save and restore anything. Tracking this
289 * information would allow us to optimize this section.
290 * Perhaps we can use current->used_math or (current->flags &
291 * PF_USEDFPU) or define a new field in the thread
292 * structure. */
293
294 /* We flush any live, task-owned cp state to the task_struct,
295 * then copy it all to the sigframe. Then we clear all
296 * cp/extra state in the task_struct, effectively
297 * clearing/resetting all cp/extra state for the signal
298 * handler (cp-exception handling will load these new values
299 * into the cp/extra registers.) This step is important for
300 * things like a floating-point cp, where the OS must reset
301 * the FCR to the default rounding mode. */
302
303 int err = 0;
304 struct task_struct *tsk = current;
305
306 flush_my_cpstate(tsk);
307 /* Note that we just copy everything: 'extra' and 'cp' state together.*/
308 err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
309 memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE);
310
311#if (XTENSA_CP_EXTRA_SIZE == 0)
312#error Sanity check on memset above, cpextra_size should not be zero.
313#endif
314
315 return err ? -1 : 1;
316#endif
317}
318
319static int
320setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate,
321 struct pt_regs *regs, unsigned long mask)
322{
323 struct thread_struct *thread;
324 int err = 0;
325
326//printk("setup_sigcontext\n");
327#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
328 COPY(pc);
329 COPY(ps);
330 COPY(depc);
331 COPY(wmask);
332 COPY(lbeg);
333 COPY(lend);
334 COPY(lcount);
335 COPY(sar);
336 COPY(windowbase);
337 COPY(windowstart);
338#undef COPY
339
340 /* Save extended register state.
341 * See struct thread_struct in processor.h.
342 */
343 thread = &current->thread;
344 err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4);
345 err |= save_cpextra(cpstate);
346 err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
347 /* non-iBCS2 extensions.. */
348 err |= __put_user(mask, &sc->oldmask);
349
350 return err;
351}
352
353asmlinkage int sys_sigreturn(struct pt_regs *regs)
354{
355 struct sigframe *frame = (struct sigframe *)regs->areg[1];
356 sigset_t set;
357 if (regs->depc > 64)
358 panic ("Double exception sys_sigreturn\n");
359
360 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
361 goto badframe;
362
363 if (__get_user(set.sig[0], &frame->sc.oldmask)
364 || (_NSIG_WORDS > 1
365 && __copy_from_user(&set.sig[1], &frame->extramask,
366 sizeof(frame->extramask))))
367 goto badframe;
368
369 sigdelsetmask(&set, ~_BLOCKABLE);
370
371 spin_lock_irq(&current->sighand->siglock);
372 current->blocked = set;
373 recalc_sigpending();
374 spin_unlock_irq(&current->sighand->siglock);
375
376 if (restore_sigcontext(regs, &frame->sc))
377 goto badframe;
378 return regs->areg[2];
379
380badframe:
381 force_sig(SIGSEGV, current);
382 return 0;
383}
384
385asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
386{
387 struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1];
388 sigset_t set;
389 stack_t st;
390 int ret;
391 if (regs->depc > 64)
392 {
393 printk("!!!!!!! DEPC !!!!!!!\n");
394 return 0;
395 }
396
397 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
398 goto badframe;
399
400 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
401 goto badframe;
402
403 sigdelsetmask(&set, ~_BLOCKABLE);
404 spin_lock_irq(&current->sighand->siglock);
405 current->blocked = set;
406 recalc_sigpending();
407 spin_unlock_irq(&current->sighand->siglock);
408
409 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
410 goto badframe;
411 ret = regs->areg[2];
412
413 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
414 goto badframe;
415 /* It is more difficult to avoid calling this function than to
416 call it and ignore errors. */
417 do_sigaltstack(&st, NULL, regs->areg[1]);
418
419 return ret;
420
421badframe:
422 force_sig(SIGSEGV, current);
423 return 0;
424}
425
426/*
427 * Set up a signal frame.
428 */
429
430/*
431 * Determine which stack to use..
432 */
433static inline void *
434get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
435{
436 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
437 sp = current->sas_ss_sp + current->sas_ss_size;
438
439 return (void *)((sp - frame_size) & -16ul);
440}
441
442#define USE_SIGRETURN 0
443#define USE_RT_SIGRETURN 1
444
445static int
446gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn)
447{
448 unsigned int retcall;
449 int err = 0;
450
451#if 0
452 /* Ignoring SA_RESTORER for now; it's supposed to be obsolete,
453 * and the xtensa glibc doesn't use it.
454 */
455 if (ka->sa.sa_flags & SA_RESTORER) {
456 regs->pr = (unsigned long) ka->sa.sa_restorer;
457 } else
458#endif /* 0 */
459 {
460
461#if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255)
462
463/* The 12-bit immediate is really split up within the 24-bit MOVI
464 * instruction. As long as the above system call numbers fit within
465 * 8-bits, the following code works fine. See the Xtensa ISA for
466 * details.
467 */
468
469#error Generating the MOVI instruction below breaks!
470#endif
471
472 retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn;
473
474#ifdef __XTENSA_EB__ /* Big Endian version */
475 /* Generate instruction: MOVI a2, retcall */
476 err |= __put_user(0x22, &codemem[0]);
477 err |= __put_user(0x0a, &codemem[1]);
478 err |= __put_user(retcall, &codemem[2]);
479 /* Generate instruction: SYSCALL */
480 err |= __put_user(0x00, &codemem[3]);
481 err |= __put_user(0x05, &codemem[4]);
482 err |= __put_user(0x00, &codemem[5]);
483
484#elif defined __XTENSA_EL__ /* Little Endian version */
485 /* Generate instruction: MOVI a2, retcall */
486 err |= __put_user(0x22, &codemem[0]);
487 err |= __put_user(0xa0, &codemem[1]);
488 err |= __put_user(retcall, &codemem[2]);
489 /* Generate instruction: SYSCALL */
490 err |= __put_user(0x00, &codemem[3]);
491 err |= __put_user(0x50, &codemem[4]);
492 err |= __put_user(0x00, &codemem[5]);
493#else
494#error Must use compiler for Xtensa processors.
495#endif
496 }
497
498 /* Flush generated code out of the data cache */
499
500 if (err == 0)
501 __flush_invalidate_cache_range((unsigned long)codemem, 6UL);
502
503 return err;
504}
505
506static void
507set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr,
508 void *handler, unsigned long arg1, void *arg2, void *arg3)
509{
510 /* Set up registers for signal handler */
511 start_thread(regs, (unsigned long) handler, (unsigned long) stack);
512
513 /* Set up a stack frame for a call4
514 * Note: PS.CALLINC is set to one by start_thread
515 */
516 regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000;
517 regs->areg[6] = arg1;
518 regs->areg[7] = (unsigned long) arg2;
519 regs->areg[8] = (unsigned long) arg3;
520}
521
522static void setup_frame(int sig, struct k_sigaction *ka,
523 sigset_t *set, struct pt_regs *regs)
524{
525 struct sigframe *frame;
526 int err = 0;
527 int signal;
528
529 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
530 if (regs->depc > 64)
531 {
532 printk("!!!!!!! DEPC !!!!!!!\n");
533 return;
534 }
535
536
537 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
538 goto give_sigsegv;
539
540 signal = current_thread_info()->exec_domain
541 && current_thread_info()->exec_domain->signal_invmap
542 && sig < 32
543 ? current_thread_info()->exec_domain->signal_invmap[sig]
544 : sig;
545
546 err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);
547
548 if (_NSIG_WORDS > 1) {
549 err |= __copy_to_user(frame->extramask, &set->sig[1],
550 sizeof(frame->extramask));
551 }
552
553 /* Create sys_sigreturn syscall in stack frame */
554 err |= gen_return_code(frame->retcode, USE_SIGRETURN);
555
556 if (err)
557 goto give_sigsegv;
558
559 /* Create signal handler execution context.
560 * Return context not modified until this point.
561 */
562 set_thread_state(regs, frame, frame->retcode,
563 ka->sa.sa_handler, signal, &frame->sc, NULL);
564
565 /* Set access mode to USER_DS. Nomenclature is outdated, but
566 * functionality is used in uaccess.h
567 */
568 set_fs(USER_DS);
569
570
571#if DEBUG_SIG
572 printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
573 current->comm, current->pid, signal, frame, regs->pc);
574#endif
575
576 return;
577
578give_sigsegv:
579 if (sig == SIGSEGV)
580 ka->sa.sa_handler = SIG_DFL;
581 force_sig(SIGSEGV, current);
582}
583
584static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
585 sigset_t *set, struct pt_regs *regs)
586{
587 struct rt_sigframe *frame;
588 int err = 0;
589 int signal;
590
591 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
592 if (regs->depc > 64)
593 panic ("Double exception sys_sigreturn\n");
594
595 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
596 goto give_sigsegv;
597
598 signal = current_thread_info()->exec_domain
599 && current_thread_info()->exec_domain->signal_invmap
600 && sig < 32
601 ? current_thread_info()->exec_domain->signal_invmap[sig]
602 : sig;
603
604 err |= copy_siginfo_to_user(&frame->info, info);
605
606 /* Create the ucontext. */
607 err |= __put_user(0, &frame->uc.uc_flags);
608 err |= __put_user(0, &frame->uc.uc_link);
609 err |= __put_user((void *)current->sas_ss_sp,
610 &frame->uc.uc_stack.ss_sp);
611 err |= __put_user(sas_ss_flags(regs->areg[1]),
612 &frame->uc.uc_stack.ss_flags);
613 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
614 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
615 regs, set->sig[0]);
616 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
617
618 /* Create sys_rt_sigreturn syscall in stack frame */
619 err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);
620
621 if (err)
622 goto give_sigsegv;
623
624 /* Create signal handler execution context.
625 * Return context not modified until this point.
626 */
627 set_thread_state(regs, frame, frame->retcode,
628 ka->sa.sa_handler, signal, &frame->info, &frame->uc);
629
630 /* Set access mode to USER_DS. Nomenclature is outdated, but
631 * functionality is used in uaccess.h
632 */
633 set_fs(USER_DS);
634
635#if DEBUG_SIG
636 printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
637 current->comm, current->pid, signal, frame, regs->pc);
638#endif
639
640 return;
641
642give_sigsegv:
643 if (sig == SIGSEGV)
644 ka->sa.sa_handler = SIG_DFL;
645 force_sig(SIGSEGV, current);
646}
647
648
649
650/*
651 * Note that 'init' is a special process: it doesn't get signals it doesn't
652 * want to handle. Thus you cannot kill init even with a SIGKILL even by
653 * mistake.
654 *
655 * Note that we go through the signals twice: once to check the signals that
656 * the kernel can handle, and then we build all the user-level signal handling
657 * stack-frames in one go after that.
658 */
659int do_signal(struct pt_regs *regs, sigset_t *oldset)
660{
661 siginfo_t info;
662 int signr;
663 struct k_sigaction ka;
664
665 if (!oldset)
666 oldset = &current->blocked;
667
668 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
669
670 /* Are we from a system call? */
671 if (regs->syscall >= 0) {
672 /* If so, check system call restarting.. */
673 switch (regs->areg[2]) {
674 case ERESTARTNOHAND:
675 case ERESTART_RESTARTBLOCK:
676 regs->areg[2] = -EINTR;
677 break;
678
679 case ERESTARTSYS:
680 if (!(ka.sa.sa_flags & SA_RESTART)) {
681 regs->areg[2] = -EINTR;
682 break;
683 }
684 /* fallthrough */
685 case ERESTARTNOINTR:
686 regs->areg[2] = regs->syscall;
687 regs->pc -= 3;
688 }
689 }
690
691 if (signr == 0)
692 return 0; /* no signals delivered */
693
694 /* Whee! Actually deliver the signal. */
695
696 /* Set up the stack frame */
697 if (ka.sa.sa_flags & SA_SIGINFO)
698 setup_rt_frame(signr, &ka, &info, oldset, regs);
699 else
700 setup_frame(signr, &ka, oldset, regs);
701
702 if (ka.sa.sa_flags & SA_ONESHOT)
703 ka.sa.sa_handler = SIG_DFL;
704
705 if (!(ka.sa.sa_flags & SA_NODEFER)) {
706 spin_lock_irq(&current->sighand->siglock);
707 sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
708 sigaddset(&current->blocked, signr);
709 recalc_sigpending();
710 spin_unlock_irq(&current->sighand->siglock);
711 }
712 return 1;
713}
diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c
new file mode 100644
index 000000000000..abc8ed6c7026
--- /dev/null
+++ b/arch/xtensa/kernel/syscalls.c
@@ -0,0 +1,418 @@
1/*
2 * arch/xtensa/kernel/syscall.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 * Copyright (C) 2000 Silicon Graphics, Inc.
10 * Copyright (C) 1995 - 2000 by Ralf Baechle
11 *
12 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
14 * Chris Zankel <chris@zankel.net>
15 * Kevin Chea
16 *
17 */
18
19#define DEBUG 0
20
21#include <linux/config.h>
22#include <linux/linkage.h>
23#include <linux/mm.h>
24#include <linux/smp.h>
25#include <linux/smp_lock.h>
26#include <linux/mman.h>
27#include <linux/sched.h>
28#include <linux/file.h>
29#include <linux/slab.h>
30#include <linux/utsname.h>
31#include <linux/unistd.h>
32#include <linux/stringify.h>
33#include <linux/syscalls.h>
34#include <linux/sem.h>
35#include <linux/msg.h>
36#include <linux/shm.h>
37#include <linux/errno.h>
38#include <asm/ptrace.h>
39#include <asm/signal.h>
40#include <asm/uaccess.h>
41#include <asm/hardirq.h>
42#include <asm/mman.h>
43#include <asm/shmparam.h>
44#include <asm/page.h>
45#include <asm/ipc.h>
46
47extern void do_syscall_trace(void);
48typedef int (*syscall_t)(void *a0,...);
49extern int (*do_syscalls)(struct pt_regs *regs, syscall_t fun,
50 int narg);
51extern syscall_t sys_call_table[];
52extern unsigned char sys_narg_table[];
53
54/*
55 * sys_pipe() is the normal C calling standard for creating a pipe. It's not
56 * the way unix traditional does this, though.
57 */
58
59int sys_pipe(int __user *userfds)
60{
61 int fd[2];
62 int error;
63
64 error = do_pipe(fd);
65 if (!error) {
66 if (copy_to_user(userfds, fd, 2 * sizeof(int)))
67 error = -EFAULT;
68 }
69 return error;
70}
71
72/*
73 * Common code for old and new mmaps.
74 */
75
76static inline long do_mmap2(unsigned long addr, unsigned long len,
77 unsigned long prot, unsigned long flags,
78 unsigned long fd, unsigned long pgoff)
79{
80 int error = -EBADF;
81 struct file * file = NULL;
82
83 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
84 if (!(flags & MAP_ANONYMOUS)) {
85 file = fget(fd);
86 if (!file)
87 goto out;
88 }
89
90 down_write(&current->mm->mmap_sem);
91 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
92 up_write(&current->mm->mmap_sem);
93
94 if (file)
95 fput(file);
96out:
97 return error;
98}
99
100unsigned long old_mmap(unsigned long addr, size_t len, int prot,
101 int flags, int fd, off_t offset)
102{
103 return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
104}
105
106long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
107 unsigned long flags, unsigned long fd, unsigned long pgoff)
108{
109 return do_mmap2(addr, len, prot, flags, fd, pgoff);
110}
111
112int sys_fork(struct pt_regs *regs)
113{
114 return do_fork(SIGCHLD, regs->areg[1], regs, 0, NULL, NULL);
115}
116
117int sys_vfork(struct pt_regs *regs)
118{
119 return do_fork(CLONE_VFORK|CLONE_VM|SIGCHLD, regs->areg[1],
120 regs, 0, NULL, NULL);
121}
122
123int sys_clone(struct pt_regs *regs)
124{
125 unsigned long clone_flags;
126 unsigned long newsp;
127 int __user *parent_tidptr, *child_tidptr;
128 clone_flags = regs->areg[4];
129 newsp = regs->areg[3];
130 parent_tidptr = (int __user *)regs->areg[5];
131 child_tidptr = (int __user *)regs->areg[6];
132 if (!newsp)
133 newsp = regs->areg[1];
134 return do_fork(clone_flags,newsp,regs,0,parent_tidptr,child_tidptr);
135}
136
137/*
138 * sys_execve() executes a new program.
139 */
140
141int sys_execve(struct pt_regs *regs)
142{
143 int error;
144 char * filename;
145
146 filename = getname((char *) (long)regs->areg[5]);
147 error = PTR_ERR(filename);
148 if (IS_ERR(filename))
149 goto out;
150 error = do_execve(filename, (char **) (long)regs->areg[3],
151 (char **) (long)regs->areg[4], regs);
152 putname(filename);
153
154out:
155 return error;
156}
157
158int sys_uname(struct old_utsname * name)
159{
160 if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
161 return 0;
162 return -EFAULT;
163}
164
165int sys_olduname(struct oldold_utsname * name)
166{
167 int error;
168
169 if (!name)
170 return -EFAULT;
171 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
172 return -EFAULT;
173
174 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
175 error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
176 error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
177 error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
178 error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
179 error -= __put_user(0,name->release+__OLD_UTS_LEN);
180 error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
181 error -= __put_user(0,name->version+__OLD_UTS_LEN);
182 error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
183 error -= __put_user(0,name->machine+__OLD_UTS_LEN);
184
185 return error ? -EFAULT : 0;
186}
187
188
189/*
190 * Build the string table for the builtin "poor man's strace".
191 */
192
193#if DEBUG
194#define SYSCALL(fun, narg) #fun,
195static char *sfnames[] = {
196#include "syscalls.h"
197};
198#undef SYS
199#endif
200
201void system_call (struct pt_regs *regs)
202{
203 syscall_t syscall;
204 unsigned long parm0, parm1, parm2, parm3, parm4, parm5;
205 int nargs, res;
206 unsigned int syscallnr;
207 int ps;
208
209#if DEBUG
210 int i;
211 unsigned long parms[6];
212 char *sysname;
213#endif
214
215 regs->syscall = regs->areg[2];
216
217 do_syscall_trace();
218
219 /* Have to load after syscall_trace because strace
220 * sometimes changes regs->syscall.
221 */
222 syscallnr = regs->syscall;
223
224 parm0 = parm1 = parm2 = parm3 = parm4 = parm5 = 0;
225
226 /* Restore interrupt level to syscall invoker's.
227 * If this were in assembly, we wouldn't disable
228 * interrupts in the first place:
229 */
230 local_save_flags (ps);
231 local_irq_restore((ps & ~XCHAL_PS_INTLEVEL_MASK) |
232 (regs->ps & XCHAL_PS_INTLEVEL_MASK) );
233
234 if (syscallnr > __NR_Linux_syscalls) {
235 regs->areg[2] = -ENOSYS;
236 return;
237 }
238
239 syscall = sys_call_table[syscallnr];
240 nargs = sys_narg_table[syscallnr];
241
242 if (syscall == NULL) {
243 regs->areg[2] = -ENOSYS;
244 return;
245 }
246
247 /* There shouldn't be more than six arguments in the table! */
248
249 if (nargs > 6)
250 panic("Internal error - too many syscall arguments (%d)!\n",
251 nargs);
252
253 /* Linux takes system-call arguments in registers. The ABI
254 * and Xtensa software conventions require the system-call
255 * number in a2. If an argument exists in a2, we move it to
256 * the next available register. Note that for improved
257 * efficiency, we do NOT shift all parameters down one
258 * register to maintain the original order.
259 *
260 * At best case (zero arguments), we just write the syscall
261 * number to a2. At worst case (1 to 6 arguments), we move
262 * the argument in a2 to the next available register, then
263 * write the syscall number to a2.
264 *
265 * For clarity, the following truth table enumerates all
266 * possibilities.
267 *
268 * arguments syscall number arg0, arg1, arg2, arg3, arg4, arg5
269 * --------- -------------- ----------------------------------
270 * 0 a2
271 * 1 a2 a3
272 * 2 a2 a4, a3
273 * 3 a2 a5, a3, a4
274 * 4 a2 a6, a3, a4, a5
275 * 5 a2 a7, a3, a4, a5, a6
276 * 6 a2 a8, a3, a4, a5, a6, a7
277 */
278 if (nargs) {
279 parm0 = regs->areg[nargs+2];
280 parm1 = regs->areg[3];
281 parm2 = regs->areg[4];
282 parm3 = regs->areg[5];
283 parm4 = regs->areg[6];
284 parm5 = regs->areg[7];
285 } else /* nargs == 0 */
286 parm0 = (unsigned long) regs;
287
288#if DEBUG
289 parms[0] = parm0;
290 parms[1] = parm1;
291 parms[2] = parm2;
292 parms[3] = parm3;
293 parms[4] = parm4;
294 parms[5] = parm5;
295
296 sysname = sfnames[syscallnr];
297 if (strncmp(sysname, "sys_", 4) == 0)
298 sysname = sysname + 4;
299
300 printk("\017SYSCALL:I:%x:%d:%s %s(", regs->pc, current->pid,
301 current->comm, sysname);
302 for (i = 0; i < nargs; i++)
303 printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
304 printk(")\n");
305#endif
306
307 res = syscall((void *)parm0, parm1, parm2, parm3, parm4, parm5);
308
309#if DEBUG
310 printk("\017SYSCALL:O:%d:%s %s(",current->pid, current->comm, sysname);
311 for (i = 0; i < nargs; i++)
312 printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
313 if (res < 4096)
314 printk(") = %d\n", res);
315 else
316 printk(") = %#x\n", res);
317#endif /* DEBUG */
318
319 regs->areg[2] = res;
320 do_syscall_trace();
321}
322
323/*
324 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
325 *
326 * This is really horribly ugly.
327 */
328
329int sys_ipc (uint call, int first, int second,
330 int third, void __user *ptr, long fifth)
331{
332 int version, ret;
333
334 version = call >> 16; /* hack for backward compatibility */
335 call &= 0xffff;
336 ret = -ENOSYS;
337
338 switch (call) {
339 case SEMOP:
340 ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
341 second, NULL);
342 break;
343
344 case SEMTIMEDOP:
345 ret = sys_semtimedop (first, (struct sembuf __user *)ptr,
346 second, (const struct timespec *) fifth);
347 break;
348
349 case SEMGET:
350 ret = sys_semget (first, second, third);
351 break;
352
353 case SEMCTL: {
354 union semun fourth;
355
356 if (ptr && !get_user(fourth.__pad, (void *__user *) ptr))
357 ret = sys_semctl (first, second, third, fourth);
358 break;
359 }
360
361 case MSGSND:
362 ret = sys_msgsnd (first, (struct msgbuf __user*) ptr,
363 second, third);
364 break;
365
366 case MSGRCV:
367 switch (version) {
368 case 0: {
369 struct ipc_kludge tmp;
370
371 if (ptr && !copy_from_user(&tmp,
372 (struct ipc_kludge *) ptr,
373 sizeof (tmp)))
374 ret = sys_msgrcv (first, tmp.msgp, second,
375 tmp.msgtyp, third);
376 break;
377 }
378
379 default:
380 ret = sys_msgrcv (first, (struct msgbuf __user *) ptr,
381 second, 0, third);
382 break;
383 }
384 break;
385
386 case MSGGET:
387 ret = sys_msgget ((key_t) first, second);
388 break;
389
390 case MSGCTL:
391 ret = sys_msgctl (first, second, (struct msqid_ds __user*) ptr);
392 break;
393
394 case SHMAT: {
395 ulong raddr;
396 ret = do_shmat (first, (char __user *) ptr, second, &raddr);
397
398 if (!ret)
399 ret = put_user (raddr, (ulong __user *) third);
400
401 break;
402 }
403
404 case SHMDT:
405 ret = sys_shmdt ((char __user *)ptr);
406 break;
407
408 case SHMGET:
409 ret = sys_shmget (first, second, third);
410 break;
411
412 case SHMCTL:
413 ret = sys_shmctl (first, second, (struct shmid_ds __user*) ptr);
414 break;
415 }
416 return ret;
417}
418
diff --git a/arch/xtensa/kernel/syscalls.h b/arch/xtensa/kernel/syscalls.h
new file mode 100644
index 000000000000..5b3f75f50feb
--- /dev/null
+++ b/arch/xtensa/kernel/syscalls.h
@@ -0,0 +1,248 @@
1/*
2 * arch/xtensa/kernel/syscalls.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
9 * Copyright (C) 2001 - 2005 Tensilica Inc.
10 *
11 * Changes by Joe Taylor <joe@tensilica.com>
12 */
13
14/*
15 * This file is being included twice - once to build a list of all
16 * syscalls and once to build a table of how many arguments each syscall
17 * accepts. Syscalls that receive a pointer to the saved registers are
18 * marked as having zero arguments.
19 *
20 * The binary compatibility calls are in a separate list.
21 *
22 * Entry '0' used to be system_call. It's removed to disable indirect
23 * system calls for now so user tasks can't recurse. See mips'
24 * sys_syscall for a comparable example.
25 */
26
27SYSCALL(0, 0) /* 00 */
28
29SYSCALL(sys_exit, 1)
30SYSCALL(sys_fork, 0)
31SYSCALL(sys_read, 3)
32SYSCALL(sys_write, 3)
33SYSCALL(sys_open, 3) /* 05 */
34SYSCALL(sys_close, 1)
35SYSCALL(sys_waitpid, 3)
36SYSCALL(sys_creat, 2)
37SYSCALL(sys_link, 2)
38SYSCALL(sys_unlink, 1) /* 10 */
39SYSCALL(sys_execve, 0)
40SYSCALL(sys_chdir, 1)
41SYSCALL(sys_time, 1)
42SYSCALL(sys_mknod, 3)
43SYSCALL(sys_chmod, 2) /* 15 */
44SYSCALL(sys_lchown, 3)
45SYSCALL(sys_ni_syscall, 0)
46SYSCALL(sys_stat, 2)
47SYSCALL(sys_lseek, 3)
48SYSCALL(sys_getpid, 0) /* 20 */
49SYSCALL(sys_mount, 5)
50SYSCALL(sys_oldumount, 1)
51SYSCALL(sys_setuid, 1)
52SYSCALL(sys_getuid, 0)
53SYSCALL(sys_stime, 1) /* 25 */
54SYSCALL(sys_ptrace, 4)
55SYSCALL(sys_alarm, 1)
56SYSCALL(sys_fstat, 2)
57SYSCALL(sys_pause, 0)
58SYSCALL(sys_utime, 2) /* 30 */
59SYSCALL(sys_ni_syscall, 0)
60SYSCALL(sys_ni_syscall, 0)
61SYSCALL(sys_access, 2)
62SYSCALL(sys_nice, 1)
63SYSCALL(sys_ni_syscall, 0) /* 35 */
64SYSCALL(sys_sync, 0)
65SYSCALL(sys_kill, 2)
66SYSCALL(sys_rename, 2)
67SYSCALL(sys_mkdir, 2)
68SYSCALL(sys_rmdir, 1) /* 40 */
69SYSCALL(sys_dup, 1)
70SYSCALL(sys_pipe, 1)
71SYSCALL(sys_times, 1)
72SYSCALL(sys_ni_syscall, 0)
73SYSCALL(sys_brk, 1) /* 45 */
74SYSCALL(sys_setgid, 1)
75SYSCALL(sys_getgid, 0)
76SYSCALL(sys_ni_syscall, 0) /* was signal(2) */
77SYSCALL(sys_geteuid, 0)
78SYSCALL(sys_getegid, 0) /* 50 */
79SYSCALL(sys_acct, 1)
80SYSCALL(sys_umount, 2)
81SYSCALL(sys_ni_syscall, 0)
82SYSCALL(sys_ioctl, 3)
83SYSCALL(sys_fcntl, 3) /* 55 */
84SYSCALL(sys_ni_syscall, 2)
85SYSCALL(sys_setpgid, 2)
86SYSCALL(sys_ni_syscall, 0)
87SYSCALL(sys_olduname, 1)
88SYSCALL(sys_umask, 1) /* 60 */
89SYSCALL(sys_chroot, 1)
90SYSCALL(sys_ustat, 2)
91SYSCALL(sys_dup2, 2)
92SYSCALL(sys_getppid, 0)
93SYSCALL(sys_getpgrp, 0) /* 65 */
94SYSCALL(sys_setsid, 0)
95SYSCALL(sys_sigaction, 3)
96SYSCALL(sys_sgetmask, 0)
97SYSCALL(sys_ssetmask, 1)
98SYSCALL(sys_setreuid, 2) /* 70 */
99SYSCALL(sys_setregid, 2)
100SYSCALL(sys_sigsuspend, 0)
101SYSCALL(sys_sigpending, 1)
102SYSCALL(sys_sethostname, 2)
103SYSCALL(sys_setrlimit, 2) /* 75 */
104SYSCALL(sys_getrlimit, 2)
105SYSCALL(sys_getrusage, 2)
106SYSCALL(sys_gettimeofday, 2)
107SYSCALL(sys_settimeofday, 2)
108SYSCALL(sys_getgroups, 2) /* 80 */
109SYSCALL(sys_setgroups, 2)
110SYSCALL(sys_ni_syscall, 0) /* old_select */
111SYSCALL(sys_symlink, 2)
112SYSCALL(sys_lstat, 2)
113SYSCALL(sys_readlink, 3) /* 85 */
114SYSCALL(sys_uselib, 1)
115SYSCALL(sys_swapon, 2)
116SYSCALL(sys_reboot, 3)
117SYSCALL(old_readdir, 3)
118SYSCALL(old_mmap, 6) /* 90 */
119SYSCALL(sys_munmap, 2)
120SYSCALL(sys_truncate, 2)
121SYSCALL(sys_ftruncate, 2)
122SYSCALL(sys_fchmod, 2)
123SYSCALL(sys_fchown, 3) /* 95 */
124SYSCALL(sys_getpriority, 2)
125SYSCALL(sys_setpriority, 3)
126SYSCALL(sys_ni_syscall, 0)
127SYSCALL(sys_statfs, 2)
128SYSCALL(sys_fstatfs, 2) /* 100 */
129SYSCALL(sys_ni_syscall, 3)
130SYSCALL(sys_socketcall, 2)
131SYSCALL(sys_syslog, 3)
132SYSCALL(sys_setitimer, 3)
133SYSCALL(sys_getitimer, 2) /* 105 */
134SYSCALL(sys_newstat, 2)
135SYSCALL(sys_newlstat, 2)
136SYSCALL(sys_newfstat, 2)
137SYSCALL(sys_uname, 1)
138SYSCALL(sys_ni_syscall, 0) /* 110 */
139SYSCALL(sys_vhangup, 0)
140SYSCALL(sys_ni_syscall, 0) /* was sys_idle() */
141SYSCALL(sys_ni_syscall, 0)
142SYSCALL(sys_wait4, 4)
143SYSCALL(sys_swapoff, 1) /* 115 */
144SYSCALL(sys_sysinfo, 1)
145SYSCALL(sys_ipc, 5) /* 6 really, but glibc uses only 5) */
146SYSCALL(sys_fsync, 1)
147SYSCALL(sys_sigreturn, 0)
148SYSCALL(sys_clone, 0) /* 120 */
149SYSCALL(sys_setdomainname, 2)
150SYSCALL(sys_newuname, 1)
151SYSCALL(sys_ni_syscall, 0) /* sys_modify_ldt */
152SYSCALL(sys_adjtimex, 1)
153SYSCALL(sys_mprotect, 3) /* 125 */
154SYSCALL(sys_sigprocmask, 3)
155SYSCALL(sys_ni_syscall, 2) /* old sys_create_module */
156SYSCALL(sys_init_module, 2)
157SYSCALL(sys_delete_module, 1)
158SYSCALL(sys_ni_syscall, 1) /* old sys_get_kernel_sysm */ /* 130 */
159SYSCALL(sys_quotactl, 0)
160SYSCALL(sys_getpgid, 1)
161SYSCALL(sys_fchdir, 1)
162SYSCALL(sys_bdflush, 2)
163SYSCALL(sys_sysfs, 3) /* 135 */
164SYSCALL(sys_personality, 1)
165SYSCALL(sys_ni_syscall, 0) /* for afs_syscall */
166SYSCALL(sys_setfsuid, 1)
167SYSCALL(sys_setfsgid, 1)
168SYSCALL(sys_llseek, 5) /* 140 */
169SYSCALL(sys_getdents, 3)
170SYSCALL(sys_select, 5)
171SYSCALL(sys_flock, 2)
172SYSCALL(sys_msync, 3)
173SYSCALL(sys_readv, 3) /* 145 */
174SYSCALL(sys_writev, 3)
175SYSCALL(sys_ni_syscall, 3)
176SYSCALL(sys_ni_syscall, 3)
177SYSCALL(sys_ni_syscall, 4) /* handled in fast syscall handler. */
178SYSCALL(sys_ni_syscall, 0) /* 150 */
179SYSCALL(sys_getsid, 1)
180SYSCALL(sys_fdatasync, 1)
181SYSCALL(sys_sysctl, 1)
182SYSCALL(sys_mlock, 2)
183SYSCALL(sys_munlock, 2) /* 155 */
184SYSCALL(sys_mlockall, 1)
185SYSCALL(sys_munlockall, 0)
186SYSCALL(sys_sched_setparam,2)
187SYSCALL(sys_sched_getparam,2)
188SYSCALL(sys_sched_setscheduler,3) /* 160 */
189SYSCALL(sys_sched_getscheduler,1)
190SYSCALL(sys_sched_yield,0)
191SYSCALL(sys_sched_get_priority_max,1)
192SYSCALL(sys_sched_get_priority_min,1)
193SYSCALL(sys_sched_rr_get_interval,2) /* 165 */
194SYSCALL(sys_nanosleep,2)
195SYSCALL(sys_mremap,4)
196SYSCALL(sys_accept, 3)
197SYSCALL(sys_bind, 3)
198SYSCALL(sys_connect, 3) /* 170 */
199SYSCALL(sys_getpeername, 3)
200SYSCALL(sys_getsockname, 3)
201SYSCALL(sys_getsockopt, 5)
202SYSCALL(sys_listen, 2)
203SYSCALL(sys_recv, 4) /* 175 */
204SYSCALL(sys_recvfrom, 6)
205SYSCALL(sys_recvmsg, 3)
206SYSCALL(sys_send, 4)
207SYSCALL(sys_sendmsg, 3)
208SYSCALL(sys_sendto, 6) /* 180 */
209SYSCALL(sys_setsockopt, 5)
210SYSCALL(sys_shutdown, 2)
211SYSCALL(sys_socket, 3)
212SYSCALL(sys_socketpair, 4)
213SYSCALL(sys_setresuid, 3) /* 185 */
214SYSCALL(sys_getresuid, 3)
215SYSCALL(sys_ni_syscall, 5) /* old sys_query_module */
216SYSCALL(sys_poll, 3)
217SYSCALL(sys_nfsservctl, 3)
218SYSCALL(sys_setresgid, 3) /* 190 */
219SYSCALL(sys_getresgid, 3)
220SYSCALL(sys_prctl, 5)
221SYSCALL(sys_rt_sigreturn, 0)
222SYSCALL(sys_rt_sigaction, 4)
223SYSCALL(sys_rt_sigprocmask, 4) /* 195 */
224SYSCALL(sys_rt_sigpending, 2)
225SYSCALL(sys_rt_sigtimedwait, 4)
226SYSCALL(sys_rt_sigqueueinfo, 3)
227SYSCALL(sys_rt_sigsuspend, 0)
228SYSCALL(sys_pread64, 5) /* 200 */
229SYSCALL(sys_pwrite64, 5)
230SYSCALL(sys_chown, 3)
231SYSCALL(sys_getcwd, 2)
232SYSCALL(sys_capget, 2)
233SYSCALL(sys_capset, 2) /* 205 */
234SYSCALL(sys_sigaltstack, 0)
235SYSCALL(sys_sendfile, 4)
236SYSCALL(sys_ni_syscall, 0)
237SYSCALL(sys_ni_syscall, 0)
238SYSCALL(sys_mmap2, 6) /* 210 */
239SYSCALL(sys_truncate64, 2)
240SYSCALL(sys_ftruncate64, 2)
241SYSCALL(sys_stat64, 2)
242SYSCALL(sys_lstat64, 2)
243SYSCALL(sys_fstat64, 2) /* 215 */
244SYSCALL(sys_pivot_root, 2)
245SYSCALL(sys_mincore, 3)
246SYSCALL(sys_madvise, 3)
247SYSCALL(sys_getdents64, 3)
248SYSCALL(sys_vfork, 0) /* 220 */
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
new file mode 100644
index 000000000000..e07287db5a40
--- /dev/null
+++ b/arch/xtensa/kernel/time.c
@@ -0,0 +1,227 @@
1/*
2 * arch/xtensa/kernel/time.c
3 *
4 * Timer and clock support.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 */
14
15#include <linux/config.h>
16#include <linux/errno.h>
17#include <linux/time.h>
18#include <linux/timex.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/irq.h>
23#include <linux/profile.h>
24#include <linux/delay.h>
25
26#include <asm/timex.h>
27#include <asm/platform.h>
28
29
30extern volatile unsigned long wall_jiffies;
31
32u64 jiffies_64 = INITIAL_JIFFIES;
33EXPORT_SYMBOL(jiffies_64);
34
35spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
36EXPORT_SYMBOL(rtc_lock);
37
38
39#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
40unsigned long ccount_per_jiffy; /* per 1/HZ */
41unsigned long ccount_nsec; /* nsec per ccount increment */
42#endif
43
44unsigned int last_ccount_stamp;
45static long last_rtc_update = 0;
46
47/*
48 * Scheduler clock - returns current tim in nanosec units.
49 */
50
51unsigned long long sched_clock(void)
52{
53 return (unsigned long long)jiffies * (1000000000 / HZ);
54}
55
56static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
57static struct irqaction timer_irqaction = {
58 .handler = timer_interrupt,
59 .flags = SA_INTERRUPT,
60 .name = "timer",
61};
62
63void __init time_init(void)
64{
65 time_t sec_o, sec_n = 0;
66
67 /* The platform must provide a function to calibrate the processor
68 * speed for the CALIBRATE.
69 */
70
71#if CONFIG_XTENSA_CALIBRATE_CCOUNT
72 printk("Calibrating CPU frequency ");
73 platform_calibrate_ccount();
74 printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
75 (int)(ccount_per_jiffy/(10000/HZ))%100);
76#endif
77
78 /* Set time from RTC (if provided) */
79
80 if (platform_get_rtc_time(&sec_o) == 0)
81 while (platform_get_rtc_time(&sec_n))
82 if (sec_o != sec_n)
83 break;
84
85 xtime.tv_nsec = 0;
86 last_rtc_update = xtime.tv_sec = sec_n;
87 last_ccount_stamp = get_ccount();
88
89 set_normalized_timespec(&wall_to_monotonic,
90 -xtime.tv_sec, -xtime.tv_nsec);
91
92 /* Initialize the linux timer interrupt. */
93
94 setup_irq(LINUX_TIMER_INT, &timer_irqaction);
95 set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
96}
97
98
99int do_settimeofday(struct timespec *tv)
100{
101 time_t wtm_sec, sec = tv->tv_sec;
102 long wtm_nsec, nsec = tv->tv_nsec;
103 unsigned long ccount;
104
105 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
106 return -EINVAL;
107
108 write_seqlock_irq(&xtime_lock);
109
110 /* This is revolting. We need to set "xtime" correctly. However, the
111 * value in this location is the value at the most recent update of
112 * wall time. Discover what correction gettimeofday() would have
113 * made, and then undo it!
114 */
115 ccount = get_ccount();
116 nsec -= (ccount - last_ccount_stamp) * CCOUNT_NSEC;
117 nsec -= (jiffies - wall_jiffies) * CCOUNT_PER_JIFFY * CCOUNT_NSEC;
118
119 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
120 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
121
122 set_normalized_timespec(&xtime, sec, nsec);
123 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
124
125 time_adjust = 0; /* stop active adjtime() */
126 time_status |= STA_UNSYNC;
127 time_maxerror = NTP_PHASE_LIMIT;
128 time_esterror = NTP_PHASE_LIMIT;
129 write_sequnlock_irq(&xtime_lock);
130 return 0;
131}
132
133EXPORT_SYMBOL(do_settimeofday);
134
135
136void do_gettimeofday(struct timeval *tv)
137{
138 unsigned long flags;
139 unsigned long sec, usec, delta, lost, seq;
140
141 do {
142 seq = read_seqbegin_irqsave(&xtime_lock, flags);
143
144 delta = get_ccount() - last_ccount_stamp;
145 sec = xtime.tv_sec;
146 usec = (xtime.tv_nsec / NSEC_PER_USEC);
147
148 lost = jiffies - wall_jiffies;
149
150 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
151
152 usec += lost * (1000000UL/HZ) + (delta * CCOUNT_NSEC) / NSEC_PER_USEC;
153 for (; usec >= 1000000; sec++, usec -= 1000000)
154 ;
155
156 tv->tv_sec = sec;
157 tv->tv_usec = usec;
158}
159
160EXPORT_SYMBOL(do_gettimeofday);
161
162/*
163 * The timer interrupt is called HZ times per second.
164 */
165
166irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
167{
168
169 unsigned long next;
170
171 next = get_linux_timer();
172
173again:
174 while ((signed long)(get_ccount() - next) > 0) {
175
176 profile_tick(CPU_PROFILING, regs);
177#ifndef CONFIG_SMP
178 update_process_times(user_mode(regs));
179#endif
180
181 write_seqlock(&xtime_lock);
182
183 last_ccount_stamp = next;
184 next += CCOUNT_PER_JIFFY;
185 do_timer (regs); /* Linux handler in kernel/timer.c */
186
187 if ((time_status & STA_UNSYNC) == 0 &&
188 xtime.tv_sec - last_rtc_update >= 659 &&
189 abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ &&
190 jiffies - wall_jiffies == 1) {
191
192 if (platform_set_rtc_time(xtime.tv_sec+1) == 0)
193 last_rtc_update = xtime.tv_sec+1;
194 else
195 /* Do it again in 60 s */
196 last_rtc_update += 60;
197 }
198 write_sequnlock(&xtime_lock);
199 }
200
201 /* NOTE: writing CCOMPAREn clears the interrupt. */
202
203 set_linux_timer (next);
204
205 /* Make sure we didn't miss any tick... */
206
207 if ((signed long)(get_ccount() - next) > 0)
208 goto again;
209
210 /* Allow platform to do something usefull (Wdog). */
211
212 platform_heartbeat();
213
214 return IRQ_HANDLED;
215}
216
217#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
218void __devinit calibrate_delay(void)
219{
220 loops_per_jiffy = CCOUNT_PER_JIFFY;
221 printk("Calibrating delay loop (skipped)... "
222 "%lu.%02lu BogoMIPS preset\n",
223 loops_per_jiffy/(1000000/HZ),
224 (loops_per_jiffy/(10000/HZ)) % 100);
225}
226#endif
227
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
new file mode 100644
index 000000000000..804246e743b1
--- /dev/null
+++ b/arch/xtensa/kernel/traps.c
@@ -0,0 +1,498 @@
1/*
2 * arch/xtensa/kernel/traps.c
3 *
4 * Exception handling.
5 *
6 * Derived from code with the following copyrights:
7 * Copyright (C) 1994 - 1999 by Ralf Baechle
8 * Modified for R3000 by Paul M. Antoine, 1995, 1996
9 * Complete output from die() by Ulf Carlsson, 1998
10 * Copyright (C) 1999 Silicon Graphics, Inc.
11 *
12 * Essentially rewritten for the Xtensa architecture port.
13 *
14 * Copyright (C) 2001 - 2005 Tensilica Inc.
15 *
16 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
17 * Chris Zankel <chris@zankel.net>
18 * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca>
19 * Kevin Chea
20 *
21 * This file is subject to the terms and conditions of the GNU General Public
22 * License. See the file "COPYING" in the main directory of this archive
23 * for more details.
24 */
25
26#include <linux/kernel.h>
27#include <linux/sched.h>
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/stringify.h>
31#include <linux/kallsyms.h>
32
33#include <asm/ptrace.h>
34#include <asm/timex.h>
35#include <asm/uaccess.h>
36#include <asm/pgtable.h>
37#include <asm/processor.h>
38
39#ifdef CONFIG_KGDB
40extern int gdb_enter;
41extern int return_from_debug_flag;
42#endif
43
44/*
45 * Machine specific interrupt handlers
46 */
47
48extern void kernel_exception(void);
49extern void user_exception(void);
50
51extern void fast_syscall_kernel(void);
52extern void fast_syscall_user(void);
53extern void fast_alloca(void);
54extern void fast_unaligned(void);
55extern void fast_second_level_miss(void);
56extern void fast_store_prohibited(void);
57extern void fast_coprocessor(void);
58
59extern void do_illegal_instruction (struct pt_regs*);
60extern void do_interrupt (struct pt_regs*);
61extern void do_unaligned_user (struct pt_regs*);
62extern void do_multihit (struct pt_regs*, unsigned long);
63extern void do_page_fault (struct pt_regs*, unsigned long);
64extern void do_debug (struct pt_regs*);
65extern void system_call (struct pt_regs*);
66
67/*
68 * The vector table must be preceded by a save area (which
69 * implies it must be in RAM, unless one places RAM immediately
70 * before a ROM and puts the vector at the start of the ROM (!))
71 */
72
73#define KRNL 0x01
74#define USER 0x02
75
76#define COPROCESSOR(x) \
77{ XCHAL_EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor }
78
79typedef struct {
80 int cause;
81 int fast;
82 void* handler;
83} dispatch_init_table_t;
84
85dispatch_init_table_t __init dispatch_init_table[] = {
86
87{ XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION, 0, do_illegal_instruction},
88{ XCHAL_EXCCAUSE_SYSTEM_CALL, KRNL, fast_syscall_kernel },
89{ XCHAL_EXCCAUSE_SYSTEM_CALL, USER, fast_syscall_user },
90{ XCHAL_EXCCAUSE_SYSTEM_CALL, 0, system_call },
91/* XCHAL_EXCCAUSE_INSTRUCTION_FETCH unhandled */
92/* XCHAL_EXCCAUSE_LOAD_STORE_ERROR unhandled*/
93{ XCHAL_EXCCAUSE_LEVEL1_INTERRUPT, 0, do_interrupt },
94{ XCHAL_EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca },
95/* XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */
96/* XCHAL_EXCCAUSE_PRIVILEGED unhandled */
97#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
98#ifdef CONFIG_UNALIGNED_USER
99{ XCHAL_EXCCAUSE_UNALIGNED, USER, fast_unaligned },
100#else
101{ XCHAL_EXCCAUSE_UNALIGNED, 0, do_unaligned_user },
102#endif
103{ XCHAL_EXCCAUSE_UNALIGNED, KRNL, fast_unaligned },
104#endif
105{ XCHAL_EXCCAUSE_ITLB_MISS, 0, do_page_fault },
106{ XCHAL_EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss},
107{ XCHAL_EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit },
108{ XCHAL_EXCCAUSE_ITLB_PRIVILEGE, 0, do_page_fault },
109/* XCHAL_EXCCAUSE_SIZE_RESTRICTION unhandled */
110{ XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE, 0, do_page_fault },
111{ XCHAL_EXCCAUSE_DTLB_MISS, USER|KRNL, fast_second_level_miss},
112{ XCHAL_EXCCAUSE_DTLB_MISS, 0, do_page_fault },
113{ XCHAL_EXCCAUSE_DTLB_MULTIHIT, 0, do_multihit },
114{ XCHAL_EXCCAUSE_DTLB_PRIVILEGE, 0, do_page_fault },
115/* XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */
116{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited },
117{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault },
118{ XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault },
119/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
120#if (XCHAL_CP_MASK & 1)
121COPROCESSOR(0),
122#endif
123#if (XCHAL_CP_MASK & 2)
124COPROCESSOR(1),
125#endif
126#if (XCHAL_CP_MASK & 4)
127COPROCESSOR(2),
128#endif
129#if (XCHAL_CP_MASK & 8)
130COPROCESSOR(3),
131#endif
132#if (XCHAL_CP_MASK & 16)
133COPROCESSOR(4),
134#endif
135#if (XCHAL_CP_MASK & 32)
136COPROCESSOR(5),
137#endif
138#if (XCHAL_CP_MASK & 64)
139COPROCESSOR(6),
140#endif
141#if (XCHAL_CP_MASK & 128)
142COPROCESSOR(7),
143#endif
144{ EXCCAUSE_MAPPED_DEBUG, 0, do_debug },
145{ -1, -1, 0 }
146
147};
148
149/* The exception table <exc_table> serves two functions:
150 * 1. it contains three dispatch tables (fast_user, fast_kernel, default-c)
151 * 2. it is a temporary memory buffer for the exception handlers.
152 */
153
154unsigned long exc_table[EXC_TABLE_SIZE/4];
155
156void die(const char*, struct pt_regs*, long);
157
158static inline void
159__die_if_kernel(const char *str, struct pt_regs *regs, long err)
160{
161 if (!user_mode(regs))
162 die(str, regs, err);
163}
164
165/*
166 * Unhandled Exceptions. Kill user task or panic if in kernel space.
167 */
168
169void do_unhandled(struct pt_regs *regs, unsigned long exccause)
170{
171 __die_if_kernel("Caught unhandled exception - should not happen",
172 regs, SIGKILL);
173
174 /* If in user mode, send SIGILL signal to current process */
175 printk("Caught unhandled exception in '%s' "
176 "(pid = %d, pc = %#010lx) - should not happen\n"
177 "\tEXCCAUSE is %ld\n",
178 current->comm, current->pid, regs->pc, exccause);
179 force_sig(SIGILL, current);
180}
181
182/*
183 * Multi-hit exception. This if fatal!
184 */
185
186void do_multihit(struct pt_regs *regs, unsigned long exccause)
187{
188 die("Caught multihit exception", regs, SIGKILL);
189}
190
191/*
192 * Level-1 interrupt.
193 * We currently have no priority encoding.
194 */
195
196unsigned long ignored_level1_interrupts;
197extern void do_IRQ(int, struct pt_regs *);
198
199void do_interrupt (struct pt_regs *regs)
200{
201 unsigned long intread = get_sr (INTREAD);
202 unsigned long intenable = get_sr (INTENABLE);
203 int i, mask;
204
205 /* Handle all interrupts (no priorities).
206 * (Clear the interrupt before processing, in case it's
207 * edge-triggered or software-generated)
208 */
209
210 for (i=0, mask = 1; i < XCHAL_NUM_INTERRUPTS; i++, mask <<= 1) {
211 if (mask & (intread & intenable)) {
212 set_sr (mask, INTCLEAR);
213 do_IRQ (i,regs);
214 }
215 }
216}
217
218/*
219 * Illegal instruction. Fatal if in kernel space.
220 */
221
222void
223do_illegal_instruction(struct pt_regs *regs)
224{
225 __die_if_kernel("Illegal instruction in kernel", regs, SIGKILL);
226
227 /* If in user mode, send SIGILL signal to current process. */
228
229 printk("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
230 current->comm, current->pid, regs->pc);
231 force_sig(SIGILL, current);
232}
233
234
235/*
236 * Handle unaligned memory accesses from user space. Kill task.
237 *
238 * If CONFIG_UNALIGNED_USER is not set, we don't allow unaligned memory
239 * accesses causes from user space.
240 */
241
242#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
243#ifndef CONFIG_UNALIGNED_USER
244void
245do_unaligned_user (struct pt_regs *regs)
246{
247 siginfo_t info;
248
249 __die_if_kernel("Unhandled unaligned exception in kernel",
250 regs, SIGKILL);
251
252 current->thread.bad_vaddr = regs->excvaddr;
253 current->thread.error_code = -3;
254 printk("Unaligned memory access to %08lx in '%s' "
255 "(pid = %d, pc = %#010lx)\n",
256 regs->excvaddr, current->comm, current->pid, regs->pc);
257 info.si_signo = SIGBUS;
258 info.si_errno = 0;
259 info.si_code = BUS_ADRALN;
260 info.si_addr = (void *) regs->excvaddr;
261 force_sig_info(SIGSEGV, &info, current);
262
263}
264#endif
265#endif
266
267void
268do_debug(struct pt_regs *regs)
269{
270#ifdef CONFIG_KGDB
271 /* If remote debugging is configured AND enabled, we give control to
272 * kgdb. Otherwise, we fall through, perhaps giving control to the
273 * native debugger.
274 */
275
276 if (gdb_enter) {
277 extern void gdb_handle_exception(struct pt_regs *);
278 gdb_handle_exception(regs);
279 return_from_debug_flag = 1;
280 return;
281 }
282#endif
283
284 __die_if_kernel("Breakpoint in kernel", regs, SIGKILL);
285
286 /* If in user mode, send SIGTRAP signal to current process */
287
288 force_sig(SIGTRAP, current);
289}
290
291
292/*
293 * Initialize dispatch tables.
294 *
295 * The exception vectors are stored compressed the __init section in the
296 * dispatch_init_table. This function initializes the following three tables
297 * from that compressed table:
298 * - fast user first dispatch table for user exceptions
299 * - fast kernel first dispatch table for kernel exceptions
300 * - default C-handler C-handler called by the default fast handler.
301 *
302 * See vectors.S for more details.
303 */
304
305#define set_handler(idx,handler) (exc_table[idx] = (unsigned long) (handler))
306
307void trap_init(void)
308{
309 int i;
310
311 /* Setup default vectors. */
312
313 for(i = 0; i < 64; i++) {
314 set_handler(EXC_TABLE_FAST_USER/4 + i, user_exception);
315 set_handler(EXC_TABLE_FAST_KERNEL/4 + i, kernel_exception);
316 set_handler(EXC_TABLE_DEFAULT/4 + i, do_unhandled);
317 }
318
319 /* Setup specific handlers. */
320
321 for(i = 0; dispatch_init_table[i].cause >= 0; i++) {
322
323 int fast = dispatch_init_table[i].fast;
324 int cause = dispatch_init_table[i].cause;
325 void *handler = dispatch_init_table[i].handler;
326
327 if (fast == 0)
328 set_handler (EXC_TABLE_DEFAULT/4 + cause, handler);
329 if (fast && fast & USER)
330 set_handler (EXC_TABLE_FAST_USER/4 + cause, handler);
331 if (fast && fast & KRNL)
332 set_handler (EXC_TABLE_FAST_KERNEL/4 + cause, handler);
333 }
334
335 /* Initialize EXCSAVE_1 to hold the address of the exception table. */
336
337 i = (unsigned long)exc_table;
338 __asm__ __volatile__("wsr %0, "__stringify(EXCSAVE_1)"\n" : : "a" (i));
339}
340
341/*
342 * This function dumps the current valid window frame and other base registers.
343 */
344
345void show_regs(struct pt_regs * regs)
346{
347 int i, wmask;
348
349 wmask = regs->wmask & ~1;
350
351 for (i = 0; i < 32; i++) {
352 if (wmask & (1 << (i / 4)))
353 break;
354 if ((i % 8) == 0)
355 printk ("\n" KERN_INFO "a%02d: ", i);
356 printk("%08lx ", regs->areg[i]);
357 }
358 printk("\n");
359
360 printk("pc: %08lx, ps: %08lx, depc: %08lx, excvaddr: %08lx\n",
361 regs->pc, regs->ps, regs->depc, regs->excvaddr);
362 printk("lbeg: %08lx, lend: %08lx lcount: %08lx, sar: %08lx\n",
363 regs->lbeg, regs->lend, regs->lcount, regs->sar);
364 if (user_mode(regs))
365 printk("wb: %08lx, ws: %08lx, wmask: %08lx, syscall: %ld\n",
366 regs->windowbase, regs->windowstart, regs->wmask,
367 regs->syscall);
368}
369
370void show_trace(struct task_struct *task, unsigned long *sp)
371{
372 unsigned long a0, a1, pc;
373 unsigned long sp_start, sp_end;
374
375 a1 = (unsigned long)sp;
376
377 if (a1 == 0)
378 __asm__ __volatile__ ("mov %0, a1\n" : "=a"(a1));
379
380
381 sp_start = a1 & ~(THREAD_SIZE-1);
382 sp_end = sp_start + THREAD_SIZE;
383
384 printk("Call Trace:");
385#ifdef CONFIG_KALLSYMS
386 printk("\n");
387#endif
388 spill_registers();
389
390 while (a1 > sp_start && a1 < sp_end) {
391 sp = (unsigned long*)a1;
392
393 a0 = *(sp - 4);
394 a1 = *(sp - 3);
395
396 if (a1 <= (unsigned long) sp)
397 break;
398
399 pc = MAKE_PC_FROM_RA(a0, a1);
400
401 if (kernel_text_address(pc)) {
402 printk(" [<%08lx>] ", pc);
403 print_symbol("%s\n", pc);
404 }
405 }
406 printk("\n");
407}
408
409/*
410 * This routine abuses get_user()/put_user() to reference pointers
411 * with at least a bit of error checking ...
412 */
413
414static int kstack_depth_to_print = 24;
415
416void show_stack(struct task_struct *task, unsigned long *sp)
417{
418 int i = 0;
419 unsigned long *stack;
420
421 if (sp == 0)
422 __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
423
424 stack = sp;
425
426 printk("\nStack: ");
427
428 for (i = 0; i < kstack_depth_to_print; i++) {
429 if (kstack_end(sp))
430 break;
431 if (i && ((i % 8) == 0))
432 printk("\n ");
433 printk("%08lx ", *sp++);
434 }
435 printk("\n");
436 show_trace(task, stack);
437}
438
439void dump_stack(void)
440{
441 show_stack(current, NULL);
442}
443
444EXPORT_SYMBOL(dump_stack);
445
446
447void show_code(unsigned int *pc)
448{
449 long i;
450
451 printk("\nCode:");
452
453 for(i = -3 ; i < 6 ; i++) {
454 unsigned long insn;
455 if (__get_user(insn, pc + i)) {
456 printk(" (Bad address in pc)\n");
457 break;
458 }
459 printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>'));
460 }
461}
462
463spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
464
465void die(const char * str, struct pt_regs * regs, long err)
466{
467 static int die_counter;
468 int nl = 0;
469
470 console_verbose();
471 spin_lock_irq(&die_lock);
472
473 printk("%s: sig: %ld [#%d]\n", str, err, ++die_counter);
474#ifdef CONFIG_PREEMPT
475 printk("PREEMPT ");
476 nl = 1;
477#endif
478 if (nl)
479 printk("\n");
480 show_regs(regs);
481 if (!user_mode(regs))
482 show_stack(NULL, (unsigned long*)regs->areg[1]);
483
484 spin_unlock_irq(&die_lock);
485
486 if (in_interrupt())
487 panic("Fatal exception in interrupt");
488
489 if (panic_on_oops) {
490 printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
491 set_current_state(TASK_UNINTERRUPTIBLE);
492 schedule_timeout(5 * HZ);
493 panic("Fatal exception");
494 }
495 do_exit(err);
496}
497
498
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
new file mode 100644
index 000000000000..81808f0c6742
--- /dev/null
+++ b/arch/xtensa/kernel/vectors.S
@@ -0,0 +1,464 @@
1/*
2 * arch/xtensa/kernel/vectors.S
3 *
4 * This file contains all exception vectors (user, kernel, and double),
5 * as well as the window vectors (overflow and underflow), and the debug
6 * vector. These are the primary vectors executed by the processor if an
7 * exception occurs.
8 *
9 * This file is subject to the terms and conditions of the GNU General
10 * Public License. See the file "COPYING" in the main directory of
11 * this archive for more details.
12 *
13 * Copyright (C) 2005 Tensilica, Inc.
14 *
15 * Chris Zankel <chris@zankel.net>
16 *
17 */
18
19/*
20 * We use a two-level table approach. The user and kernel exception vectors
21 * use a first-level dispatch table to dispatch the exception to a registered
22 * fast handler or the default handler, if no fast handler was registered.
23 * The default handler sets up a C-stack and dispatches the exception to a
24 * registerd C handler in the second-level dispatch table.
25 *
26 * Fast handler entry condition:
27 *
28 * a0: trashed, original value saved on stack (PT_AREG0)
29 * a1: a1
30 * a2: new stack pointer, original value in depc
31 * a3: dispatch table
32 * depc: a2, original value saved on stack (PT_DEPC)
33 * excsave_1: a3
34 *
35 * The value for PT_DEPC saved to stack also functions as a boolean to
36 * indicate that the exception is either a double or a regular exception:
37 *
38 * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception
39 * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
40 *
41 * Note: Neither the kernel nor the user exception handler generate literals.
42 *
43 */
44
45#include <linux/linkage.h>
46#include <asm/ptrace.h>
47#include <asm/ptrace.h>
48#include <asm/current.h>
49#include <asm/offsets.h>
50#include <asm/pgtable.h>
51#include <asm/processor.h>
52#include <asm/page.h>
53#include <asm/thread_info.h>
54#include <asm/processor.h>
55
56
57/*
58 * User exception vector. (Exceptions with PS.UM == 1, PS.EXCM == 0)
59 *
60 * We get here when an exception occurred while we were in userland.
61 * We switch to the kernel stack and jump to the first level handler
62 * associated to the exception cause.
63 *
64 * Note: the saved kernel stack pointer (EXC_TABLE_KSTK) is already
65 * decremented by PT_USER_SIZE.
66 */
67
68 .section .UserExceptionVector.text, "ax"
69
70ENTRY(_UserExceptionVector)
71
72 xsr a3, EXCSAVE_1 # save a3 and get dispatch table
73 wsr a2, DEPC # save a2
74 l32i a2, a3, EXC_TABLE_KSTK # load kernel stack to a2
75 s32i a0, a2, PT_AREG0 # save a0 to ESF
76 rsr a0, EXCCAUSE # retrieve exception cause
77 s32i a0, a2, PT_DEPC # mark it as a regular exception
78 addx4 a0, a0, a3 # find entry in table
79 l32i a0, a0, EXC_TABLE_FAST_USER # load handler
80 jx a0
81
82/*
83 * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0)
84 *
85 * We get this exception when we were already in kernel space.
86 * We decrement the current stack pointer (kernel) by PT_SIZE and
87 * jump to the first-level handler associated with the exception cause.
88 *
89 * Note: we need to preserve space for the spill region.
90 */
91
92 .section .KernelExceptionVector.text, "ax"
93
94ENTRY(_KernelExceptionVector)
95
96 xsr a3, EXCSAVE_1 # save a3, and get dispatch table
97 wsr a2, DEPC # save a2
98 addi a2, a1, -16-PT_SIZE # adjust stack pointer
99 s32i a0, a2, PT_AREG0 # save a0 to ESF
100 rsr a0, EXCCAUSE # retrieve exception cause
101 s32i a0, a2, PT_DEPC # mark it as a regular exception
102 addx4 a0, a0, a3 # find entry in table
103 l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address
104 jx a0
105
106
107/*
108 * Double exception vector (Exceptions with PS.EXCM == 1)
109 * We get this exception when another exception occurs while were are
110 * already in an exception, such as window overflow/underflow exception,
111 * or 'expected' exceptions, for example memory exception when we were trying
112 * to read data from an invalid address in user space.
113 *
114 * Note that this vector is never invoked for level-1 interrupts, because such
115 * interrupts are disabled (masked) when PS.EXCM is set.
116 *
117 * We decode the exception and take the appropriate action. However, the
118 * double exception vector is much more careful, because a lot more error
119 * cases go through the double exception vector than through the user and
120 * kernel exception vectors.
121 *
122 * Occasionally, the kernel expects a double exception to occur. This usually
123 * happens when accessing user-space memory with the user's permissions
124 * (l32e/s32e instructions). The kernel state, though, is not always suitable
125 * for immediate transfer of control to handle_double, where "normal" exception
126 * processing occurs. Also in kernel mode, TLB misses can occur if accessing
127 * vmalloc memory, possibly requiring repair in a double exception handler.
128 *
129 * The variable at TABLE_FIXUP offset from the pointer in EXCSAVE_1 doubles as
130 * a boolean variable and a pointer to a fixup routine. If the variable
131 * EXC_TABLE_FIXUP is non-zero, this handler jumps to that address. A value of
132 * zero indicates to use the default kernel/user exception handler.
133 * There is only one exception, when the value is identical to the exc_table
134 * label, the kernel is in trouble. This mechanism is used to protect critical
135 * sections, mainly when the handler writes to the stack to assert the stack
136 * pointer is valid. Once the fixup/default handler leaves that area, the
137 * EXC_TABLE_FIXUP variable is reset to the fixup handler or zero.
138 *
139 * Procedures wishing to use this mechanism should set EXC_TABLE_FIXUP to the
140 * nonzero address of a fixup routine before it could cause a double exception
141 * and reset it before it returns.
142 *
143 * Some other things to take care of when a fast exception handler doesn't
144 * specify a particular fixup handler but wants to use the default handlers:
145 *
146 * - The original stack pointer (in a1) must not be modified. The fast
147 * exception handler should only use a2 as the stack pointer.
148 *
149 * - If the fast handler manipulates the stack pointer (in a2), it has to
150 * register a valid fixup handler and cannot use the default handlers.
151 *
152 * - The handler can use any other generic register from a3 to a15, but it
153 * must save the content of these registers to stack (PT_AREG3...PT_AREGx)
154 *
155 * - These registers must be saved before a double exception can occur.
156 *
157 * - If we ever implement handling signals while in double exceptions, the
158 * number of registers a fast handler has saved (excluding a0 and a1) must
159 * be written to PT_AREG1. (1 if only a3 is used, 2 for a3 and a4, etc. )
160 *
161 * The fixup handlers are special handlers:
162 *
163 * - Fixup entry conditions differ from regular exceptions:
164 *
165 * a0: DEPC
166 * a1: a1
167 * a2: trashed, original value in EXC_TABLE_DOUBLE_A2
168 * a3: exctable
169 * depc: a0
170 * excsave_1: a3
171 *
172 * - When the kernel enters the fixup handler, it still assumes it is in a
173 * critical section, so EXC_TABLE_FIXUP variable is set to exc_table.
174 * The fixup handler, therefore, has to re-register itself as the fixup
175 * handler before it returns from the double exception.
176 *
177 * - Fixup handler can share the same exception frame with the fast handler.
178 * The kernel stack pointer is not changed when entering the fixup handler.
179 *
180 * - Fixup handlers can jump to the default kernel and user exception
181 * handlers. Before it jumps, though, it has to setup a exception frame
182 * on stack. Because the default handler resets the register fixup handler
183 * the fixup handler must make sure that the default handler returns to
184 * it instead of the exception address, so it can re-register itself as
185 * the fixup handler.
186 *
187 * In case of a critical condition where the kernel cannot recover, we jump
188 * to unrecoverable_exception with the following entry conditions.
189 * All registers a0...a15 are unchanged from the last exception, except:
190 *
191 * a0: last address before we jumped to the unrecoverable_exception.
192 * excsave_1: a0
193 *
194 *
195 * See the handle_alloca_user and spill_registers routines for example clients.
196 *
197 * FIXME: Note: we currently don't allow signal handling coming from a double
198 * exception, so the item markt with (*) is not required.
199 */
200
201 .section .DoubleExceptionVector.text, "ax"
202 .begin literal_prefix .DoubleExceptionVector
203
204ENTRY(_DoubleExceptionVector)
205
206 /* Deliberately destroy excsave (don't assume it's value was valid). */
207
208 wsr a3, EXCSAVE_1 # save a3
209
210 /* Check for kernel double exception (usually fatal). */
211
212 rsr a3, PS
213 _bbci.l a3, PS_UM_SHIFT, .Lksp
214
215 /* Check if we are currently handling a window exception. */
216 /* Note: We don't need to indicate that we enter a critical section. */
217
218 xsr a0, DEPC # get DEPC, save a0
219
220 movi a3, XCHAL_WINDOW_VECTORS_VADDR
221 _bltu a0, a3, .Lfixup
222 addi a3, a3, XSHAL_WINDOW_VECTORS_SIZE
223 _bgeu a0, a3, .Lfixup
224
225 /* Window overflow/underflow exception. Get stack pointer. */
226
227 mov a3, a2
228 movi a2, exc_table
229 l32i a2, a2, EXC_TABLE_KSTK
230
231 /* Check for overflow/underflow exception, jump if overflow. */
232
233 _bbci.l a0, 6, .Lovfl
234
235 /* a0: depc, a1: a1, a2: kstk, a3: a2, depc: a0, excsave: a3 */
236
237 /* Restart window underflow exception.
238 * We return to the instruction in user space that caused the window
239 * underflow exception. Therefore, we change window base to the value
240 * before we entered the window underflow exception and prepare the
241 * registers to return as if we were coming from a regular exception
242 * by changing depc (in a0).
243 * Note: We can trash the current window frame (a0...a3) and depc!
244 */
245
246 wsr a2, DEPC # save stack pointer temporarily
247 rsr a0, PS
248 extui a0, a0, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS
249 wsr a0, WINDOWBASE
250 rsync
251
252 /* We are now in the previous window frame. Save registers again. */
253
254 xsr a2, DEPC # save a2 and get stack pointer
255 s32i a0, a2, PT_AREG0
256
257 wsr a3, EXCSAVE_1 # save a3
258 movi a3, exc_table
259
260 rsr a0, EXCCAUSE
261 s32i a0, a2, PT_DEPC # mark it as a regular exception
262 addx4 a0, a0, a3
263 l32i a0, a0, EXC_TABLE_FAST_USER
264 jx a0
265
266.Lfixup:/* Check for a fixup handler or if we were in a critical section. */
267
268 /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */
269
270 movi a3, exc_table
271 s32i a2, a3, EXC_TABLE_DOUBLE_SAVE # temporary variable
272
273 /* Enter critical section. */
274
275 l32i a2, a3, EXC_TABLE_FIXUP
276 s32i a3, a3, EXC_TABLE_FIXUP
277 beq a2, a3, .Lunrecoverable_fixup # critical!
278 beqz a2, .Ldflt # no handler was registered
279
280 /* a0: depc, a1: a1, a2: trash, a3: exctable, depc: a0, excsave: a3 */
281
282 jx a2
283
284.Ldflt: /* Get stack pointer. */
285
286 l32i a3, a3, EXC_TABLE_DOUBLE_SAVE
287 addi a2, a3, -PT_USER_SIZE
288
289.Lovfl: /* Jump to default handlers. */
290
291 /* a0: depc, a1: a1, a2: kstk, a3: a2, depc: a0, excsave: a3 */
292
293 xsr a3, DEPC
294 s32i a0, a2, PT_DEPC
295 s32i a3, a2, PT_AREG0
296
297 /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */
298
299 movi a3, exc_table
300 rsr a0, EXCCAUSE
301 addx4 a0, a0, a3
302 l32i a0, a0, EXC_TABLE_FAST_USER
303 jx a0
304
305 /*
306 * We only allow the ITLB miss exception if we are in kernel space.
307 * All other exceptions are unexpected and thus unrecoverable!
308 */
309
310 .extern fast_second_level_miss_double_kernel
311
312.Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
313
314 rsr a3, EXCCAUSE
315 beqi a3, XCHAL_EXCCAUSE_ITLB_MISS, 1f
316 addi a3, a3, -XCHAL_EXCCAUSE_DTLB_MISS
317 bnez a3, .Lunrecoverable
3181: movi a3, fast_second_level_miss_double_kernel
319 jx a3
320
321 /* Critical! We can't handle this situation. PANIC! */
322
323 .extern unrecoverable_exception
324
325.Lunrecoverable_fixup:
326 l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
327 xsr a0, DEPC
328
329.Lunrecoverable:
330 rsr a3, EXCSAVE_1
331 wsr a0, EXCSAVE_1
332 movi a0, unrecoverable_exception
333 callx0 a0
334
335 .end literal_prefix
336
337
338/*
339 * Debug interrupt vector
340 *
341 * There is not much space here, so simply jump to another handler.
342 * EXCSAVE[DEBUGLEVEL] has been set to that handler.
343 */
344
345 .section .DebugInterruptVector.text, "ax"
346
347ENTRY(_DebugInterruptVector)
348 xsr a0, EXCSAVE + XCHAL_DEBUGLEVEL
349 jx a0
350
351
352
353/* Window overflow and underflow handlers.
354 * The handlers must be 64 bytes apart, first starting with the underflow
355 * handlers underflow-4 to underflow-12, then the overflow handlers
356 * overflow-4 to overflow-12.
357 *
358 * Note: We rerun the underflow handlers if we hit an exception, so
359 * we try to access any page that would cause a page fault early.
360 */
361
362 .section .WindowVectors.text, "ax"
363
364
365/* 4-Register Window Overflow Vector (Handler) */
366
367 .align 64
368.global _WindowOverflow4
369_WindowOverflow4:
370 s32e a0, a5, -16
371 s32e a1, a5, -12
372 s32e a2, a5, -8
373 s32e a3, a5, -4
374 rfwo
375
376
377/* 4-Register Window Underflow Vector (Handler) */
378
379 .align 64
380.global _WindowUnderflow4
381_WindowUnderflow4:
382 l32e a0, a5, -16
383 l32e a1, a5, -12
384 l32e a2, a5, -8
385 l32e a3, a5, -4
386 rfwu
387
388
389/* 8-Register Window Overflow Vector (Handler) */
390
391 .align 64
392.global _WindowOverflow8
393_WindowOverflow8:
394 s32e a0, a9, -16
395 l32e a0, a1, -12
396 s32e a2, a9, -8
397 s32e a1, a9, -12
398 s32e a3, a9, -4
399 s32e a4, a0, -32
400 s32e a5, a0, -28
401 s32e a6, a0, -24
402 s32e a7, a0, -20
403 rfwo
404
405/* 8-Register Window Underflow Vector (Handler) */
406
407 .align 64
408.global _WindowUnderflow8
409_WindowUnderflow8:
410 l32e a1, a9, -12
411 l32e a0, a9, -16
412 l32e a7, a1, -12
413 l32e a2, a9, -8
414 l32e a4, a7, -32
415 l32e a3, a9, -4
416 l32e a5, a7, -28
417 l32e a6, a7, -24
418 l32e a7, a7, -20
419 rfwu
420
421
422/* 12-Register Window Overflow Vector (Handler) */
423
424 .align 64
425.global _WindowOverflow12
426_WindowOverflow12:
427 s32e a0, a13, -16
428 l32e a0, a1, -12
429 s32e a1, a13, -12
430 s32e a2, a13, -8
431 s32e a3, a13, -4
432 s32e a4, a0, -48
433 s32e a5, a0, -44
434 s32e a6, a0, -40
435 s32e a7, a0, -36
436 s32e a8, a0, -32
437 s32e a9, a0, -28
438 s32e a10, a0, -24
439 s32e a11, a0, -20
440 rfwo
441
442/* 12-Register Window Underflow Vector (Handler) */
443
444 .align 64
445.global _WindowUnderflow12
446_WindowUnderflow12:
447 l32e a1, a13, -12
448 l32e a0, a13, -16
449 l32e a11, a1, -12
450 l32e a2, a13, -8
451 l32e a4, a11, -48
452 l32e a8, a11, -32
453 l32e a3, a13, -4
454 l32e a5, a11, -44
455 l32e a6, a11, -40
456 l32e a7, a11, -36
457 l32e a9, a11, -28
458 l32e a10, a11, -24
459 l32e a11, a11, -20
460 rfwu
461
462 .text
463
464
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..476b2b53cd01
--- /dev/null
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -0,0 +1,341 @@
1/*
2 * arch/xtensa/kernel/vmlinux.lds.S
3 *
4 * Xtensa linker script
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
15 */
16
17#include <asm-generic/vmlinux.lds.h>
18
19#include <linux/config.h>
20#define _NOCLANGUAGE
21#include <xtensa/config/core.h>
22#include <xtensa/config/system.h>
23OUTPUT_ARCH(xtensa)
24ENTRY(_start)
25
26#if XCHAL_MEMORY_ORDER == XTHAL_BIGENDIAN
27jiffies = jiffies_64 + 4;
28#else
29jiffies = jiffies_64;
30#endif
31
32#define KERNELOFFSET 0x1000
33
34/* Note: In the following macros, it would be nice to specify only the
35 vector name and section kind and construct "sym" and "section" using
36 CPP concatenation, but that does not work reliably. Concatenating a
37 string with "." produces an invalid token. CPP will not print a
38 warning because it thinks this is an assembly file, but it leaves
39 them as multiple tokens and there may or may not be whitespace
40 between them. */
41
42/* Macro for a relocation entry */
43
44#define RELOCATE_ENTRY(sym, section) \
45 LONG(sym ## _start); \
46 LONG(sym ## _end); \
47 LONG(LOADADDR(section))
48
49/* Macro to define a section for a vector.
50 *
51 * Use of the MIN function catches the types of errors illustrated in
52 * the following example:
53 *
54 * Assume the section .DoubleExceptionVector.literal is completely
55 * full. Then a programmer adds code to .DoubleExceptionVector.text
56 * that produces another literal. The final literal position will
57 * overlay onto the first word of the adjacent code section
58 * .DoubleExceptionVector.text. (In practice, the literals will
59 * overwrite the code, and the first few instructions will be
60 * garbage.)
61 */
62
63#define SECTION_VECTOR(sym, section, addr, max_prevsec_size, prevsec) \
64 section addr : AT((MIN(LOADADDR(prevsec) + max_prevsec_size, \
65 LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3) \
66 { \
67 . = ALIGN(4); \
68 sym ## _start = ABSOLUTE(.); \
69 *(section) \
70 sym ## _end = ABSOLUTE(.); \
71 }
72
73/*
74 * Mapping of input sections to output sections when linking.
75 */
76
77SECTIONS
78{
79 . = XCHAL_KSEG_CACHED_VADDR + KERNELOFFSET;
80 /* .text section */
81
82 _text = .;
83 _stext = .;
84 _ftext = .;
85
86 .text :
87 {
88 /* The .head.text section must be the first section! */
89 *(.head.text)
90 *(.literal .text)
91 *(.srom.text)
92 VMLINUX_SYMBOL(__sched_text_start) = .;
93 *(.sched.text.literal .sched.text)
94 VMLINUX_SYMBOL(__sched_text_end) = .;
95 VMLINUX_SYMBOL(__lock_text_start) = .;
96 *(.spinlock.text.literal .spinlock.text)
97 VMLINUX_SYMBOL(__lock_text_end) = .;
98
99 }
100 _etext = .;
101
102 . = ALIGN(16);
103
104 RODATA
105
106 /* Relocation table */
107
108 . = ALIGN(16);
109 __boot_reloc_table_start = ABSOLUTE(.);
110
111 __relocate : {
112
113 RELOCATE_ENTRY(_WindowVectors_text,
114 .WindowVectors.text);
115#if 0
116 RELOCATE_ENTRY(_KernelExceptionVector_literal,
117 .KernelExceptionVector.literal);
118#endif
119 RELOCATE_ENTRY(_KernelExceptionVector_text,
120 .KernelExceptionVector.text);
121#if 0
122 RELOCATE_ENTRY(_UserExceptionVector_literal,
123 .UserExceptionVector.literal);
124#endif
125 RELOCATE_ENTRY(_UserExceptionVector_text,
126 .UserExceptionVector.text);
127 RELOCATE_ENTRY(_DoubleExceptionVector_literal,
128 .DoubleExceptionVector.literal);
129 RELOCATE_ENTRY(_DoubleExceptionVector_text,
130 .DoubleExceptionVector.text);
131 }
132 __boot_reloc_table_end = ABSOLUTE(.) ;
133
134 .fixup : { *(.fixup) }
135
136 . = ALIGN(16);
137
138 __ex_table : {
139 __start___ex_table = .;
140 *(__ex_table)
141 __stop___ex_table = .;
142 }
143
144 /* Data section */
145
146 . = ALIGN(XCHAL_ICACHE_LINESIZE);
147 _fdata = .;
148 .data :
149 {
150 *(.data) CONSTRUCTORS
151 . = ALIGN(XCHAL_ICACHE_LINESIZE);
152 *(.data.cacheline_aligned)
153 }
154
155 _edata = .;
156
157 /* The initial task */
158 . = ALIGN(8192);
159 .data.init_task : { *(.data.init_task) }
160
161 /* Initialization code and data: */
162
163 . = ALIGN(1<<XCHAL_MMU_MIN_PTE_PAGE_SIZE);
164 __init_begin = .;
165 .init.text : {
166 _sinittext = .;
167 *(.init.text.literal) *(.init.text)
168 _einittext = .;
169 }
170
171 .init.data :
172 {
173 *(.init.data)
174 . = ALIGN(0x4);
175 __tagtable_begin = .;
176 *(.taglist)
177 __tagtable_end = .;
178 }
179
180 . = ALIGN(XCHAL_ICACHE_LINESIZE);
181
182 __setup_start = .;
183 .init.setup : { *(.init.setup) }
184 __setup_end = .;
185
186 __initcall_start = .;
187 .initcall.init : {
188 *(.initcall1.init)
189 *(.initcall2.init)
190 *(.initcall3.init)
191 *(.initcall4.init)
192 *(.initcall5.init)
193 *(.initcall6.init)
194 *(.initcall7.init)
195 }
196 __initcall_end = .;
197
198 __con_initcall_start = .;
199 .con_initcall.init : { *(.con_initcall.init) }
200 __con_initcall_end = .;
201
202 SECURITY_INIT
203
204 . = ALIGN(4);
205
206 __start___ftr_fixup = .;
207 __ftr_fixup : { *(__ftr_fixup) }
208 __stop___ftr_fixup = .;
209
210 . = ALIGN(32);
211 __per_cpu_start = .;
212 .data.percpu : { *(.data.percpu) }
213 __per_cpu_end = .;
214
215 . = ALIGN(4096);
216 __initramfs_start =.;
217 .init.ramfs : { *(.init.ramfs) }
218 __initramfs_end = .;
219
220 /* We need this dummy segment here */
221
222 . = ALIGN(4);
223 .dummy : { LONG(0) }
224
225 /* The vectors are relocated to the real position at startup time */
226
227 SECTION_VECTOR (_WindowVectors_text,
228 .WindowVectors.text,
229 XCHAL_WINDOW_VECTORS_VADDR, 4,
230 .dummy)
231 SECTION_VECTOR (_DebugInterruptVector_literal,
232 .DebugInterruptVector.literal,
233 XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL) - 4,
234 SIZEOF(.WindowVectors.text),
235 .WindowVectors.text)
236 SECTION_VECTOR (_DebugInterruptVector_text,
237 .DebugInterruptVector.text,
238 XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL),
239 4,
240 .DebugInterruptVector.literal)
241 SECTION_VECTOR (_KernelExceptionVector_literal,
242 .KernelExceptionVector.literal,
243 XCHAL_KERNELEXC_VECTOR_VADDR - 4,
244 SIZEOF(.DebugInterruptVector.text),
245 .DebugInterruptVector.text)
246 SECTION_VECTOR (_KernelExceptionVector_text,
247 .KernelExceptionVector.text,
248 XCHAL_KERNELEXC_VECTOR_VADDR,
249 4,
250 .KernelExceptionVector.literal)
251 SECTION_VECTOR (_UserExceptionVector_literal,
252 .UserExceptionVector.literal,
253 XCHAL_USEREXC_VECTOR_VADDR - 4,
254 SIZEOF(.KernelExceptionVector.text),
255 .KernelExceptionVector.text)
256 SECTION_VECTOR (_UserExceptionVector_text,
257 .UserExceptionVector.text,
258 XCHAL_USEREXC_VECTOR_VADDR,
259 4,
260 .UserExceptionVector.literal)
261 SECTION_VECTOR (_DoubleExceptionVector_literal,
262 .DoubleExceptionVector.literal,
263 XCHAL_DOUBLEEXC_VECTOR_VADDR - 16,
264 SIZEOF(.UserExceptionVector.text),
265 .UserExceptionVector.text)
266 SECTION_VECTOR (_DoubleExceptionVector_text,
267 .DoubleExceptionVector.text,
268 XCHAL_DOUBLEEXC_VECTOR_VADDR,
269 32,
270 .DoubleExceptionVector.literal)
271
272 . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
273 . = ALIGN(1<<XCHAL_MMU_MIN_PTE_PAGE_SIZE);
274
275 __init_end = .;
276
277 . = ALIGN(8192);
278
279 /* BSS section */
280 _bss_start = .;
281 .sbss : { *(.sbss) *(.scommon) }
282 .bss : { *(COMMON) *(.bss) }
283 _bss_end = .;
284 _end = .;
285
286 /* only used by the boot loader */
287
288 . = ALIGN(0x10);
289 .bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) }
290
291 . = ALIGN(0x1000);
292 __initrd_start = .;
293 .initrd : { *(.initrd) }
294 __initrd_end = .;
295
296 .ResetVector.text XCHAL_RESET_VECTOR_VADDR :
297 {
298 *(.ResetVector.text)
299 }
300
301
302 /* Sections to be discarded */
303 /DISCARD/ :
304 {
305 *(.text.exit)
306 *(.text.exit.literal)
307 *(.data.exit)
308 *(.exitcall.exit)
309 }
310
311
312 .debug 0 : { *(.debug) }
313 .line 0 : { *(.line) }
314 .debug_srcinfo 0 : { *(.debug_srcinfo) }
315 .debug_sfnames 0 : { *(.debug_sfnames) }
316 .debug_aranges 0 : { *(.debug_aranges) }
317 .debug_pubnames 0 : { *(.debug_pubnames) }
318 .debug_info 0 : { *(.debug_info) }
319 .debug_abbrev 0 : { *(.debug_abbrev) }
320 .debug_line 0 : { *(.debug_line) }
321 .debug_frame 0 : { *(.debug_frame) }
322 .debug_str 0 : { *(.debug_str) }
323 .debug_loc 0 : { *(.debug_loc) }
324 .debug_macinfo 0 : { *(.debug_macinfo) }
325 .debug_weaknames 0 : { *(.debug_weaknames) }
326 .debug_funcnames 0 : { *(.debug_funcnames) }
327 .debug_typenames 0 : { *(.debug_typenames) }
328 .debug_varnames 0 : { *(.debug_varnames) }
329
330 .xt.insn 0 :
331 {
332 *(.xt.insn)
333 *(.gnu.linkonce.x*)
334 }
335
336 .xt.lit 0 :
337 {
338 *(.xt.lit)
339 *(.gnu.linkonce.p*)
340 }
341}
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
new file mode 100644
index 000000000000..efae56a51475
--- /dev/null
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -0,0 +1,123 @@
1/*
2 * arch/xtensa/kernel/xtensa_ksyms.c
3 *
4 * Export Xtensa-specific functions for loadable modules.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * Joe Taylor <joe@tensilica.com>
13 */
14
15#include <linux/config.h>
16#include <linux/module.h>
17#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/interrupt.h>
20#include <asm/irq.h>
21#include <linux/in6.h>
22#include <linux/pci.h>
23#include <linux/ide.h>
24
25#include <asm/uaccess.h>
26#include <asm/checksum.h>
27#include <asm/dma.h>
28#include <asm/io.h>
29#include <asm/page.h>
30#include <asm/pgalloc.h>
31#include <asm/semaphore.h>
32#ifdef CONFIG_BLK_DEV_FD
33#include <asm/floppy.h>
34#endif
35#ifdef CONFIG_NET
36#include <net/checksum.h>
37#endif /* CONFIG_NET */
38
39
40/*
41 * String functions
42 */
43EXPORT_SYMBOL(memcmp);
44EXPORT_SYMBOL(memset);
45EXPORT_SYMBOL(memcpy);
46EXPORT_SYMBOL(memmove);
47EXPORT_SYMBOL(memchr);
48EXPORT_SYMBOL(strcat);
49EXPORT_SYMBOL(strchr);
50EXPORT_SYMBOL(strlen);
51EXPORT_SYMBOL(strpbrk);
52EXPORT_SYMBOL(strncat);
53EXPORT_SYMBOL(strnlen);
54EXPORT_SYMBOL(strrchr);
55EXPORT_SYMBOL(strstr);
56
57EXPORT_SYMBOL(enable_irq);
58EXPORT_SYMBOL(disable_irq);
59EXPORT_SYMBOL(kernel_thread);
60
61/*
62 * gcc internal math functions
63 */
64extern long long __ashrdi3(long long, int);
65extern long long __ashldi3(long long, int);
66extern long long __lshrdi3(long long, int);
67extern int __divsi3(int, int);
68extern int __modsi3(int, int);
69extern long long __muldi3(long long, long long);
70extern int __mulsi3(int, int);
71extern unsigned int __udivsi3(unsigned int, unsigned int);
72extern unsigned int __umodsi3(unsigned int, unsigned int);
73extern unsigned long long __umoddi3(unsigned long long, unsigned long long);
74extern unsigned long long __udivdi3(unsigned long long, unsigned long long);
75
76EXPORT_SYMBOL(__ashldi3);
77EXPORT_SYMBOL(__ashrdi3);
78EXPORT_SYMBOL(__lshrdi3);
79EXPORT_SYMBOL(__divsi3);
80EXPORT_SYMBOL(__modsi3);
81EXPORT_SYMBOL(__muldi3);
82EXPORT_SYMBOL(__mulsi3);
83EXPORT_SYMBOL(__udivsi3);
84EXPORT_SYMBOL(__umodsi3);
85EXPORT_SYMBOL(__udivdi3);
86EXPORT_SYMBOL(__umoddi3);
87
88/*
89 * Semaphore operations
90 */
91EXPORT_SYMBOL(__down);
92EXPORT_SYMBOL(__down_interruptible);
93EXPORT_SYMBOL(__down_trylock);
94EXPORT_SYMBOL(__up);
95
96#ifdef CONFIG_NET
97/*
98 * Networking support
99 */
100EXPORT_SYMBOL(csum_partial_copy_generic);
101#endif /* CONFIG_NET */
102
103/*
104 * Architecture-specific symbols
105 */
106EXPORT_SYMBOL(__xtensa_copy_user);
107
108/*
109 * Kernel hacking ...
110 */
111
112#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
113// FIXME EXPORT_SYMBOL(screen_info);
114#endif
115
116EXPORT_SYMBOL(get_wchan);
117
118EXPORT_SYMBOL(outsb);
119EXPORT_SYMBOL(outsw);
120EXPORT_SYMBOL(outsl);
121EXPORT_SYMBOL(insb);
122EXPORT_SYMBOL(insw);
123EXPORT_SYMBOL(insl);
diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile
new file mode 100644
index 000000000000..ed935b58e8a4
--- /dev/null
+++ b/arch/xtensa/lib/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for Xtensa-specific library files.
3#
4
5lib-y += memcopy.o memset.o checksum.o strcasecmp.o \
6 usercopy.o strncpy_user.o strnlen_user.o
7lib-$(CONFIG_PCI) += pci-auto.o
diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S
new file mode 100644
index 000000000000..e2d64dfd530c
--- /dev/null
+++ b/arch/xtensa/lib/checksum.S
@@ -0,0 +1,410 @@
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * IP/TCP/UDP checksumming routines
7 *
8 * Xtensa version: Copyright (C) 2001 Tensilica, Inc. by Kevin Chea
9 * Optimized by Joe Taylor
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#include <asm/errno.h>
18#include <linux/linkage.h>
19#define _ASMLANGUAGE
20#include <xtensa/config/core.h>
21
22/*
23 * computes a partial checksum, e.g. for TCP/UDP fragments
24 */
25
26/*
27 * unsigned int csum_partial(const unsigned char *buf, int len,
28 * unsigned int sum);
29 * a2 = buf
30 * a3 = len
31 * a4 = sum
32 *
33 * This function assumes 2- or 4-byte alignment. Other alignments will fail!
34 */
35
36/* ONES_ADD converts twos-complement math to ones-complement. */
37#define ONES_ADD(sum, val) \
38 add sum, sum, val ; \
39 bgeu sum, val, 99f ; \
40 addi sum, sum, 1 ; \
4199: ;
42
43.text
44ENTRY(csum_partial)
45 /*
46 * Experiments with Ethernet and SLIP connections show that buf
47 * is aligned on either a 2-byte or 4-byte boundary.
48 */
49 entry sp, 32
50 extui a5, a2, 0, 2
51 bnez a5, 8f /* branch if 2-byte aligned */
52 /* Fall-through on common case, 4-byte alignment */
531:
54 srli a5, a3, 5 /* 32-byte chunks */
55#if XCHAL_HAVE_LOOPS
56 loopgtz a5, 2f
57#else
58 beqz a5, 2f
59 slli a5, a5, 5
60 add a5, a5, a2 /* a5 = end of last 32-byte chunk */
61.Loop1:
62#endif
63 l32i a6, a2, 0
64 l32i a7, a2, 4
65 ONES_ADD(a4, a6)
66 ONES_ADD(a4, a7)
67 l32i a6, a2, 8
68 l32i a7, a2, 12
69 ONES_ADD(a4, a6)
70 ONES_ADD(a4, a7)
71 l32i a6, a2, 16
72 l32i a7, a2, 20
73 ONES_ADD(a4, a6)
74 ONES_ADD(a4, a7)
75 l32i a6, a2, 24
76 l32i a7, a2, 28
77 ONES_ADD(a4, a6)
78 ONES_ADD(a4, a7)
79 addi a2, a2, 4*8
80#if !XCHAL_HAVE_LOOPS
81 blt a2, a5, .Loop1
82#endif
832:
84 extui a5, a3, 2, 3 /* remaining 4-byte chunks */
85#if XCHAL_HAVE_LOOPS
86 loopgtz a5, 3f
87#else
88 beqz a5, 3f
89 slli a5, a5, 2
90 add a5, a5, a2 /* a5 = end of last 4-byte chunk */
91.Loop2:
92#endif
93 l32i a6, a2, 0
94 ONES_ADD(a4, a6)
95 addi a2, a2, 4
96#if !XCHAL_HAVE_LOOPS
97 blt a2, a5, .Loop2
98#endif
993:
100 _bbci.l a3, 1, 5f /* remaining 2-byte chunk */
101 l16ui a6, a2, 0
102 ONES_ADD(a4, a6)
103 addi a2, a2, 2
1045:
105 _bbci.l a3, 0, 7f /* remaining 1-byte chunk */
1066: l8ui a6, a2, 0
107#ifdef __XTENSA_EB__
108 slli a6, a6, 8 /* load byte into bits 8..15 */
109#endif
110 ONES_ADD(a4, a6)
1117:
112 mov a2, a4
113 retw
114
115 /* uncommon case, buf is 2-byte aligned */
1168:
117 beqz a3, 7b /* branch if len == 0 */
118 beqi a3, 1, 6b /* branch if len == 1 */
119
120 extui a5, a2, 0, 1
121 bnez a5, 8f /* branch if 1-byte aligned */
122
123 l16ui a6, a2, 0 /* common case, len >= 2 */
124 ONES_ADD(a4, a6)
125 addi a2, a2, 2 /* adjust buf */
126 addi a3, a3, -2 /* adjust len */
127 j 1b /* now buf is 4-byte aligned */
128
129 /* case: odd-byte aligned, len > 1
130 * This case is dog slow, so don't give us an odd address.
131 * (I don't think this ever happens, but just in case.)
132 */
1338:
134 srli a5, a3, 2 /* 4-byte chunks */
135#if XCHAL_HAVE_LOOPS
136 loopgtz a5, 2f
137#else
138 beqz a5, 2f
139 slli a5, a5, 2
140 add a5, a5, a2 /* a5 = end of last 4-byte chunk */
141.Loop3:
142#endif
143 l8ui a6, a2, 0 /* bits 24..31 */
144 l16ui a7, a2, 1 /* bits 8..23 */
145 l8ui a8, a2, 3 /* bits 0.. 8 */
146#ifdef __XTENSA_EB__
147 slli a6, a6, 24
148#else
149 slli a8, a8, 24
150#endif
151 slli a7, a7, 8
152 or a7, a7, a6
153 or a7, a7, a8
154 ONES_ADD(a4, a7)
155 addi a2, a2, 4
156#if !XCHAL_HAVE_LOOPS
157 blt a2, a5, .Loop3
158#endif
1592:
160 _bbci.l a3, 1, 3f /* remaining 2-byte chunk, still odd addr */
161 l8ui a6, a2, 0
162 l8ui a7, a2, 1
163#ifdef __XTENSA_EB__
164 slli a6, a6, 8
165#else
166 slli a7, a7, 8
167#endif
168 or a7, a7, a6
169 ONES_ADD(a4, a7)
170 addi a2, a2, 2
1713:
172 j 5b /* branch to handle the remaining byte */
173
174
175
176/*
177 * Copy from ds while checksumming, otherwise like csum_partial
178 *
179 * The macros SRC and DST specify the type of access for the instruction.
180 * thus we can call a custom exception handler for each access type.
181 */
182
183#define SRC(y...) \
184 9999: y; \
185 .section __ex_table, "a"; \
186 .long 9999b, 6001f ; \
187 .previous
188
189#define DST(y...) \
190 9999: y; \
191 .section __ex_table, "a"; \
192 .long 9999b, 6002f ; \
193 .previous
194
195/*
196unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
197 int sum, int *src_err_ptr, int *dst_err_ptr)
198 a2 = src
199 a3 = dst
200 a4 = len
201 a5 = sum
202 a6 = src_err_ptr
203 a7 = dst_err_ptr
204 a8 = temp
205 a9 = temp
206 a10 = temp
207 a11 = original len for exception handling
208 a12 = original dst for exception handling
209
210 This function is optimized for 4-byte aligned addresses. Other
211 alignments work, but not nearly as efficiently.
212 */
213
214ENTRY(csum_partial_copy_generic)
215 entry sp, 32
216 mov a12, a3
217 mov a11, a4
218 or a10, a2, a3
219
220 /* We optimize the following alignment tests for the 4-byte
221 aligned case. Two bbsi.l instructions might seem more optimal
222 (commented out below). However, both labels 5: and 3: are out
223 of the imm8 range, so the assembler relaxes them into
224 equivalent bbci.l, j combinations, which is actually
225 slower. */
226
227 extui a9, a10, 0, 2
228 beqz a9, 1f /* branch if both are 4-byte aligned */
229 bbsi.l a10, 0, 5f /* branch if one address is odd */
230 j 3f /* one address is 2-byte aligned */
231
232/* _bbsi.l a10, 0, 5f */ /* branch if odd address */
233/* _bbsi.l a10, 1, 3f */ /* branch if 2-byte-aligned address */
234
2351:
236 /* src and dst are both 4-byte aligned */
237 srli a10, a4, 5 /* 32-byte chunks */
238#if XCHAL_HAVE_LOOPS
239 loopgtz a10, 2f
240#else
241 beqz a10, 2f
242 slli a10, a10, 5
243 add a10, a10, a2 /* a10 = end of last 32-byte src chunk */
244.Loop5:
245#endif
246SRC( l32i a9, a2, 0 )
247SRC( l32i a8, a2, 4 )
248DST( s32i a9, a3, 0 )
249DST( s32i a8, a3, 4 )
250 ONES_ADD(a5, a9)
251 ONES_ADD(a5, a8)
252SRC( l32i a9, a2, 8 )
253SRC( l32i a8, a2, 12 )
254DST( s32i a9, a3, 8 )
255DST( s32i a8, a3, 12 )
256 ONES_ADD(a5, a9)
257 ONES_ADD(a5, a8)
258SRC( l32i a9, a2, 16 )
259SRC( l32i a8, a2, 20 )
260DST( s32i a9, a3, 16 )
261DST( s32i a8, a3, 20 )
262 ONES_ADD(a5, a9)
263 ONES_ADD(a5, a8)
264SRC( l32i a9, a2, 24 )
265SRC( l32i a8, a2, 28 )
266DST( s32i a9, a3, 24 )
267DST( s32i a8, a3, 28 )
268 ONES_ADD(a5, a9)
269 ONES_ADD(a5, a8)
270 addi a2, a2, 32
271 addi a3, a3, 32
272#if !XCHAL_HAVE_LOOPS
273 blt a2, a10, .Loop5
274#endif
2752:
276 extui a10, a4, 2, 3 /* remaining 4-byte chunks */
277 extui a4, a4, 0, 2 /* reset len for general-case, 2-byte chunks */
278#if XCHAL_HAVE_LOOPS
279 loopgtz a10, 3f
280#else
281 beqz a10, 3f
282 slli a10, a10, 2
283 add a10, a10, a2 /* a10 = end of last 4-byte src chunk */
284.Loop6:
285#endif
286SRC( l32i a9, a2, 0 )
287DST( s32i a9, a3, 0 )
288 ONES_ADD(a5, a9)
289 addi a2, a2, 4
290 addi a3, a3, 4
291#if !XCHAL_HAVE_LOOPS
292 blt a2, a10, .Loop6
293#endif
2943:
295 /*
296 Control comes to here in two cases: (1) It may fall through
297 to here from the 4-byte alignment case to process, at most,
298 one 2-byte chunk. (2) It branches to here from above if
299 either src or dst is 2-byte aligned, and we process all bytes
300 here, except for perhaps a trailing odd byte. It's
301 inefficient, so align your addresses to 4-byte boundaries.
302
303 a2 = src
304 a3 = dst
305 a4 = len
306 a5 = sum
307 */
308 srli a10, a4, 1 /* 2-byte chunks */
309#if XCHAL_HAVE_LOOPS
310 loopgtz a10, 4f
311#else
312 beqz a10, 4f
313 slli a10, a10, 1
314 add a10, a10, a2 /* a10 = end of last 2-byte src chunk */
315.Loop7:
316#endif
317SRC( l16ui a9, a2, 0 )
318DST( s16i a9, a3, 0 )
319 ONES_ADD(a5, a9)
320 addi a2, a2, 2
321 addi a3, a3, 2
322#if !XCHAL_HAVE_LOOPS
323 blt a2, a10, .Loop7
324#endif
3254:
326 /* This section processes a possible trailing odd byte. */
327 _bbci.l a4, 0, 8f /* 1-byte chunk */
328SRC( l8ui a9, a2, 0 )
329DST( s8i a9, a3, 0 )
330#ifdef __XTENSA_EB__
331 slli a9, a9, 8 /* shift byte to bits 8..15 */
332#endif
333 ONES_ADD(a5, a9)
3348:
335 mov a2, a5
336 retw
337
3385:
339 /* Control branch to here when either src or dst is odd. We
340 process all bytes using 8-bit accesses. Grossly inefficient,
341 so don't feed us an odd address. */
342
343 srli a10, a4, 1 /* handle in pairs for 16-bit csum */
344#if XCHAL_HAVE_LOOPS
345 loopgtz a10, 6f
346#else
347 beqz a10, 6f
348 slli a10, a10, 1
349 add a10, a10, a2 /* a10 = end of last odd-aligned, 2-byte src chunk */
350.Loop8:
351#endif
352SRC( l8ui a9, a2, 0 )
353SRC( l8ui a8, a2, 1 )
354DST( s8i a9, a3, 0 )
355DST( s8i a8, a3, 1 )
356#ifdef __XTENSA_EB__
357 slli a9, a9, 8 /* combine into a single 16-bit value */
358#else /* for checksum computation */
359 slli a8, a8, 8
360#endif
361 or a9, a9, a8
362 ONES_ADD(a5, a9)
363 addi a2, a2, 2
364 addi a3, a3, 2
365#if !XCHAL_HAVE_LOOPS
366 blt a2, a10, .Loop8
367#endif
3686:
369 j 4b /* process the possible trailing odd byte */
370
371
372# Exception handler:
373.section .fixup, "ax"
374/*
375 a6 = src_err_ptr
376 a7 = dst_err_ptr
377 a11 = original len for exception handling
378 a12 = original dst for exception handling
379*/
380
3816001:
382 _movi a2, -EFAULT
383 s32i a2, a6, 0 /* src_err_ptr */
384
385 # clear the complete destination - computing the rest
386 # is too much work
387 movi a2, 0
388#if XCHAL_HAVE_LOOPS
389 loopgtz a11, 2f
390#else
391 beqz a11, 2f
392 add a11, a11, a12 /* a11 = ending address */
393.Leloop:
394#endif
395 s8i a2, a12, 0
396 addi a12, a12, 1
397#if !XCHAL_HAVE_LOOPS
398 blt a12, a11, .Leloop
399#endif
4002:
401 retw
402
4036002:
404 movi a2, -EFAULT
405 s32i a2, a7, 0 /* dst_err_ptr */
406 movi a2, 0
407 retw
408
409.previous
410
diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S
new file mode 100644
index 000000000000..e8f6d7eb7222
--- /dev/null
+++ b/arch/xtensa/lib/memcopy.S
@@ -0,0 +1,315 @@
1/*
2 * arch/xtensa/lib/hal/memcopy.S -- Core HAL library functions
3 * xthal_memcpy and xthal_bcopy
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
7 * for more details.
8 *
9 * Copyright (C) 2002 - 2005 Tensilica Inc.
10 */
11
12#include <xtensa/coreasm.h>
13
14 .macro src_b r, w0, w1
15#ifdef __XTENSA_EB__
16 src \r, \w0, \w1
17#else
18 src \r, \w1, \w0
19#endif
20 .endm
21
22 .macro ssa8 r
23#ifdef __XTENSA_EB__
24 ssa8b \r
25#else
26 ssa8l \r
27#endif
28 .endm
29
30
31/*
32 * void *memcpy(void *dst, const void *src, size_t len);
33 * void *memmove(void *dst, const void *src, size_t len);
34 * void *bcopy(const void *src, void *dst, size_t len);
35 *
36 * This function is intended to do the same thing as the standard
37 * library function memcpy() (or bcopy()) for most cases.
38 * However, where the source and/or destination references
39 * an instruction RAM or ROM or a data RAM or ROM, that
40 * source and/or destination will always be accessed with
41 * 32-bit load and store instructions (as required for these
42 * types of devices).
43 *
44 * !!!!!!! XTFIXME:
45 * !!!!!!! Handling of IRAM/IROM has not yet
46 * !!!!!!! been implemented.
47 *
48 * The bcopy version is provided here to avoid the overhead
49 * of an extra call, for callers that require this convention.
50 *
51 * The (general case) algorithm is as follows:
52 * If destination is unaligned, align it by conditionally
53 * copying 1 and 2 bytes.
54 * If source is aligned,
55 * do 16 bytes with a loop, and then finish up with
56 * 8, 4, 2, and 1 byte copies conditional on the length;
57 * else (if source is unaligned),
58 * do the same, but use SRC to align the source data.
59 * This code tries to use fall-through branches for the common
60 * case of aligned source and destination and multiple
61 * of 4 (or 8) length.
62 *
63 * Register use:
64 * a0/ return address
65 * a1/ stack pointer
66 * a2/ return value
67 * a3/ src
68 * a4/ length
69 * a5/ dst
70 * a6/ tmp
71 * a7/ tmp
72 * a8/ tmp
73 * a9/ tmp
74 * a10/ tmp
75 * a11/ tmp
76 */
77
78 .text
79 .align 4
80 .global bcopy
81 .type bcopy,@function
82bcopy:
83 entry sp, 16 # minimal stack frame
84 # a2=src, a3=dst, a4=len
85 mov a5, a3 # copy dst so that a2 is return value
86 mov a3, a2
87 mov a2, a5
88 j .Lcommon # go to common code for memcpy+bcopy
89
90
91/*
92 * Byte by byte copy
93 */
94 .align 4
95 .byte 0 # 1 mod 4 alignment for LOOPNEZ
96 # (0 mod 4 alignment for LBEG)
97.Lbytecopy:
98#if XCHAL_HAVE_LOOPS
99 loopnez a4, .Lbytecopydone
100#else /* !XCHAL_HAVE_LOOPS */
101 beqz a4, .Lbytecopydone
102 add a7, a3, a4 # a7 = end address for source
103#endif /* !XCHAL_HAVE_LOOPS */
104.Lnextbyte:
105 l8ui a6, a3, 0
106 addi a3, a3, 1
107 s8i a6, a5, 0
108 addi a5, a5, 1
109#if !XCHAL_HAVE_LOOPS
110 blt a3, a7, .Lnextbyte
111#endif /* !XCHAL_HAVE_LOOPS */
112.Lbytecopydone:
113 retw
114
115/*
116 * Destination is unaligned
117 */
118
119 .align 4
120.Ldst1mod2: # dst is only byte aligned
121 _bltui a4, 7, .Lbytecopy # do short copies byte by byte
122
123 # copy 1 byte
124 l8ui a6, a3, 0
125 addi a3, a3, 1
126 addi a4, a4, -1
127 s8i a6, a5, 0
128 addi a5, a5, 1
129 _bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then
130 # return to main algorithm
131.Ldst2mod4: # dst 16-bit aligned
132 # copy 2 bytes
133 _bltui a4, 6, .Lbytecopy # do short copies byte by byte
134 l8ui a6, a3, 0
135 l8ui a7, a3, 1
136 addi a3, a3, 2
137 addi a4, a4, -2
138 s8i a6, a5, 0
139 s8i a7, a5, 1
140 addi a5, a5, 2
141 j .Ldstaligned # dst is now aligned, return to main algorithm
142
143 .align 4
144 .global memcpy
145 .type memcpy,@function
146memcpy:
147 .global memmove
148 .type memmove,@function
149memmove:
150
151 entry sp, 16 # minimal stack frame
152 # a2/ dst, a3/ src, a4/ len
153 mov a5, a2 # copy dst so that a2 is return value
154.Lcommon:
155 _bbsi.l a2, 0, .Ldst1mod2 # if dst is 1 mod 2
156 _bbsi.l a2, 1, .Ldst2mod4 # if dst is 2 mod 4
157.Ldstaligned: # return here from .Ldst?mod? once dst is aligned
158 srli a7, a4, 4 # number of loop iterations with 16B
159 # per iteration
160 movi a8, 3 # if source is not aligned,
161 _bany a3, a8, .Lsrcunaligned # then use shifting copy
162 /*
163 * Destination and source are word-aligned, use word copy.
164 */
165 # copy 16 bytes per iteration for word-aligned dst and word-aligned src
166#if XCHAL_HAVE_LOOPS
167 loopnez a7, .Loop1done
168#else /* !XCHAL_HAVE_LOOPS */
169 beqz a7, .Loop1done
170 slli a8, a7, 4
171 add a8, a8, a3 # a8 = end of last 16B source chunk
172#endif /* !XCHAL_HAVE_LOOPS */
173.Loop1:
174 l32i a6, a3, 0
175 l32i a7, a3, 4
176 s32i a6, a5, 0
177 l32i a6, a3, 8
178 s32i a7, a5, 4
179 l32i a7, a3, 12
180 s32i a6, a5, 8
181 addi a3, a3, 16
182 s32i a7, a5, 12
183 addi a5, a5, 16
184#if !XCHAL_HAVE_LOOPS
185 blt a3, a8, .Loop1
186#endif /* !XCHAL_HAVE_LOOPS */
187.Loop1done:
188 bbci.l a4, 3, .L2
189 # copy 8 bytes
190 l32i a6, a3, 0
191 l32i a7, a3, 4
192 addi a3, a3, 8
193 s32i a6, a5, 0
194 s32i a7, a5, 4
195 addi a5, a5, 8
196.L2:
197 bbsi.l a4, 2, .L3
198 bbsi.l a4, 1, .L4
199 bbsi.l a4, 0, .L5
200 retw
201.L3:
202 # copy 4 bytes
203 l32i a6, a3, 0
204 addi a3, a3, 4
205 s32i a6, a5, 0
206 addi a5, a5, 4
207 bbsi.l a4, 1, .L4
208 bbsi.l a4, 0, .L5
209 retw
210.L4:
211 # copy 2 bytes
212 l16ui a6, a3, 0
213 addi a3, a3, 2
214 s16i a6, a5, 0
215 addi a5, a5, 2
216 bbsi.l a4, 0, .L5
217 retw
218.L5:
219 # copy 1 byte
220 l8ui a6, a3, 0
221 s8i a6, a5, 0
222 retw
223
224/*
225 * Destination is aligned, Source is unaligned
226 */
227
228 .align 4
229.Lsrcunaligned:
230 _beqz a4, .Ldone # avoid loading anything for zero-length copies
231 # copy 16 bytes per iteration for word-aligned dst and unaligned src
232 ssa8 a3 # set shift amount from byte offset
233#define SIM_CHECKS_ALIGNMENT 1 /* set to 1 when running on ISS (simulator) with the
234 lint or ferret client, or 0 to save a few cycles */
235#if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT
236 and a11, a3, a8 # save unalignment offset for below
237 sub a3, a3, a11 # align a3
238#endif
239 l32i a6, a3, 0 # load first word
240#if XCHAL_HAVE_LOOPS
241 loopnez a7, .Loop2done
242#else /* !XCHAL_HAVE_LOOPS */
243 beqz a7, .Loop2done
244 slli a10, a7, 4
245 add a10, a10, a3 # a10 = end of last 16B source chunk
246#endif /* !XCHAL_HAVE_LOOPS */
247.Loop2:
248 l32i a7, a3, 4
249 l32i a8, a3, 8
250 src_b a6, a6, a7
251 s32i a6, a5, 0
252 l32i a9, a3, 12
253 src_b a7, a7, a8
254 s32i a7, a5, 4
255 l32i a6, a3, 16
256 src_b a8, a8, a9
257 s32i a8, a5, 8
258 addi a3, a3, 16
259 src_b a9, a9, a6
260 s32i a9, a5, 12
261 addi a5, a5, 16
262#if !XCHAL_HAVE_LOOPS
263 blt a3, a10, .Loop2
264#endif /* !XCHAL_HAVE_LOOPS */
265.Loop2done:
266 bbci.l a4, 3, .L12
267 # copy 8 bytes
268 l32i a7, a3, 4
269 l32i a8, a3, 8
270 src_b a6, a6, a7
271 s32i a6, a5, 0
272 addi a3, a3, 8
273 src_b a7, a7, a8
274 s32i a7, a5, 4
275 addi a5, a5, 8
276 mov a6, a8
277.L12:
278 bbci.l a4, 2, .L13
279 # copy 4 bytes
280 l32i a7, a3, 4
281 addi a3, a3, 4
282 src_b a6, a6, a7
283 s32i a6, a5, 0
284 addi a5, a5, 4
285 mov a6, a7
286.L13:
287#if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT
288 add a3, a3, a11 # readjust a3 with correct misalignment
289#endif
290 bbsi.l a4, 1, .L14
291 bbsi.l a4, 0, .L15
292.Ldone: retw
293.L14:
294 # copy 2 bytes
295 l8ui a6, a3, 0
296 l8ui a7, a3, 1
297 addi a3, a3, 2
298 s8i a6, a5, 0
299 s8i a7, a5, 1
300 addi a5, a5, 2
301 bbsi.l a4, 0, .L15
302 retw
303.L15:
304 # copy 1 byte
305 l8ui a6, a3, 0
306 s8i a6, a5, 0
307 retw
308
309/*
310 * Local Variables:
311 * mode:fundamental
312 * comment-start: "# "
313 * comment-start-skip: "# *"
314 * End:
315 */
diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S
new file mode 100644
index 000000000000..4de25134bc62
--- /dev/null
+++ b/arch/xtensa/lib/memset.S
@@ -0,0 +1,160 @@
1/*
2 * arch/xtensa/lib/memset.S
3 *
4 * ANSI C standard library function memset
5 * (Well, almost. .fixup code might return zero.)
6 *
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file "COPYING" in the main directory of
9 * this archive for more details.
10 *
11 * Copyright (C) 2002 Tensilica Inc.
12 */
13
14#include <xtensa/coreasm.h>
15
16/*
17 * void *memset(void *dst, int c, size_t length)
18 *
19 * The algorithm is as follows:
20 * Create a word with c in all byte positions
21 * If the destination is aligned,
22 * do 16B chucks with a loop, and then finish up with
23 * 8B, 4B, 2B, and 1B stores conditional on the length.
24 * If destination is unaligned, align it by conditionally
25 * setting 1B and 2B and then go to aligned case.
26 * This code tries to use fall-through branches for the common
27 * case of an aligned destination (except for the branches to
28 * the alignment labels).
29 */
30
31/* Load or store instructions that may cause exceptions use the EX macro. */
32
33#define EX(insn,reg1,reg2,offset,handler) \
349: insn reg1, reg2, offset; \
35 .section __ex_table, "a"; \
36 .word 9b, handler; \
37 .previous
38
39
40.text
41.align 4
42.global memset
43.type memset,@function
44memset:
45 entry sp, 16 # minimal stack frame
46 # a2/ dst, a3/ c, a4/ length
47 extui a3, a3, 0, 8 # mask to just 8 bits
48 slli a7, a3, 8 # duplicate character in all bytes of word
49 or a3, a3, a7 # ...
50 slli a7, a3, 16 # ...
51 or a3, a3, a7 # ...
52 mov a5, a2 # copy dst so that a2 is return value
53 movi a6, 3 # for alignment tests
54 bany a2, a6, .Ldstunaligned # if dst is unaligned
55.L0: # return here from .Ldstunaligned when dst is aligned
56 srli a7, a4, 4 # number of loop iterations with 16B
57 # per iteration
58 bnez a4, .Laligned
59 retw
60
61/*
62 * Destination is word-aligned.
63 */
64 # set 16 bytes per iteration for word-aligned dst
65 .align 4 # 1 mod 4 alignment for LOOPNEZ
66 .byte 0 # (0 mod 4 alignment for LBEG)
67.Laligned:
68#if XCHAL_HAVE_LOOPS
69 loopnez a7, .Loop1done
70#else /* !XCHAL_HAVE_LOOPS */
71 beqz a7, .Loop1done
72 slli a6, a7, 4
73 add a6, a6, a5 # a6 = end of last 16B chunk
74#endif /* !XCHAL_HAVE_LOOPS */
75.Loop1:
76 EX(s32i, a3, a5, 0, memset_fixup)
77 EX(s32i, a3, a5, 4, memset_fixup)
78 EX(s32i, a3, a5, 8, memset_fixup)
79 EX(s32i, a3, a5, 12, memset_fixup)
80 addi a5, a5, 16
81#if !XCHAL_HAVE_LOOPS
82 blt a5, a6, .Loop1
83#endif /* !XCHAL_HAVE_LOOPS */
84.Loop1done:
85 bbci.l a4, 3, .L2
86 # set 8 bytes
87 EX(s32i, a3, a5, 0, memset_fixup)
88 EX(s32i, a3, a5, 4, memset_fixup)
89 addi a5, a5, 8
90.L2:
91 bbci.l a4, 2, .L3
92 # set 4 bytes
93 EX(s32i, a3, a5, 0, memset_fixup)
94 addi a5, a5, 4
95.L3:
96 bbci.l a4, 1, .L4
97 # set 2 bytes
98 EX(s16i, a3, a5, 0, memset_fixup)
99 addi a5, a5, 2
100.L4:
101 bbci.l a4, 0, .L5
102 # set 1 byte
103 EX(s8i, a3, a5, 0, memset_fixup)
104.L5:
105.Lret1:
106 retw
107
108/*
109 * Destination is unaligned
110 */
111
112.Ldstunaligned:
113 bltui a4, 8, .Lbyteset # do short copies byte by byte
114 bbci.l a5, 0, .L20 # branch if dst alignment half-aligned
115 # dst is only byte aligned
116 # set 1 byte
117 EX(s8i, a3, a5, 0, memset_fixup)
118 addi a5, a5, 1
119 addi a4, a4, -1
120 # now retest if dst aligned
121 bbci.l a5, 1, .L0 # if now aligned, return to main algorithm
122.L20:
123 # dst half-aligned
124 # set 2 bytes
125 EX(s16i, a3, a5, 0, memset_fixup)
126 addi a5, a5, 2
127 addi a4, a4, -2
128 j .L0 # dst is now aligned, return to main algorithm
129
130/*
131 * Byte by byte set
132 */
133 .align 4
134 .byte 0 # 1 mod 4 alignment for LOOPNEZ
135 # (0 mod 4 alignment for LBEG)
136.Lbyteset:
137#if XCHAL_HAVE_LOOPS
138 loopnez a4, .Lbytesetdone
139#else /* !XCHAL_HAVE_LOOPS */
140 beqz a4, .Lbytesetdone
141 add a6, a5, a4 # a6 = ending address
142#endif /* !XCHAL_HAVE_LOOPS */
143.Lbyteloop:
144 EX(s8i, a3, a5, 0, memset_fixup)
145 addi a5, a5, 1
146#if !XCHAL_HAVE_LOOPS
147 blt a5, a6, .Lbyteloop
148#endif /* !XCHAL_HAVE_LOOPS */
149.Lbytesetdone:
150 retw
151
152
153 .section .fixup, "ax"
154 .align 4
155
156/* We return zero if a failure occurred. */
157
158memset_fixup:
159 movi a2, 0
160 retw
diff --git a/arch/xtensa/lib/pci-auto.c b/arch/xtensa/lib/pci-auto.c
new file mode 100644
index 000000000000..90c790f6123b
--- /dev/null
+++ b/arch/xtensa/lib/pci-auto.c
@@ -0,0 +1,352 @@
1/*
2 * arch/xtensa/kernel/pci-auto.c
3 *
4 * PCI autoconfiguration library
5 *
6 * Copyright (C) 2001 - 2005 Tensilica Inc.
7 *
8 * Chris Zankel <zankel@tensilica.com, cez@zankel.net>
9 *
10 * Based on work from Matt Porter <mporter@mvista.com>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/pci.h>
21
22#include <asm/pci-bridge.h>
23
24
25/*
26 *
27 * Setting up a PCI
28 *
29 * pci_ctrl->first_busno = <first bus number (0)>
30 * pci_ctrl->last_busno = <last bus number (0xff)>
31 * pci_ctrl->ops = <PCI config operations>
32 * pci_ctrl->map_irq = <function to return the interrupt number for a device>
33 *
34 * pci_ctrl->io_space.start = <IO space start address (PCI view)>
35 * pci_ctrl->io_space.end = <IO space end address (PCI view)>
36 * pci_ctrl->io_space.base = <IO space offset: address 0 from CPU space>
37 * pci_ctrl->mem_space.start = <MEM space start address (PCI view)>
38 * pci_ctrl->mem_space.end = <MEM space end address (PCI view)>
39 * pci_ctrl->mem_space.base = <MEM space offset: address 0 from CPU space>
40 *
41 * pcibios_init_resource(&pci_ctrl->io_resource, <IO space start>,
42 * <IO space end>, IORESOURCE_IO, "PCI host bridge");
43 * pcibios_init_resource(&pci_ctrl->mem_resources[0], <MEM space start>,
44 * <MEM space end>, IORESOURCE_MEM, "PCI host bridge");
45 *
46 * pci_ctrl->last_busno = pciauto_bus_scan(pci_ctrl,pci_ctrl->first_busno);
47 *
48 * int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
49 *
50 */
51
52
53/* define DEBUG to print some debugging messages. */
54
55#undef DEBUG
56
57#ifdef DEBUG
58# define DBG(x...) printk(x)
59#else
60# define DBG(x...)
61#endif
62
63static int pciauto_upper_iospc;
64static int pciauto_upper_memspc;
65
66static struct pci_dev pciauto_dev;
67static struct pci_bus pciauto_bus;
68
69/*
70 * Helper functions
71 */
72
73/* Initialize the bars of a PCI device. */
74
75static void __init
76pciauto_setup_bars(struct pci_dev *dev, int bar_limit)
77{
78 int bar_size;
79 int bar, bar_nr;
80 int *upper_limit;
81 int found_mem64 = 0;
82
83 for (bar = PCI_BASE_ADDRESS_0, bar_nr = 0;
84 bar <= bar_limit;
85 bar+=4, bar_nr++)
86 {
87 /* Tickle the BAR and get the size */
88 pci_write_config_dword(dev, bar, 0xffffffff);
89 pci_read_config_dword(dev, bar, &bar_size);
90
91 /* If BAR is not implemented go to the next BAR */
92 if (!bar_size)
93 continue;
94
95 /* Check the BAR type and set our address mask */
96 if (bar_size & PCI_BASE_ADDRESS_SPACE_IO)
97 {
98 bar_size &= PCI_BASE_ADDRESS_IO_MASK;
99 upper_limit = &pciauto_upper_iospc;
100 DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
101 }
102 else
103 {
104 if ((bar_size & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
105 PCI_BASE_ADDRESS_MEM_TYPE_64)
106 found_mem64 = 1;
107
108 bar_size &= PCI_BASE_ADDRESS_MEM_MASK;
109 upper_limit = &pciauto_upper_memspc;
110 DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
111 }
112
113 /* Allocate a base address (bar_size is negative!) */
114 *upper_limit = (*upper_limit + bar_size) & bar_size;
115
116 /* Write it out and update our limit */
117 pci_write_config_dword(dev, bar, *upper_limit);
118
119 /*
120 * If we are a 64-bit decoder then increment to the
121 * upper 32 bits of the bar and force it to locate
122 * in the lower 4GB of memory.
123 */
124
125 if (found_mem64)
126 pci_write_config_dword(dev, (bar+=4), 0x00000000);
127
128 DBG("size=0x%x, address=0x%x\n", ~bar_size + 1, *upper_limit);
129 }
130}
131
132/* Initialize the interrupt number. */
133
134static void __init
135pciauto_setup_irq(struct pci_controller* pci_ctrl,struct pci_dev *dev,int devfn)
136{
137 u8 pin;
138 int irq = 0;
139
140 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
141
142 /* Fix illegal pin numbers. */
143
144 if (pin == 0 || pin > 4)
145 pin = 1;
146
147 if (pci_ctrl->map_irq)
148 irq = pci_ctrl->map_irq(dev, PCI_SLOT(devfn), pin);
149
150 if (irq == -1)
151 irq = 0;
152
153 DBG("PCI Autoconfig: Interrupt %d, pin %d\n", irq, pin);
154
155 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
156}
157
158
159static void __init
160pciauto_prescan_setup_bridge(struct pci_dev *dev, int current_bus,
161 int sub_bus, int *iosave, int *memsave)
162{
163 /* Configure bus number registers */
164 pci_write_config_byte(dev, PCI_PRIMARY_BUS, current_bus);
165 pci_write_config_byte(dev, PCI_SECONDARY_BUS, sub_bus + 1);
166 pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, 0xff);
167
168 /* Round memory allocator to 1MB boundary */
169 pciauto_upper_memspc &= ~(0x100000 - 1);
170 *memsave = pciauto_upper_memspc;
171
172 /* Round I/O allocator to 4KB boundary */
173 pciauto_upper_iospc &= ~(0x1000 - 1);
174 *iosave = pciauto_upper_iospc;
175
176 /* Set up memory and I/O filter limits, assume 32-bit I/O space */
177 pci_write_config_word(dev, PCI_MEMORY_LIMIT,
178 ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
179 pci_write_config_byte(dev, PCI_IO_LIMIT,
180 ((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
181 pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
182 ((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
183}
184
185static void __init
186pciauto_postscan_setup_bridge(struct pci_dev *dev, int current_bus, int sub_bus,
187 int *iosave, int *memsave)
188{
189 int cmdstat;
190
191 /* Configure bus number registers */
192 pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, sub_bus);
193
194 /*
195 * Round memory allocator to 1MB boundary.
196 * If no space used, allocate minimum.
197 */
198 pciauto_upper_memspc &= ~(0x100000 - 1);
199 if (*memsave == pciauto_upper_memspc)
200 pciauto_upper_memspc -= 0x00100000;
201
202 pci_write_config_word(dev, PCI_MEMORY_BASE, pciauto_upper_memspc >> 16);
203
204 /* Allocate 1MB for pre-fretch */
205 pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT,
206 ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
207
208 pciauto_upper_memspc -= 0x100000;
209
210 pci_write_config_word(dev, PCI_PREF_MEMORY_BASE,
211 pciauto_upper_memspc >> 16);
212
213 /* Round I/O allocator to 4KB boundary */
214 pciauto_upper_iospc &= ~(0x1000 - 1);
215 if (*iosave == pciauto_upper_iospc)
216 pciauto_upper_iospc -= 0x1000;
217
218 pci_write_config_byte(dev, PCI_IO_BASE,
219 (pciauto_upper_iospc & 0x0000f000) >> 8);
220 pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
221 pciauto_upper_iospc >> 16);
222
223 /* Enable memory and I/O accesses, enable bus master */
224 pci_read_config_dword(dev, PCI_COMMAND, &cmdstat);
225 pci_write_config_dword(dev, PCI_COMMAND,
226 cmdstat |
227 PCI_COMMAND_IO |
228 PCI_COMMAND_MEMORY |
229 PCI_COMMAND_MASTER);
230}
231
232/*
233 * Scan the current PCI bus.
234 */
235
236
237int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
238{
239 int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
240 unsigned short vid;
241 unsigned char header_type;
242 struct pci_dev *dev = &pciauto_dev;
243
244 pciauto_dev.bus = &pciauto_bus;
245 pciauto_dev.sysdata = pci_ctrl;
246 pciauto_bus.ops = pci_ctrl->ops;
247
248 /*
249 * Fetch our I/O and memory space upper boundaries used
250 * to allocated base addresses on this pci_controller.
251 */
252
253 if (current_bus == pci_ctrl->first_busno)
254 {
255 pciauto_upper_iospc = pci_ctrl->io_resource.end + 1;
256 pciauto_upper_memspc = pci_ctrl->mem_resources[0].end + 1;
257 }
258
259 sub_bus = current_bus;
260
261 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++)
262 {
263 /* Skip our host bridge */
264 if ((current_bus == pci_ctrl->first_busno) && (pci_devfn == 0))
265 continue;
266
267 if (PCI_FUNC(pci_devfn) && !found_multi)
268 continue;
269
270 pciauto_bus.number = current_bus;
271 pciauto_dev.devfn = pci_devfn;
272
273 /* If config space read fails from this device, move on */
274 if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type))
275 continue;
276
277 if (!PCI_FUNC(pci_devfn))
278 found_multi = header_type & 0x80;
279 pci_read_config_word(dev, PCI_VENDOR_ID, &vid);
280
281 if (vid == 0xffff || vid == 0x0000) {
282 found_multi = 0;
283 continue;
284 }
285
286 pci_read_config_dword(dev, PCI_CLASS_REVISION, &pci_class);
287
288 if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
289
290 int iosave, memsave;
291
292 DBG("PCI Autoconfig: Found P2P bridge, device %d\n",
293 PCI_SLOT(pci_devfn));
294
295 /* Allocate PCI I/O and/or memory space */
296 pciauto_setup_bars(dev, PCI_BASE_ADDRESS_1);
297
298 pciauto_prescan_setup_bridge(dev, current_bus, sub_bus,
299 &iosave, &memsave);
300 sub_bus = pciauto_bus_scan(pci_ctrl, sub_bus+1);
301 pciauto_postscan_setup_bridge(dev, current_bus, sub_bus,
302 &iosave, &memsave);
303 pciauto_bus.number = current_bus;
304
305 continue;
306
307 }
308
309
310#if 0
311 /* Skip legacy mode IDE controller */
312
313 if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
314
315 unsigned char prg_iface;
316 pci_read_config_byte(dev, PCI_CLASS_PROG, &prg_iface);
317
318 if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
319 DBG("PCI Autoconfig: Skipping legacy mode "
320 "IDE controller\n");
321 continue;
322 }
323 }
324#endif
325
326 /*
327 * Found a peripheral, enable some standard
328 * settings
329 */
330
331 pci_read_config_dword(dev, PCI_COMMAND, &cmdstat);
332 pci_write_config_dword(dev, PCI_COMMAND,
333 cmdstat |
334 PCI_COMMAND_IO |
335 PCI_COMMAND_MEMORY |
336 PCI_COMMAND_MASTER);
337 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
338
339 /* Allocate PCI I/O and/or memory space */
340 DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
341 current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
342
343 pciauto_setup_bars(dev, PCI_BASE_ADDRESS_5);
344 pciauto_setup_irq(pci_ctrl, dev, pci_devfn);
345 }
346 return sub_bus;
347}
348
349
350
351
352
diff --git a/arch/xtensa/lib/strcasecmp.c b/arch/xtensa/lib/strcasecmp.c
new file mode 100644
index 000000000000..165b2d6effa5
--- /dev/null
+++ b/arch/xtensa/lib/strcasecmp.c
@@ -0,0 +1,32 @@
1/*
2 * linux/arch/xtensa/lib/strcasecmp.c
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2002 Tensilica Inc.
9 */
10
11#include <linux/string.h>
12
13
14/* We handle nothing here except the C locale. Since this is used in
15 only one place, on strings known to contain only 7 bit ASCII, this
16 is ok. */
17
18int strcasecmp(const char *a, const char *b)
19{
20 int ca, cb;
21
22 do {
23 ca = *a++ & 0xff;
24 cb = *b++ & 0xff;
25 if (ca >= 'A' && ca <= 'Z')
26 ca += 'a' - 'A';
27 if (cb >= 'A' && cb <= 'Z')
28 cb += 'a' - 'A';
29 } while (ca == cb && ca != '\0');
30
31 return ca - cb;
32}
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S
new file mode 100644
index 000000000000..71d55df43893
--- /dev/null
+++ b/arch/xtensa/lib/strncpy_user.S
@@ -0,0 +1,224 @@
1/*
2 * arch/xtensa/lib/strncpy_user.S
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Returns: -EFAULT if exception before terminator, N if the entire
9 * buffer filled, else strlen.
10 *
11 * Copyright (C) 2002 Tensilica Inc.
12 */
13
14#include <xtensa/coreasm.h>
15#include <linux/errno.h>
16
17/* Load or store instructions that may cause exceptions use the EX macro. */
18
19#define EX(insn,reg1,reg2,offset,handler) \
209: insn reg1, reg2, offset; \
21 .section __ex_table, "a"; \
22 .word 9b, handler; \
23 .previous
24
25/*
26 * char *__strncpy_user(char *dst, const char *src, size_t len)
27 */
28.text
29.begin literal
30.align 4
31.Lmask0:
32 .byte 0xff, 0x00, 0x00, 0x00
33.Lmask1:
34 .byte 0x00, 0xff, 0x00, 0x00
35.Lmask2:
36 .byte 0x00, 0x00, 0xff, 0x00
37.Lmask3:
38 .byte 0x00, 0x00, 0x00, 0xff
39.end literal
40
41# Register use
42# a0/ return address
43# a1/ stack pointer
44# a2/ return value
45# a3/ src
46# a4/ len
47# a5/ mask0
48# a6/ mask1
49# a7/ mask2
50# a8/ mask3
51# a9/ tmp
52# a10/ tmp
53# a11/ dst
54# a12/ tmp
55
56.align 4
57.global __strncpy_user
58.type __strncpy_user,@function
59__strncpy_user:
60 entry sp, 16 # minimal stack frame
61 # a2/ dst, a3/ src, a4/ len
62 mov a11, a2 # leave dst in return value register
63 beqz a4, .Lret # if len is zero
64 l32r a5, .Lmask0 # mask for byte 0
65 l32r a6, .Lmask1 # mask for byte 1
66 l32r a7, .Lmask2 # mask for byte 2
67 l32r a8, .Lmask3 # mask for byte 3
68 bbsi.l a3, 0, .Lsrc1mod2 # if only 8-bit aligned
69 bbsi.l a3, 1, .Lsrc2mod4 # if only 16-bit aligned
70.Lsrcaligned: # return here when src is word-aligned
71 srli a12, a4, 2 # number of loop iterations with 4B per loop
72 movi a9, 3
73 bnone a11, a9, .Laligned
74 j .Ldstunaligned
75
76.Lsrc1mod2: # src address is odd
77 EX(l8ui, a9, a3, 0, fixup_l) # get byte 0
78 addi a3, a3, 1 # advance src pointer
79 EX(s8i, a9, a11, 0, fixup_s) # store byte 0
80 beqz a9, .Lret # if byte 0 is zero
81 addi a11, a11, 1 # advance dst pointer
82 addi a4, a4, -1 # decrement len
83 beqz a4, .Lret # if len is zero
84 bbci.l a3, 1, .Lsrcaligned # if src is now word-aligned
85
86.Lsrc2mod4: # src address is 2 mod 4
87 EX(l8ui, a9, a3, 0, fixup_l) # get byte 0
88 /* 1-cycle interlock */
89 EX(s8i, a9, a11, 0, fixup_s) # store byte 0
90 beqz a9, .Lret # if byte 0 is zero
91 addi a11, a11, 1 # advance dst pointer
92 addi a4, a4, -1 # decrement len
93 beqz a4, .Lret # if len is zero
94 EX(l8ui, a9, a3, 1, fixup_l) # get byte 0
95 addi a3, a3, 2 # advance src pointer
96 EX(s8i, a9, a11, 0, fixup_s) # store byte 0
97 beqz a9, .Lret # if byte 0 is zero
98 addi a11, a11, 1 # advance dst pointer
99 addi a4, a4, -1 # decrement len
100 bnez a4, .Lsrcaligned # if len is nonzero
101.Lret:
102 sub a2, a11, a2 # compute strlen
103 retw
104
105/*
106 * dst is word-aligned, src is word-aligned
107 */
108 .align 4 # 1 mod 4 alignment for LOOPNEZ
109 .byte 0 # (0 mod 4 alignment for LBEG)
110.Laligned:
111#if XCHAL_HAVE_LOOPS
112 loopnez a12, .Loop1done
113#else
114 beqz a12, .Loop1done
115 slli a12, a12, 2
116 add a12, a12, a11 # a12 = end of last 4B chunck
117#endif
118.Loop1:
119 EX(l32i, a9, a3, 0, fixup_l) # get word from src
120 addi a3, a3, 4 # advance src pointer
121 bnone a9, a5, .Lz0 # if byte 0 is zero
122 bnone a9, a6, .Lz1 # if byte 1 is zero
123 bnone a9, a7, .Lz2 # if byte 2 is zero
124 EX(s32i, a9, a11, 0, fixup_s) # store word to dst
125 bnone a9, a8, .Lz3 # if byte 3 is zero
126 addi a11, a11, 4 # advance dst pointer
127#if !XCHAL_HAVE_LOOPS
128 blt a11, a12, .Loop1
129#endif
130
131.Loop1done:
132 bbci.l a4, 1, .L100
133 # copy 2 bytes
134 EX(l16ui, a9, a3, 0, fixup_l)
135 addi a3, a3, 2 # advance src pointer
136#ifdef __XTENSA_EB__
137 bnone a9, a7, .Lz0 # if byte 2 is zero
138 bnone a9, a8, .Lz1 # if byte 3 is zero
139#else
140 bnone a9, a5, .Lz0 # if byte 0 is zero
141 bnone a9, a6, .Lz1 # if byte 1 is zero
142#endif
143 EX(s16i, a9, a11, 0, fixup_s)
144 addi a11, a11, 2 # advance dst pointer
145.L100:
146 bbci.l a4, 0, .Lret
147 EX(l8ui, a9, a3, 0, fixup_l)
148 /* slot */
149 EX(s8i, a9, a11, 0, fixup_s)
150 beqz a9, .Lret # if byte is zero
151 addi a11, a11, 1-3 # advance dst ptr 1, but also cancel
152 # the effect of adding 3 in .Lz3 code
153 /* fall thru to .Lz3 and "retw" */
154
155.Lz3: # byte 3 is zero
156 addi a11, a11, 3 # advance dst pointer
157 sub a2, a11, a2 # compute strlen
158 retw
159.Lz0: # byte 0 is zero
160#ifdef __XTENSA_EB__
161 movi a9, 0
162#endif /* __XTENSA_EB__ */
163 EX(s8i, a9, a11, 0, fixup_s)
164 sub a2, a11, a2 # compute strlen
165 retw
166.Lz1: # byte 1 is zero
167#ifdef __XTENSA_EB__
168 extui a9, a9, 16, 16
169#endif /* __XTENSA_EB__ */
170 EX(s16i, a9, a11, 0, fixup_s)
171 addi a11, a11, 1 # advance dst pointer
172 sub a2, a11, a2 # compute strlen
173 retw
174.Lz2: # byte 2 is zero
175#ifdef __XTENSA_EB__
176 extui a9, a9, 16, 16
177#endif /* __XTENSA_EB__ */
178 EX(s16i, a9, a11, 0, fixup_s)
179 movi a9, 0
180 EX(s8i, a9, a11, 2, fixup_s)
181 addi a11, a11, 2 # advance dst pointer
182 sub a2, a11, a2 # compute strlen
183 retw
184
185 .align 4 # 1 mod 4 alignment for LOOPNEZ
186 .byte 0 # (0 mod 4 alignment for LBEG)
187.Ldstunaligned:
188/*
189 * for now just use byte copy loop
190 */
191#if XCHAL_HAVE_LOOPS
192 loopnez a4, .Lunalignedend
193#else
194 beqz a4, .Lunalignedend
195 add a12, a11, a4 # a12 = ending address
196#endif /* XCHAL_HAVE_LOOPS */
197.Lnextbyte:
198 EX(l8ui, a9, a3, 0, fixup_l)
199 addi a3, a3, 1
200 EX(s8i, a9, a11, 0, fixup_s)
201 beqz a9, .Lunalignedend
202 addi a11, a11, 1
203#if !XCHAL_HAVE_LOOPS
204 blt a11, a12, .Lnextbyte
205#endif
206
207.Lunalignedend:
208 sub a2, a11, a2 # compute strlen
209 retw
210
211
212 .section .fixup, "ax"
213 .align 4
214
215 /* For now, just return -EFAULT. Future implementations might
216 * like to clear remaining kernel space, like the fixup
217 * implementation in memset(). Thus, we differentiate between
218 * load/store fixups. */
219
220fixup_s:
221fixup_l:
222 movi a2, -EFAULT
223 retw
224
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S
new file mode 100644
index 000000000000..cdff4d670f3b
--- /dev/null
+++ b/arch/xtensa/lib/strnlen_user.S
@@ -0,0 +1,147 @@
1/*
2 * arch/xtensa/lib/strnlen_user.S
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Returns strnlen, including trailing zero terminator.
9 * Zero indicates error.
10 *
11 * Copyright (C) 2002 Tensilica Inc.
12 */
13
14#include <xtensa/coreasm.h>
15
16/* Load or store instructions that may cause exceptions use the EX macro. */
17
18#define EX(insn,reg1,reg2,offset,handler) \
199: insn reg1, reg2, offset; \
20 .section __ex_table, "a"; \
21 .word 9b, handler; \
22 .previous
23
24/*
25 * size_t __strnlen_user(const char *s, size_t len)
26 */
27.text
28.begin literal
29.align 4
30.Lmask0:
31 .byte 0xff, 0x00, 0x00, 0x00
32.Lmask1:
33 .byte 0x00, 0xff, 0x00, 0x00
34.Lmask2:
35 .byte 0x00, 0x00, 0xff, 0x00
36.Lmask3:
37 .byte 0x00, 0x00, 0x00, 0xff
38.end literal
39
40# Register use:
41# a2/ src
42# a3/ len
43# a4/ tmp
44# a5/ mask0
45# a6/ mask1
46# a7/ mask2
47# a8/ mask3
48# a9/ tmp
49# a10/ tmp
50
51.align 4
52.global __strnlen_user
53.type __strnlen_user,@function
54__strnlen_user:
55 entry sp, 16 # minimal stack frame
56 # a2/ s, a3/ len
57 addi a4, a2, -4 # because we overincrement at the end;
58 # we compensate with load offsets of 4
59 l32r a5, .Lmask0 # mask for byte 0
60 l32r a6, .Lmask1 # mask for byte 1
61 l32r a7, .Lmask2 # mask for byte 2
62 l32r a8, .Lmask3 # mask for byte 3
63 bbsi.l a2, 0, .L1mod2 # if only 8-bit aligned
64 bbsi.l a2, 1, .L2mod4 # if only 16-bit aligned
65
66/*
67 * String is word-aligned.
68 */
69.Laligned:
70 srli a10, a3, 2 # number of loop iterations with 4B per loop
71#if XCHAL_HAVE_LOOPS
72 loopnez a10, .Ldone
73#else
74 beqz a10, .Ldone
75 slli a10, a10, 2
76 add a10, a10, a4 # a10 = end of last 4B chunk
77#endif /* XCHAL_HAVE_LOOPS */
78.Loop:
79 EX(l32i, a9, a4, 4, lenfixup) # get next word of string
80 addi a4, a4, 4 # advance string pointer
81 bnone a9, a5, .Lz0 # if byte 0 is zero
82 bnone a9, a6, .Lz1 # if byte 1 is zero
83 bnone a9, a7, .Lz2 # if byte 2 is zero
84 bnone a9, a8, .Lz3 # if byte 3 is zero
85#if !XCHAL_HAVE_LOOPS
86 blt a4, a10, .Loop
87#endif
88
89.Ldone:
90 EX(l32i, a9, a4, 4, lenfixup) # load 4 bytes for remaining checks
91
92 bbci.l a3, 1, .L100
93 # check two more bytes (bytes 0, 1 of word)
94 addi a4, a4, 2 # advance string pointer
95 bnone a9, a5, .Lz0 # if byte 0 is zero
96 bnone a9, a6, .Lz1 # if byte 1 is zero
97.L100:
98 bbci.l a3, 0, .L101
99 # check one more byte (byte 2 of word)
100 # Actually, we don't need to check. Zero or nonzero, we'll add one.
101 # Do not add an extra one for the NULL terminator since we have
102 # exhausted the original len parameter.
103 addi a4, a4, 1 # advance string pointer
104.L101:
105 sub a2, a4, a2 # compute length
106 retw
107
108# NOTE that in several places below, we point to the byte just after
109# the zero byte in order to include the NULL terminator in the count.
110
111.Lz3: # byte 3 is zero
112 addi a4, a4, 3 # point to zero byte
113.Lz0: # byte 0 is zero
114 addi a4, a4, 1 # point just beyond zero byte
115 sub a2, a4, a2 # subtract to get length
116 retw
117.Lz1: # byte 1 is zero
118 addi a4, a4, 1+1 # point just beyond zero byte
119 sub a2, a4, a2 # subtract to get length
120 retw
121.Lz2: # byte 2 is zero
122 addi a4, a4, 2+1 # point just beyond zero byte
123 sub a2, a4, a2 # subtract to get length
124 retw
125
126.L1mod2: # address is odd
127 EX(l8ui, a9, a4, 4, lenfixup) # get byte 0
128 addi a4, a4, 1 # advance string pointer
129 beqz a9, .Lz3 # if byte 0 is zero
130 bbci.l a4, 1, .Laligned # if string pointer is now word-aligned
131
132.L2mod4: # address is 2 mod 4
133 addi a4, a4, 2 # advance ptr for aligned access
134 EX(l32i, a9, a4, 0, lenfixup) # get word with first two bytes of string
135 bnone a9, a7, .Lz2 # if byte 2 (of word, not string) is zero
136 bany a9, a8, .Laligned # if byte 3 (of word, not string) is nonzero
137 # byte 3 is zero
138 addi a4, a4, 3+1 # point just beyond zero byte
139 sub a2, a4, a2 # subtract to get length
140 retw
141
142 .section .fixup, "ax"
143 .align 4
144lenfixup:
145 movi a2, 0
146 retw
147
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S
new file mode 100644
index 000000000000..265db2693cbd
--- /dev/null
+++ b/arch/xtensa/lib/usercopy.S
@@ -0,0 +1,321 @@
1/*
2 * arch/xtensa/lib/usercopy.S
3 *
4 * Copy to/from user space (derived from arch/xtensa/lib/hal/memcopy.S)
5 *
6 * DO NOT COMBINE this function with <arch/xtensa/lib/hal/memcopy.S>.
7 * It needs to remain separate and distinct. The hal files are part
8 * of the the Xtensa link-time HAL, and those files may differ per
9 * processor configuration. Patching the kernel for another
10 * processor configuration includes replacing the hal files, and we
11 * could loose the special functionality for accessing user-space
12 * memory during such a patch. We sacrifice a little code space here
13 * in favor to simplify code maintenance.
14 *
15 * This file is subject to the terms and conditions of the GNU General
16 * Public License. See the file "COPYING" in the main directory of
17 * this archive for more details.
18 *
19 * Copyright (C) 2002 Tensilica Inc.
20 */
21
22
23/*
24 * size_t __xtensa_copy_user (void *dst, const void *src, size_t len);
25 *
26 * The returned value is the number of bytes not copied. Implies zero
27 * is success.
28 *
29 * The general case algorithm is as follows:
30 * If the destination and source are both aligned,
31 * do 16B chunks with a loop, and then finish up with
32 * 8B, 4B, 2B, and 1B copies conditional on the length.
33 * If destination is aligned and source unaligned,
34 * do the same, but use SRC to align the source data.
35 * If destination is unaligned, align it by conditionally
36 * copying 1B and 2B and then retest.
37 * This code tries to use fall-through braches for the common
38 * case of aligned destinations (except for the branches to
39 * the alignment label).
40 *
41 * Register use:
42 * a0/ return address
43 * a1/ stack pointer
44 * a2/ return value
45 * a3/ src
46 * a4/ length
47 * a5/ dst
48 * a6/ tmp
49 * a7/ tmp
50 * a8/ tmp
51 * a9/ tmp
52 * a10/ tmp
53 * a11/ original length
54 */
55
56#include <xtensa/coreasm.h>
57
58#ifdef __XTENSA_EB__
59#define ALIGN(R, W0, W1) src R, W0, W1
60#define SSA8(R) ssa8b R
61#else
62#define ALIGN(R, W0, W1) src R, W1, W0
63#define SSA8(R) ssa8l R
64#endif
65
66/* Load or store instructions that may cause exceptions use the EX macro. */
67
68#define EX(insn,reg1,reg2,offset,handler) \
699: insn reg1, reg2, offset; \
70 .section __ex_table, "a"; \
71 .word 9b, handler; \
72 .previous
73
74
75 .text
76 .align 4
77 .global __xtensa_copy_user
78 .type __xtensa_copy_user,@function
79__xtensa_copy_user:
80 entry sp, 16 # minimal stack frame
81 # a2/ dst, a3/ src, a4/ len
82 mov a5, a2 # copy dst so that a2 is return value
83 mov a11, a4 # preserve original len for error case
84.Lcommon:
85 bbsi.l a2, 0, .Ldst1mod2 # if dst is 1 mod 2
86 bbsi.l a2, 1, .Ldst2mod4 # if dst is 2 mod 4
87.Ldstaligned: # return here from .Ldstunaligned when dst is aligned
88 srli a7, a4, 4 # number of loop iterations with 16B
89 # per iteration
90 movi a8, 3 # if source is also aligned,
91 bnone a3, a8, .Laligned # then use word copy
92 SSA8( a3) # set shift amount from byte offset
93 bnez a4, .Lsrcunaligned
94 movi a2, 0 # return success for len==0
95 retw
96
97/*
98 * Destination is unaligned
99 */
100
101.Ldst1mod2: # dst is only byte aligned
102 bltui a4, 7, .Lbytecopy # do short copies byte by byte
103
104 # copy 1 byte
105 EX(l8ui, a6, a3, 0, l_fixup)
106 addi a3, a3, 1
107 EX(s8i, a6, a5, 0, s_fixup)
108 addi a5, a5, 1
109 addi a4, a4, -1
110 bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then
111 # return to main algorithm
112.Ldst2mod4: # dst 16-bit aligned
113 # copy 2 bytes
114 bltui a4, 6, .Lbytecopy # do short copies byte by byte
115 EX(l8ui, a6, a3, 0, l_fixup)
116 EX(l8ui, a7, a3, 1, l_fixup)
117 addi a3, a3, 2
118 EX(s8i, a6, a5, 0, s_fixup)
119 EX(s8i, a7, a5, 1, s_fixup)
120 addi a5, a5, 2
121 addi a4, a4, -2
122 j .Ldstaligned # dst is now aligned, return to main algorithm
123
124/*
125 * Byte by byte copy
126 */
127 .align 4
128 .byte 0 # 1 mod 4 alignment for LOOPNEZ
129 # (0 mod 4 alignment for LBEG)
130.Lbytecopy:
131#if XCHAL_HAVE_LOOPS
132 loopnez a4, .Lbytecopydone
133#else /* !XCHAL_HAVE_LOOPS */
134 beqz a4, .Lbytecopydone
135 add a7, a3, a4 # a7 = end address for source
136#endif /* !XCHAL_HAVE_LOOPS */
137.Lnextbyte:
138 EX(l8ui, a6, a3, 0, l_fixup)
139 addi a3, a3, 1
140 EX(s8i, a6, a5, 0, s_fixup)
141 addi a5, a5, 1
142#if !XCHAL_HAVE_LOOPS
143 blt a3, a7, .Lnextbyte
144#endif /* !XCHAL_HAVE_LOOPS */
145.Lbytecopydone:
146 movi a2, 0 # return success for len bytes copied
147 retw
148
149/*
150 * Destination and source are word-aligned.
151 */
152 # copy 16 bytes per iteration for word-aligned dst and word-aligned src
153 .align 4 # 1 mod 4 alignment for LOOPNEZ
154 .byte 0 # (0 mod 4 alignment for LBEG)
155.Laligned:
156#if XCHAL_HAVE_LOOPS
157 loopnez a7, .Loop1done
158#else /* !XCHAL_HAVE_LOOPS */
159 beqz a7, .Loop1done
160 slli a8, a7, 4
161 add a8, a8, a3 # a8 = end of last 16B source chunk
162#endif /* !XCHAL_HAVE_LOOPS */
163.Loop1:
164 EX(l32i, a6, a3, 0, l_fixup)
165 EX(l32i, a7, a3, 4, l_fixup)
166 EX(s32i, a6, a5, 0, s_fixup)
167 EX(l32i, a6, a3, 8, l_fixup)
168 EX(s32i, a7, a5, 4, s_fixup)
169 EX(l32i, a7, a3, 12, l_fixup)
170 EX(s32i, a6, a5, 8, s_fixup)
171 addi a3, a3, 16
172 EX(s32i, a7, a5, 12, s_fixup)
173 addi a5, a5, 16
174#if !XCHAL_HAVE_LOOPS
175 blt a3, a8, .Loop1
176#endif /* !XCHAL_HAVE_LOOPS */
177.Loop1done:
178 bbci.l a4, 3, .L2
179 # copy 8 bytes
180 EX(l32i, a6, a3, 0, l_fixup)
181 EX(l32i, a7, a3, 4, l_fixup)
182 addi a3, a3, 8
183 EX(s32i, a6, a5, 0, s_fixup)
184 EX(s32i, a7, a5, 4, s_fixup)
185 addi a5, a5, 8
186.L2:
187 bbci.l a4, 2, .L3
188 # copy 4 bytes
189 EX(l32i, a6, a3, 0, l_fixup)
190 addi a3, a3, 4
191 EX(s32i, a6, a5, 0, s_fixup)
192 addi a5, a5, 4
193.L3:
194 bbci.l a4, 1, .L4
195 # copy 2 bytes
196 EX(l16ui, a6, a3, 0, l_fixup)
197 addi a3, a3, 2
198 EX(s16i, a6, a5, 0, s_fixup)
199 addi a5, a5, 2
200.L4:
201 bbci.l a4, 0, .L5
202 # copy 1 byte
203 EX(l8ui, a6, a3, 0, l_fixup)
204 EX(s8i, a6, a5, 0, s_fixup)
205.L5:
206 movi a2, 0 # return success for len bytes copied
207 retw
208
209/*
210 * Destination is aligned, Source is unaligned
211 */
212
213 .align 4
214 .byte 0 # 1 mod 4 alignement for LOOPNEZ
215 # (0 mod 4 alignment for LBEG)
216.Lsrcunaligned:
217 # copy 16 bytes per iteration for word-aligned dst and unaligned src
218 and a10, a3, a8 # save unalignment offset for below
219 sub a3, a3, a10 # align a3 (to avoid sim warnings only; not needed for hardware)
220 EX(l32i, a6, a3, 0, l_fixup) # load first word
221#if XCHAL_HAVE_LOOPS
222 loopnez a7, .Loop2done
223#else /* !XCHAL_HAVE_LOOPS */
224 beqz a7, .Loop2done
225 slli a10, a7, 4
226 add a10, a10, a3 # a10 = end of last 16B source chunk
227#endif /* !XCHAL_HAVE_LOOPS */
228.Loop2:
229 EX(l32i, a7, a3, 4, l_fixup)
230 EX(l32i, a8, a3, 8, l_fixup)
231 ALIGN( a6, a6, a7)
232 EX(s32i, a6, a5, 0, s_fixup)
233 EX(l32i, a9, a3, 12, l_fixup)
234 ALIGN( a7, a7, a8)
235 EX(s32i, a7, a5, 4, s_fixup)
236 EX(l32i, a6, a3, 16, l_fixup)
237 ALIGN( a8, a8, a9)
238 EX(s32i, a8, a5, 8, s_fixup)
239 addi a3, a3, 16
240 ALIGN( a9, a9, a6)
241 EX(s32i, a9, a5, 12, s_fixup)
242 addi a5, a5, 16
243#if !XCHAL_HAVE_LOOPS
244 blt a3, a10, .Loop2
245#endif /* !XCHAL_HAVE_LOOPS */
246.Loop2done:
247 bbci.l a4, 3, .L12
248 # copy 8 bytes
249 EX(l32i, a7, a3, 4, l_fixup)
250 EX(l32i, a8, a3, 8, l_fixup)
251 ALIGN( a6, a6, a7)
252 EX(s32i, a6, a5, 0, s_fixup)
253 addi a3, a3, 8
254 ALIGN( a7, a7, a8)
255 EX(s32i, a7, a5, 4, s_fixup)
256 addi a5, a5, 8
257 mov a6, a8
258.L12:
259 bbci.l a4, 2, .L13
260 # copy 4 bytes
261 EX(l32i, a7, a3, 4, l_fixup)
262 addi a3, a3, 4
263 ALIGN( a6, a6, a7)
264 EX(s32i, a6, a5, 0, s_fixup)
265 addi a5, a5, 4
266 mov a6, a7
267.L13:
268 add a3, a3, a10 # readjust a3 with correct misalignment
269 bbci.l a4, 1, .L14
270 # copy 2 bytes
271 EX(l8ui, a6, a3, 0, l_fixup)
272 EX(l8ui, a7, a3, 1, l_fixup)
273 addi a3, a3, 2
274 EX(s8i, a6, a5, 0, s_fixup)
275 EX(s8i, a7, a5, 1, s_fixup)
276 addi a5, a5, 2
277.L14:
278 bbci.l a4, 0, .L15
279 # copy 1 byte
280 EX(l8ui, a6, a3, 0, l_fixup)
281 EX(s8i, a6, a5, 0, s_fixup)
282.L15:
283 movi a2, 0 # return success for len bytes copied
284 retw
285
286
287 .section .fixup, "ax"
288 .align 4
289
290/* a2 = original dst; a5 = current dst; a11= original len
291 * bytes_copied = a5 - a2
292 * retval = bytes_not_copied = original len - bytes_copied
293 * retval = a11 - (a5 - a2)
294 *
295 * Clearing the remaining pieces of kernel memory plugs security
296 * holes. This functionality is the equivalent of the *_zeroing
297 * functions that some architectures provide.
298 */
299
300.Lmemset:
301 .word memset
302
303s_fixup:
304 sub a2, a5, a2 /* a2 <-- bytes copied */
305 sub a2, a11, a2 /* a2 <-- bytes not copied */
306 retw
307
308l_fixup:
309 sub a2, a5, a2 /* a2 <-- bytes copied */
310 sub a2, a11, a2 /* a2 <-- bytes not copied == return value */
311
312 /* void *memset(void *s, int c, size_t n); */
313 mov a6, a5 /* s */
314 movi a7, 0 /* c */
315 mov a8, a2 /* n */
316 l32r a4, .Lmemset
317 callx4 a4
318 /* Ignore memset return value in a6. */
319 /* a2 still contains bytes not copied. */
320 retw
321
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
new file mode 100644
index 000000000000..a5aed5932d7b
--- /dev/null
+++ b/arch/xtensa/mm/Makefile
@@ -0,0 +1,13 @@
1#
2# Makefile for the Linux/Xtensa-specific parts of the memory manager.
3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8# Note 2! The CFLAGS definition is now in the main makefile...
9
10obj-y := init.o fault.o tlb.o misc.o
11obj-m :=
12obj-n :=
13obj- :=
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
new file mode 100644
index 000000000000..a945a33e85a1
--- /dev/null
+++ b/arch/xtensa/mm/fault.c
@@ -0,0 +1,241 @@
1// TODO VM_EXEC flag work-around, cache aliasing
2/*
3 * arch/xtensa/mm/fault.c
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
7 * for more details.
8 *
9 * Copyright (C) 2001 - 2005 Tensilica Inc.
10 *
11 * Chris Zankel <chris@zankel.net>
12 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
13 */
14
15#include <linux/mm.h>
16#include <linux/module.h>
17#include <asm/mmu_context.h>
18#include <asm/cacheflush.h>
19#include <asm/hardirq.h>
20#include <asm/uaccess.h>
21#include <asm/system.h>
22#include <asm/pgalloc.h>
23
24unsigned long asid_cache = ASID_FIRST_VERSION;
25void bad_page_fault(struct pt_regs*, unsigned long, int);
26
27/*
28 * This routine handles page faults. It determines the address,
29 * and the problem, and then passes it off to one of the appropriate
30 * routines.
31 *
32 * Note: does not handle Miss and MultiHit.
33 */
34
35void do_page_fault(struct pt_regs *regs)
36{
37 struct vm_area_struct * vma;
38 struct mm_struct *mm = current->mm;
39 unsigned int exccause = regs->exccause;
40 unsigned int address = regs->excvaddr;
41 siginfo_t info;
42
43 int is_write, is_exec;
44
45 info.si_code = SEGV_MAPERR;
46
47 /* We fault-in kernel-space virtual memory on-demand. The
48 * 'reference' page table is init_mm.pgd.
49 */
50 if (address >= TASK_SIZE && !user_mode(regs))
51 goto vmalloc_fault;
52
53 /* If we're in an interrupt or have no user
54 * context, we must not take the fault..
55 */
56 if (in_atomic() || !mm) {
57 bad_page_fault(regs, address, SIGSEGV);
58 return;
59 }
60
61 is_write = (exccause == XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE) ? 1 : 0;
62 is_exec = (exccause == XCHAL_EXCCAUSE_ITLB_PRIVILEGE ||
63 exccause == XCHAL_EXCCAUSE_ITLB_MISS ||
64 exccause == XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0;
65
66#if 0
67 printk("[%s:%d:%08x:%d:%08x:%s%s]\n", current->comm, current->pid,
68 address, exccause, regs->pc, is_write? "w":"", is_exec? "x":"");
69#endif
70
71 down_read(&mm->mmap_sem);
72 vma = find_vma(mm, address);
73
74 if (!vma)
75 goto bad_area;
76 if (vma->vm_start <= address)
77 goto good_area;
78 if (!(vma->vm_flags & VM_GROWSDOWN))
79 goto bad_area;
80 if (expand_stack(vma, address))
81 goto bad_area;
82
83 /* Ok, we have a good vm_area for this memory access, so
84 * we can handle it..
85 */
86
87good_area:
88 info.si_code = SEGV_ACCERR;
89
90 if (is_write) {
91 if (!(vma->vm_flags & VM_WRITE))
92 goto bad_area;
93 } else if (is_exec) {
94 if (!(vma->vm_flags & VM_EXEC))
95 goto bad_area;
96 } else /* Allow read even from write-only pages. */
97 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
98 goto bad_area;
99
100 /* If for any reason at all we couldn't handle the fault,
101 * make sure we exit gracefully rather than endlessly redo
102 * the fault.
103 */
104survive:
105 switch (handle_mm_fault(mm, vma, address, is_write)) {
106 case VM_FAULT_MINOR:
107 current->min_flt++;
108 break;
109 case VM_FAULT_MAJOR:
110 current->maj_flt++;
111 break;
112 case VM_FAULT_SIGBUS:
113 goto do_sigbus;
114 case VM_FAULT_OOM:
115 goto out_of_memory;
116 default:
117 BUG();
118 }
119
120 up_read(&mm->mmap_sem);
121 return;
122
123 /* Something tried to access memory that isn't in our memory map..
124 * Fix it, but check if it's kernel or user first..
125 */
126bad_area:
127 up_read(&mm->mmap_sem);
128 if (user_mode(regs)) {
129 current->thread.bad_vaddr = address;
130 current->thread.error_code = is_write;
131 info.si_signo = SIGSEGV;
132 info.si_errno = 0;
133 /* info.si_code has been set above */
134 info.si_addr = (void *) address;
135 force_sig_info(SIGSEGV, &info, current);
136 return;
137 }
138 bad_page_fault(regs, address, SIGSEGV);
139 return;
140
141
142 /* We ran out of memory, or some other thing happened to us that made
143 * us unable to handle the page fault gracefully.
144 */
145out_of_memory:
146 up_read(&mm->mmap_sem);
147 if (current->pid == 1) {
148 yield();
149 down_read(&mm->mmap_sem);
150 goto survive;
151 }
152 printk("VM: killing process %s\n", current->comm);
153 if (user_mode(regs))
154 do_exit(SIGKILL);
155 bad_page_fault(regs, address, SIGKILL);
156 return;
157
158do_sigbus:
159 up_read(&mm->mmap_sem);
160
161 /* Send a sigbus, regardless of whether we were in kernel
162 * or user mode.
163 */
164 current->thread.bad_vaddr = address;
165 info.si_code = SIGBUS;
166 info.si_errno = 0;
167 info.si_code = BUS_ADRERR;
168 info.si_addr = (void *) address;
169 force_sig_info(SIGBUS, &info, current);
170
171 /* Kernel mode? Handle exceptions or die */
172 if (!user_mode(regs))
173 bad_page_fault(regs, address, SIGBUS);
174
175vmalloc_fault:
176 {
177 /* Synchronize this task's top level page-table
178 * with the 'reference' page table.
179 */
180 struct mm_struct *act_mm = current->active_mm;
181 int index = pgd_index(address);
182 pgd_t *pgd, *pgd_k;
183 pmd_t *pmd, *pmd_k;
184 pte_t *pte_k;
185
186 if (act_mm == NULL)
187 goto bad_page_fault;
188
189 pgd = act_mm->pgd + index;
190 pgd_k = init_mm.pgd + index;
191
192 if (!pgd_present(*pgd_k))
193 goto bad_page_fault;
194
195 pgd_val(*pgd) = pgd_val(*pgd_k);
196
197 pmd = pmd_offset(pgd, address);
198 pmd_k = pmd_offset(pgd_k, address);
199 if (!pmd_present(*pmd) || !pmd_present(*pmd_k))
200 goto bad_page_fault;
201
202 pmd_val(*pmd) = pmd_val(*pmd_k);
203 pte_k = pte_offset_kernel(pmd_k, address);
204
205 if (!pte_present(*pte_k))
206 goto bad_page_fault;
207 return;
208 }
209bad_page_fault:
210 bad_page_fault(regs, address, SIGKILL);
211 return;
212}
213
214
215void
216bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
217{
218 extern void die(const char*, struct pt_regs*, long);
219 const struct exception_table_entry *entry;
220
221 /* Are we prepared to handle this kernel fault? */
222 if ((entry = search_exception_tables(regs->pc)) != NULL) {
223#if 1
224 printk(KERN_DEBUG "%s: Exception at pc=%#010lx (%lx)\n",
225 current->comm, regs->pc, entry->fixup);
226#endif
227 current->thread.bad_uaddr = address;
228 regs->pc = entry->fixup;
229 return;
230 }
231
232 /* Oops. The kernel tried to access some bad page. We'll have to
233 * terminate things with extreme prejudice.
234 */
235 printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
236 "address %08lx\n pc = %08lx, ra = %08lx\n",
237 address, regs->pc, regs->areg[0]);
238 die("Oops", regs, sig);
239 do_exit(sig);
240}
241
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
new file mode 100644
index 000000000000..56aace84aaeb
--- /dev/null
+++ b/arch/xtensa/mm/init.c
@@ -0,0 +1,551 @@
1/*
2 * arch/xtensa/mm/init.c
3 *
4 * Derived from MIPS, PPC.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
14 * Marc Gauthier
15 * Kevin Chea
16 */
17
18#include <linux/config.h>
19#include <linux/init.h>
20#include <linux/signal.h>
21#include <linux/sched.h>
22#include <linux/kernel.h>
23#include <linux/errno.h>
24#include <linux/string.h>
25#include <linux/types.h>
26#include <linux/ptrace.h>
27#include <linux/bootmem.h>
28#include <linux/swap.h>
29
30#include <asm/pgtable.h>
31#include <asm/bootparam.h>
32#include <asm/mmu_context.h>
33#include <asm/tlb.h>
34#include <asm/tlbflush.h>
35#include <asm/page.h>
36#include <asm/pgalloc.h>
37#include <asm/pgtable.h>
38
39
40#define DEBUG 0
41
42DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
43//static DEFINE_SPINLOCK(tlb_lock);
44
45/*
46 * This flag is used to indicate that the page was mapped and modified in
47 * kernel space, so the cache is probably dirty at that address.
48 * If cache aliasing is enabled and the page color mismatches, update_mmu_cache
49 * synchronizes the caches if this bit is set.
50 */
51
52#define PG_cache_clean PG_arch_1
53
54/* References to section boundaries */
55
56extern char _ftext, _etext, _fdata, _edata, _rodata_end;
57extern char __init_begin, __init_end;
58
59/*
60 * mem_reserve(start, end, must_exist)
61 *
62 * Reserve some memory from the memory pool.
63 *
64 * Parameters:
65 * start Start of region,
66 * end End of region,
67 * must_exist Must exist in memory pool.
68 *
69 * Returns:
70 * 0 (memory area couldn't be mapped)
71 * -1 (success)
72 */
73
74int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
75{
76 int i;
77
78 if (start == end)
79 return 0;
80
81 start = start & PAGE_MASK;
82 end = PAGE_ALIGN(end);
83
84 for (i = 0; i < sysmem.nr_banks; i++)
85 if (start < sysmem.bank[i].end
86 && end >= sysmem.bank[i].start)
87 break;
88
89 if (i == sysmem.nr_banks) {
90 if (must_exist)
91 printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) "
92 "not in any region!\n", start, end);
93 return 0;
94 }
95
96 if (start > sysmem.bank[i].start) {
97 if (end < sysmem.bank[i].end) {
98 /* split entry */
99 if (sysmem.nr_banks >= SYSMEM_BANKS_MAX)
100 panic("meminfo overflow\n");
101 sysmem.bank[sysmem.nr_banks].start = end;
102 sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end;
103 sysmem.nr_banks++;
104 }
105 sysmem.bank[i].end = start;
106 } else {
107 if (end < sysmem.bank[i].end)
108 sysmem.bank[i].start = end;
109 else {
110 /* remove entry */
111 sysmem.nr_banks--;
112 sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start;
113 sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end;
114 }
115 }
116 return -1;
117}
118
119
120/*
121 * Initialize the bootmem system and give it all the memory we have available.
122 */
123
124void __init bootmem_init(void)
125{
126 unsigned long pfn;
127 unsigned long bootmap_start, bootmap_size;
128 int i;
129
130 max_low_pfn = max_pfn = 0;
131 min_low_pfn = ~0;
132
133 for (i=0; i < sysmem.nr_banks; i++) {
134 pfn = PAGE_ALIGN(sysmem.bank[i].start) >> PAGE_SHIFT;
135 if (pfn < min_low_pfn)
136 min_low_pfn = pfn;
137 pfn = PAGE_ALIGN(sysmem.bank[i].end - 1) >> PAGE_SHIFT;
138 if (pfn > max_pfn)
139 max_pfn = pfn;
140 }
141
142 if (min_low_pfn > max_pfn)
143 panic("No memory found!\n");
144
145 max_low_pfn = max_pfn < MAX_LOW_MEMORY >> PAGE_SHIFT ?
146 max_pfn : MAX_LOW_MEMORY >> PAGE_SHIFT;
147
148 /* Find an area to use for the bootmem bitmap. */
149
150 bootmap_size = bootmem_bootmap_pages(max_low_pfn) << PAGE_SHIFT;
151 bootmap_start = ~0;
152
153 for (i=0; i<sysmem.nr_banks; i++)
154 if (sysmem.bank[i].end - sysmem.bank[i].start >= bootmap_size) {
155 bootmap_start = sysmem.bank[i].start;
156 break;
157 }
158
159 if (bootmap_start == ~0UL)
160 panic("Cannot find %ld bytes for bootmap\n", bootmap_size);
161
162 /* Reserve the bootmem bitmap area */
163
164 mem_reserve(bootmap_start, bootmap_start + bootmap_size, 1);
165 bootmap_size = init_bootmem_node(NODE_DATA(0), min_low_pfn,
166 bootmap_start >> PAGE_SHIFT,
167 max_low_pfn);
168
169 /* Add all remaining memory pieces into the bootmem map */
170
171 for (i=0; i<sysmem.nr_banks; i++)
172 free_bootmem(sysmem.bank[i].start,
173 sysmem.bank[i].end - sysmem.bank[i].start);
174
175}
176
177
178void __init paging_init(void)
179{
180 unsigned long zones_size[MAX_NR_ZONES];
181 int i;
182
183 /* All pages are DMA-able, so we put them all in the DMA zone. */
184
185 zones_size[ZONE_DMA] = max_low_pfn;
186 for (i = 1; i < MAX_NR_ZONES; i++)
187 zones_size[i] = 0;
188
189#ifdef CONFIG_HIGHMEM
190 zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
191#endif
192
193 /* Initialize the kernel's page tables. */
194
195 memset(swapper_pg_dir, 0, PAGE_SIZE);
196
197 free_area_init(zones_size);
198}
199
200/*
201 * Flush the mmu and reset associated register to default values.
202 */
203
204void __init init_mmu (void)
205{
206 /* Writing zeros to the <t>TLBCFG special registers ensure
207 * that valid values exist in the register. For existing
208 * PGSZID<w> fields, zero selects the first element of the
209 * page-size array. For nonexistant PGSZID<w> fields, zero is
210 * the best value to write. Also, when changing PGSZID<w>
211 * fields, the corresponding TLB must be flushed.
212 */
213 set_itlbcfg_register (0);
214 set_dtlbcfg_register (0);
215 flush_tlb_all ();
216
217 /* Set rasid register to a known value. */
218
219 set_rasid_register (ASID_ALL_RESERVED);
220
221 /* Set PTEVADDR special register to the start of the page
222 * table, which is in kernel mappable space (ie. not
223 * statically mapped). This register's value is undefined on
224 * reset.
225 */
226 set_ptevaddr_register (PGTABLE_START);
227}
228
229/*
230 * Initialize memory pages.
231 */
232
233void __init mem_init(void)
234{
235 unsigned long codesize, reservedpages, datasize, initsize;
236 unsigned long highmemsize, tmp, ram;
237
238 max_mapnr = num_physpages = max_low_pfn;
239 high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
240 highmemsize = 0;
241
242#if CONFIG_HIGHMEM
243#error HIGHGMEM not implemented in init.c
244#endif
245
246 totalram_pages += free_all_bootmem();
247
248 reservedpages = ram = 0;
249 for (tmp = 0; tmp < max_low_pfn; tmp++) {
250 ram++;
251 if (PageReserved(mem_map+tmp))
252 reservedpages++;
253 }
254
255 codesize = (unsigned long) &_etext - (unsigned long) &_ftext;
256 datasize = (unsigned long) &_edata - (unsigned long) &_fdata;
257 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
258
259 printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
260 "%ldk data, %ldk init %ldk highmem)\n",
261 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
262 ram << (PAGE_SHIFT-10),
263 codesize >> 10,
264 reservedpages << (PAGE_SHIFT-10),
265 datasize >> 10,
266 initsize >> 10,
267 highmemsize >> 10);
268}
269
270void
271free_reserved_mem(void *start, void *end)
272{
273 for (; start < end; start += PAGE_SIZE) {
274 ClearPageReserved(virt_to_page(start));
275 set_page_count(virt_to_page(start), 1);
276 free_page((unsigned long)start);
277 totalram_pages++;
278 }
279}
280
281#ifdef CONFIG_BLK_DEV_INITRD
282extern int initrd_is_mapped;
283
284void free_initrd_mem(unsigned long start, unsigned long end)
285{
286 if (initrd_is_mapped) {
287 free_reserved_mem((void*)start, (void*)end);
288 printk ("Freeing initrd memory: %ldk freed\n",(end-start)>>10);
289 }
290}
291#endif
292
293void free_initmem(void)
294{
295 free_reserved_mem(&__init_begin, &__init_end);
296 printk("Freeing unused kernel memory: %dk freed\n",
297 (&__init_end - &__init_begin) >> 10);
298}
299
300void show_mem(void)
301{
302 int i, free = 0, total = 0, reserved = 0;
303 int shared = 0, cached = 0;
304
305 printk("Mem-info:\n");
306 show_free_areas();
307 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
308 i = max_mapnr;
309 while (i-- > 0) {
310 total++;
311 if (PageReserved(mem_map+i))
312 reserved++;
313 else if (PageSwapCache(mem_map+i))
314 cached++;
315 else if (!page_count(mem_map + i))
316 free++;
317 else
318 shared += page_count(mem_map + i) - 1;
319 }
320 printk("%d pages of RAM\n", total);
321 printk("%d reserved pages\n", reserved);
322 printk("%d pages shared\n", shared);
323 printk("%d pages swap cached\n",cached);
324 printk("%d free pages\n", free);
325}
326
327/* ------------------------------------------------------------------------- */
328
329#if (DCACHE_WAY_SIZE > PAGE_SIZE)
330
331/*
332 * With cache aliasing, the page color of the page in kernel space and user
333 * space might mismatch. We temporarily map the page to a different virtual
334 * address with the same color and clear the page there.
335 */
336
337void clear_user_page(void *kaddr, unsigned long vaddr, struct page* page)
338{
339
340 /* There shouldn't be any entries for this page. */
341
342 __flush_invalidate_dcache_page_phys(__pa(page_address(page)));
343
344 if (!PAGE_COLOR_EQ(vaddr, kaddr)) {
345 unsigned long v, p;
346
347 /* Temporarily map page to DTLB_WAY_DCACHE_ALIAS0. */
348
349 spin_lock(&tlb_lock);
350
351 p = (unsigned long)pte_val((mk_pte(page,PAGE_KERNEL)));
352 kaddr = (void*)PAGE_COLOR_MAP0(vaddr);
353 v = (unsigned long)kaddr | DTLB_WAY_DCACHE_ALIAS0;
354 __asm__ __volatile__("wdtlb %0,%1; dsync" : :"a" (p), "a" (v));
355
356 clear_page(kaddr);
357
358 spin_unlock(&tlb_lock);
359 } else {
360 clear_page(kaddr);
361 }
362
363 /* We need to make sure that i$ and d$ are coherent. */
364
365 clear_bit(PG_cache_clean, &page->flags);
366}
367
368/*
369 * With cache aliasing, we have to make sure that the page color of the page
370 * in kernel space matches that of the virtual user address before we read
371 * the page. If the page color differ, we create a temporary DTLB entry with
372 * the corrent page color and use this 'temporary' address as the source.
373 * We then use the same approach as in clear_user_page and copy the data
374 * to the kernel space and clear the PG_cache_clean bit to synchronize caches
375 * later.
376 *
377 * Note:
378 * Instead of using another 'way' for the temporary DTLB entry, we could
379 * probably use the same entry that points to the kernel address (after
380 * saving the original value and restoring it when we are done).
381 */
382
383void copy_user_page(void* to, void* from, unsigned long vaddr,
384 struct page* to_page)
385{
386 /* There shouldn't be any entries for the new page. */
387
388 __flush_invalidate_dcache_page_phys(__pa(page_address(to_page)));
389
390 spin_lock(&tlb_lock);
391
392 if (!PAGE_COLOR_EQ(vaddr, from)) {
393 unsigned long v, p, t;
394
395 __asm__ __volatile__ ("pdtlb %1,%2; rdtlb1 %0,%1"
396 : "=a"(p), "=a"(t) : "a"(from));
397 from = (void*)PAGE_COLOR_MAP0(vaddr);
398 v = (unsigned long)from | DTLB_WAY_DCACHE_ALIAS0;
399 __asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
400 }
401
402 if (!PAGE_COLOR_EQ(vaddr, to)) {
403 unsigned long v, p;
404
405 p = (unsigned long)pte_val((mk_pte(to_page,PAGE_KERNEL)));
406 to = (void*)PAGE_COLOR_MAP1(vaddr);
407 v = (unsigned long)to | DTLB_WAY_DCACHE_ALIAS1;
408 __asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
409 }
410 copy_page(to, from);
411
412 spin_unlock(&tlb_lock);
413
414 /* We need to make sure that i$ and d$ are coherent. */
415
416 clear_bit(PG_cache_clean, &to_page->flags);
417}
418
419
420
421/*
422 * Any time the kernel writes to a user page cache page, or it is about to
423 * read from a page cache page this routine is called.
424 *
425 * Note:
426 * The kernel currently only provides one architecture bit in the page
427 * flags that we use for I$/D$ coherency. Maybe, in future, we can
428 * use a sepearte bit for deferred dcache aliasing:
429 * If the page is not mapped yet, we only need to set a flag,
430 * if mapped, we need to invalidate the page.
431 */
432// FIXME: we probably need this for WB caches not only for Page Coloring..
433
434void flush_dcache_page(struct page *page)
435{
436 unsigned long addr = __pa(page_address(page));
437 struct address_space *mapping = page_mapping(page);
438
439 __flush_invalidate_dcache_page_phys(addr);
440
441 if (!test_bit(PG_cache_clean, &page->flags))
442 return;
443
444 /* If this page hasn't been mapped, yet, handle I$/D$ coherency later.*/
445#if 0
446 if (mapping && !mapping_mapped(mapping))
447 clear_bit(PG_cache_clean, &page->flags);
448 else
449#endif
450 __invalidate_icache_page_phys(addr);
451}
452
453void flush_cache_range(struct vm_area_struct* vma, unsigned long s,
454 unsigned long e)
455{
456 __flush_invalidate_cache_all();
457}
458
459void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
460 unsigned long pfn)
461{
462 struct page *page = pfn_to_page(pfn);
463
464 /* Remove any entry for the old mapping. */
465
466 if (current->active_mm == vma->vm_mm) {
467 unsigned long addr = __pa(page_address(page));
468 __flush_invalidate_dcache_page_phys(addr);
469 if ((vma->vm_flags & VM_EXEC) != 0)
470 __invalidate_icache_page_phys(addr);
471 } else {
472 BUG();
473 }
474}
475
476#endif /* (DCACHE_WAY_SIZE > PAGE_SIZE) */
477
478
479pte_t* pte_alloc_one_kernel (struct mm_struct* mm, unsigned long addr)
480{
481 pte_t* pte = (pte_t*)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 0);
482 if (likely(pte)) {
483 pte_t* ptep = (pte_t*)(pte_val(*pte) + PAGE_OFFSET);
484 int i;
485 for (i = 0; i < 1024; i++, ptep++)
486 pte_clear(mm, addr, ptep);
487 }
488 return pte;
489}
490
491struct page* pte_alloc_one(struct mm_struct *mm, unsigned long addr)
492{
493 struct page *page;
494
495 page = alloc_pages(GFP_KERNEL | __GFP_REPEAT, 0);
496
497 if (likely(page)) {
498 pte_t* ptep = kmap_atomic(page, KM_USER0);
499 int i;
500
501 for (i = 0; i < 1024; i++, ptep++)
502 pte_clear(mm, addr, ptep);
503
504 kunmap_atomic(ptep, KM_USER0);
505 }
506 return page;
507}
508
509
510/*
511 * Handle D$/I$ coherency.
512 *
513 * Note:
514 * We only have one architecture bit for the page flags, so we cannot handle
515 * cache aliasing, yet.
516 */
517
518void
519update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
520{
521 unsigned long pfn = pte_pfn(pte);
522 struct page *page;
523 unsigned long vaddr = addr & PAGE_MASK;
524
525 if (!pfn_valid(pfn))
526 return;
527
528 page = pfn_to_page(pfn);
529
530 invalidate_itlb_mapping(addr);
531 invalidate_dtlb_mapping(addr);
532
533 /* We have a new mapping. Use it. */
534
535 write_dtlb_entry(pte, dtlb_probe(addr));
536
537 /* If the processor can execute from this page, synchronize D$/I$. */
538
539 if ((vma->vm_flags & VM_EXEC) != 0) {
540
541 write_itlb_entry(pte, itlb_probe(addr));
542
543 /* Synchronize caches, if not clean. */
544
545 if (!test_and_set_bit(PG_cache_clean, &page->flags)) {
546 __flush_dcache_page(vaddr);
547 __invalidate_icache_page(vaddr);
548 }
549 }
550}
551
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
new file mode 100644
index 000000000000..327c0f17187c
--- /dev/null
+++ b/arch/xtensa/mm/misc.S
@@ -0,0 +1,374 @@
1/*
2 * arch/xtensa/mm/misc.S
3 *
4 * Miscellaneous assembly functions.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 */
14
15/* Note: we might want to implement some of the loops as zero-overhead-loops,
16 * where applicable and if supported by the processor.
17 */
18
19#include <linux/linkage.h>
20#include <asm/page.h>
21#include <asm/pgtable.h>
22
23#include <xtensa/cacheasm.h>
24#include <xtensa/cacheattrasm.h>
25
26/* clear_page (page) */
27
28ENTRY(clear_page)
29 entry a1, 16
30 addi a4, a2, PAGE_SIZE
31 movi a3, 0
32
331: s32i a3, a2, 0
34 s32i a3, a2, 4
35 s32i a3, a2, 8
36 s32i a3, a2, 12
37 s32i a3, a2, 16
38 s32i a3, a2, 20
39 s32i a3, a2, 24
40 s32i a3, a2, 28
41 addi a2, a2, 32
42 blt a2, a4, 1b
43
44 retw
45
46/*
47 * copy_page (void *to, void *from)
48 * a2 a3
49 */
50
51ENTRY(copy_page)
52 entry a1, 16
53 addi a4, a2, PAGE_SIZE
54
551: l32i a5, a3, 0
56 l32i a6, a3, 4
57 l32i a7, a3, 8
58 s32i a5, a2, 0
59 s32i a6, a2, 4
60 s32i a7, a2, 8
61 l32i a5, a3, 12
62 l32i a6, a3, 16
63 l32i a7, a3, 20
64 s32i a5, a2, 12
65 s32i a6, a2, 16
66 s32i a7, a2, 20
67 l32i a5, a3, 24
68 l32i a6, a3, 28
69 s32i a5, a2, 24
70 s32i a6, a2, 28
71 addi a2, a2, 32
72 addi a3, a3, 32
73 blt a2, a4, 1b
74
75 retw
76
77
78/*
79 * void __flush_invalidate_cache_all(void)
80 */
81
82ENTRY(__flush_invalidate_cache_all)
83 entry sp, 16
84 dcache_writeback_inv_all a2, a3
85 icache_invalidate_all a2, a3
86 retw
87
88/*
89 * void __invalidate_icache_all(void)
90 */
91
92ENTRY(__invalidate_icache_all)
93 entry sp, 16
94 icache_invalidate_all a2, a3
95 retw
96
97/*
98 * void __flush_invalidate_dcache_all(void)
99 */
100
101ENTRY(__flush_invalidate_dcache_all)
102 entry sp, 16
103 dcache_writeback_inv_all a2, a3
104 retw
105
106
107/*
108 * void __flush_invalidate_cache_range(ulong start, ulong size)
109 */
110
111ENTRY(__flush_invalidate_cache_range)
112 entry sp, 16
113 mov a4, a2
114 mov a5, a3
115 dcache_writeback_inv_region a4, a5, a6
116 icache_invalidate_region a2, a3, a4
117 retw
118
119/*
120 * void __invalidate_icache_page(ulong start)
121 */
122
123ENTRY(__invalidate_icache_page)
124 entry sp, 16
125 movi a3, PAGE_SIZE
126 icache_invalidate_region a2, a3, a4
127 retw
128
129/*
130 * void __invalidate_dcache_page(ulong start)
131 */
132
133ENTRY(__invalidate_dcache_page)
134 entry sp, 16
135 movi a3, PAGE_SIZE
136 dcache_invalidate_region a2, a3, a4
137 retw
138
139/*
140 * void __invalidate_icache_range(ulong start, ulong size)
141 */
142
143ENTRY(__invalidate_icache_range)
144 entry sp, 16
145 icache_invalidate_region a2, a3, a4
146 retw
147
148/*
149 * void __invalidate_dcache_range(ulong start, ulong size)
150 */
151
152ENTRY(__invalidate_dcache_range)
153 entry sp, 16
154 dcache_invalidate_region a2, a3, a4
155 retw
156
157/*
158 * void __flush_dcache_page(ulong start)
159 */
160
161ENTRY(__flush_dcache_page)
162 entry sp, 16
163 movi a3, PAGE_SIZE
164 dcache_writeback_region a2, a3, a4
165 retw
166
167/*
168 * void __flush_invalidate_dcache_page(ulong start)
169 */
170
171ENTRY(__flush_invalidate_dcache_page)
172 entry sp, 16
173 movi a3, PAGE_SIZE
174 dcache_writeback_inv_region a2, a3, a4
175 retw
176
177/*
178 * void __flush_invalidate_dcache_range(ulong start, ulong size)
179 */
180
181ENTRY(__flush_invalidate_dcache_range)
182 entry sp, 16
183 dcache_writeback_inv_region a2, a3, a4
184 retw
185
186/*
187 * void __invalidate_dcache_all(void)
188 */
189
190ENTRY(__invalidate_dcache_all)
191 entry sp, 16
192 dcache_invalidate_all a2, a3
193 retw
194
195/*
196 * void __flush_invalidate_dcache_page_phys(ulong start)
197 */
198
199ENTRY(__flush_invalidate_dcache_page_phys)
200 entry sp, 16
201
202 movi a3, XCHAL_DCACHE_SIZE
203 movi a4, PAGE_MASK | 1
204 addi a2, a2, 1
205
2061: addi a3, a3, -XCHAL_DCACHE_LINESIZE
207
208 ldct a6, a3
209 dsync
210 and a6, a6, a4
211 beq a6, a2, 2f
212 bgeui a3, 2, 1b
213 retw
214
2152: diwbi a3, 0
216 bgeui a3, 2, 1b
217 retw
218
219ENTRY(check_dcache_low0)
220 entry sp, 16
221
222 movi a3, XCHAL_DCACHE_SIZE / 4
223 movi a4, PAGE_MASK | 1
224 addi a2, a2, 1
225
2261: addi a3, a3, -XCHAL_DCACHE_LINESIZE
227
228 ldct a6, a3
229 dsync
230 and a6, a6, a4
231 beq a6, a2, 2f
232 bgeui a3, 2, 1b
233 retw
234
2352: j 2b
236
237ENTRY(check_dcache_high0)
238 entry sp, 16
239
240 movi a5, XCHAL_DCACHE_SIZE / 4
241 movi a3, XCHAL_DCACHE_SIZE / 2
242 movi a4, PAGE_MASK | 1
243 addi a2, a2, 1
244
2451: addi a3, a3, -XCHAL_DCACHE_LINESIZE
246 addi a5, a5, -XCHAL_DCACHE_LINESIZE
247
248 ldct a6, a3
249 dsync
250 and a6, a6, a4
251 beq a6, a2, 2f
252 bgeui a5, 2, 1b
253 retw
254
2552: j 2b
256
257ENTRY(check_dcache_low1)
258 entry sp, 16
259
260 movi a5, XCHAL_DCACHE_SIZE / 4
261 movi a3, XCHAL_DCACHE_SIZE * 3 / 4
262 movi a4, PAGE_MASK | 1
263 addi a2, a2, 1
264
2651: addi a3, a3, -XCHAL_DCACHE_LINESIZE
266 addi a5, a5, -XCHAL_DCACHE_LINESIZE
267
268 ldct a6, a3
269 dsync
270 and a6, a6, a4
271 beq a6, a2, 2f
272 bgeui a5, 2, 1b
273 retw
274
2752: j 2b
276
277ENTRY(check_dcache_high1)
278 entry sp, 16
279
280 movi a5, XCHAL_DCACHE_SIZE / 4
281 movi a3, XCHAL_DCACHE_SIZE
282 movi a4, PAGE_MASK | 1
283 addi a2, a2, 1
284
2851: addi a3, a3, -XCHAL_DCACHE_LINESIZE
286 addi a5, a5, -XCHAL_DCACHE_LINESIZE
287
288 ldct a6, a3
289 dsync
290 and a6, a6, a4
291 beq a6, a2, 2f
292 bgeui a5, 2, 1b
293 retw
294
2952: j 2b
296
297
298/*
299 * void __invalidate_icache_page_phys(ulong start)
300 */
301
302ENTRY(__invalidate_icache_page_phys)
303 entry sp, 16
304
305 movi a3, XCHAL_ICACHE_SIZE
306 movi a4, PAGE_MASK | 1
307 addi a2, a2, 1
308
3091: addi a3, a3, -XCHAL_ICACHE_LINESIZE
310
311 lict a6, a3
312 isync
313 and a6, a6, a4
314 beq a6, a2, 2f
315 bgeui a3, 2, 1b
316 retw
317
3182: iii a3, 0
319 bgeui a3, 2, 1b
320 retw
321
322
323#if 0
324
325 movi a3, XCHAL_DCACHE_WAYS - 1
326 movi a4, PAGE_SIZE
327
3281: mov a5, a2
329 add a6, a2, a4
330
3312: diwbi a5, 0
332 diwbi a5, XCHAL_DCACHE_LINESIZE
333 diwbi a5, XCHAL_DCACHE_LINESIZE * 2
334 diwbi a5, XCHAL_DCACHE_LINESIZE * 3
335
336 addi a5, a5, XCHAL_DCACHE_LINESIZE * 4
337 blt a5, a6, 2b
338
339 addi a3, a3, -1
340 addi a2, a2, XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS
341 bgez a3, 1b
342
343 retw
344
345ENTRY(__invalidate_icache_page_index)
346 entry sp, 16
347
348 movi a3, XCHAL_ICACHE_WAYS - 1
349 movi a4, PAGE_SIZE
350
3511: mov a5, a2
352 add a6, a2, a4
353
3542: iii a5, 0
355 iii a5, XCHAL_ICACHE_LINESIZE
356 iii a5, XCHAL_ICACHE_LINESIZE * 2
357 iii a5, XCHAL_ICACHE_LINESIZE * 3
358
359 addi a5, a5, XCHAL_ICACHE_LINESIZE * 4
360 blt a5, a6, 2b
361
362 addi a3, a3, -1
363 addi a2, a2, XCHAL_ICACHE_SIZE / XCHAL_ICACHE_WAYS
364 bgez a3, 2b
365
366 retw
367
368#endif
369
370
371
372
373
374
diff --git a/arch/xtensa/mm/pgtable.c b/arch/xtensa/mm/pgtable.c
new file mode 100644
index 000000000000..e5e119c820e4
--- /dev/null
+++ b/arch/xtensa/mm/pgtable.c
@@ -0,0 +1,76 @@
1/*
2 * arch/xtensa/mm/fault.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 *
10 * Chris Zankel <chris@zankel.net>
11 */
12
13#if (DCACHE_SIZE > PAGE_SIZE)
14
15pte_t* pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
16{
17 pte_t *pte, p;
18 int color = ADDR_COLOR(address);
19 int i;
20
21 p = (pte_t*) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, COLOR_ORDER);
22
23 if (likely(p)) {
24 struct page *page;
25
26 for (i = 0; i < COLOR_SIZE; i++, p++) {
27 page = virt_to_page(pte);
28
29 set_page_count(page, 1);
30 ClearPageCompound(page);
31
32 if (ADDR_COLOR(p) == color)
33 pte = p;
34 else
35 free_page(p);
36 }
37 clear_page(pte);
38 }
39 return pte;
40}
41
42#ifdef PROFILING
43
44int mask;
45int hit;
46int flush;
47
48#endif
49
50struct page* pte_alloc_one(struct mm_struct *mm, unsigned long address)
51{
52 struct page *page, p;
53 int color = ADDR_COLOR(address);
54
55 p = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
56
57 if (likely(p)) {
58 for (i = 0; i < PAGE_ORDER; i++) {
59 set_page_count(p, 1);
60 ClearPageCompound(p);
61
62 if (PADDR_COLOR(page_address(pg)) == color)
63 page = p;
64 else
65 free_page(p);
66 }
67 clear_highpage(page);
68 }
69
70 return page;
71}
72
73#endif
74
75
76
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c
new file mode 100644
index 000000000000..d3bd3bfc3b3b
--- /dev/null
+++ b/arch/xtensa/mm/tlb.c
@@ -0,0 +1,545 @@
1/*
2 * arch/xtensa/mm/mmu.c
3 *
4 * Logic that manipulates the Xtensa MMU. Derived from MIPS.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2003 Tensilica Inc.
11 *
12 * Joe Taylor
13 * Chris Zankel <chris@zankel.net>
14 * Marc Gauthier
15 */
16
17#include <linux/mm.h>
18#include <asm/processor.h>
19#include <asm/mmu_context.h>
20#include <asm/tlbflush.h>
21#include <asm/system.h>
22#include <asm/cacheflush.h>
23
24
25static inline void __flush_itlb_all (void)
26{
27 int way, index;
28
29 for (way = 0; way < XCHAL_ITLB_ARF_WAYS; way++) {
30 for (index = 0; index < ITLB_ENTRIES_PER_ARF_WAY; index++) {
31 int entry = way + (index << PAGE_SHIFT);
32 invalidate_itlb_entry_no_isync (entry);
33 }
34 }
35 asm volatile ("isync\n");
36}
37
38static inline void __flush_dtlb_all (void)
39{
40 int way, index;
41
42 for (way = 0; way < XCHAL_DTLB_ARF_WAYS; way++) {
43 for (index = 0; index < DTLB_ENTRIES_PER_ARF_WAY; index++) {
44 int entry = way + (index << PAGE_SHIFT);
45 invalidate_dtlb_entry_no_isync (entry);
46 }
47 }
48 asm volatile ("isync\n");
49}
50
51
52void flush_tlb_all (void)
53{
54 __flush_itlb_all();
55 __flush_dtlb_all();
56}
57
58/* If mm is current, we simply assign the current task a new ASID, thus,
59 * invalidating all previous tlb entries. If mm is someone else's user mapping,
60 * wie invalidate the context, thus, when that user mapping is swapped in,
61 * a new context will be assigned to it.
62 */
63
64void flush_tlb_mm(struct mm_struct *mm)
65{
66#if 0
67 printk("[tlbmm<%lx>]\n", (unsigned long)mm->context);
68#endif
69
70 if (mm == current->active_mm) {
71 int flags;
72 local_save_flags(flags);
73 get_new_mmu_context(mm, asid_cache);
74 set_rasid_register(ASID_INSERT(mm->context));
75 local_irq_restore(flags);
76 }
77 else
78 mm->context = 0;
79}
80
81void flush_tlb_range (struct vm_area_struct *vma,
82 unsigned long start, unsigned long end)
83{
84 struct mm_struct *mm = vma->vm_mm;
85 unsigned long flags;
86
87 if (mm->context == NO_CONTEXT)
88 return;
89
90#if 0
91 printk("[tlbrange<%02lx,%08lx,%08lx>]\n",
92 (unsigned long)mm->context, start, end);
93#endif
94 local_save_flags(flags);
95
96 if (end-start + (PAGE_SIZE-1) <= SMALLEST_NTLB_ENTRIES << PAGE_SHIFT) {
97 int oldpid = get_rasid_register();
98 set_rasid_register (ASID_INSERT(mm->context));
99 start &= PAGE_MASK;
100 if (vma->vm_flags & VM_EXEC)
101 while(start < end) {
102 invalidate_itlb_mapping(start);
103 invalidate_dtlb_mapping(start);
104 start += PAGE_SIZE;
105 }
106 else
107 while(start < end) {
108 invalidate_dtlb_mapping(start);
109 start += PAGE_SIZE;
110 }
111
112 set_rasid_register(oldpid);
113 } else {
114 get_new_mmu_context(mm, asid_cache);
115 if (mm == current->active_mm)
116 set_rasid_register(ASID_INSERT(mm->context));
117 }
118 local_irq_restore(flags);
119}
120
121void flush_tlb_page (struct vm_area_struct *vma, unsigned long page)
122{
123 struct mm_struct* mm = vma->vm_mm;
124 unsigned long flags;
125 int oldpid;
126#if 0
127 printk("[tlbpage<%02lx,%08lx>]\n",
128 (unsigned long)mm->context, page);
129#endif
130
131 if(mm->context == NO_CONTEXT)
132 return;
133
134 local_save_flags(flags);
135
136 oldpid = get_rasid_register();
137
138 if (vma->vm_flags & VM_EXEC)
139 invalidate_itlb_mapping(page);
140 invalidate_dtlb_mapping(page);
141
142 set_rasid_register(oldpid);
143
144 local_irq_restore(flags);
145
146#if 0
147 flush_tlb_all();
148 return;
149#endif
150}
151
152
153#ifdef DEBUG_TLB
154
155#define USE_ITLB 0
156#define USE_DTLB 1
157
158struct way_config_t {
159 int indicies;
160 int indicies_log2;
161 int pgsz_log2;
162 int arf;
163};
164
165static struct way_config_t itlb[XCHAL_ITLB_WAYS] =
166{
167 { XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES),
168 XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES_LOG2),
169 XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, PAGESZ_LOG2_MIN),
170 XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ARF)
171 },
172 { XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES),
173 XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES_LOG2),
174 XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, PAGESZ_LOG2_MIN),
175 XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ARF)
176 },
177 { XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES),
178 XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES_LOG2),
179 XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, PAGESZ_LOG2_MIN),
180 XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ARF)
181 },
182 { XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES),
183 XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES_LOG2),
184 XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, PAGESZ_LOG2_MIN),
185 XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ARF)
186 },
187 { XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES),
188 XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES_LOG2),
189 XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, PAGESZ_LOG2_MIN),
190 XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ARF)
191 },
192 { XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES),
193 XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES_LOG2),
194 XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, PAGESZ_LOG2_MIN),
195 XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ARF)
196 },
197 { XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES),
198 XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES_LOG2),
199 XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, PAGESZ_LOG2_MIN),
200 XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ARF)
201 }
202};
203
204static struct way_config_t dtlb[XCHAL_DTLB_WAYS] =
205{
206 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES),
207 XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES_LOG2),
208 XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, PAGESZ_LOG2_MIN),
209 XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ARF)
210 },
211 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES),
212 XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES_LOG2),
213 XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, PAGESZ_LOG2_MIN),
214 XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ARF)
215 },
216 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES),
217 XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES_LOG2),
218 XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, PAGESZ_LOG2_MIN),
219 XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ARF)
220 },
221 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES),
222 XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES_LOG2),
223 XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, PAGESZ_LOG2_MIN),
224 XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ARF)
225 },
226 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES),
227 XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES_LOG2),
228 XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, PAGESZ_LOG2_MIN),
229 XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ARF)
230 },
231 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES),
232 XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES_LOG2),
233 XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, PAGESZ_LOG2_MIN),
234 XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ARF)
235 },
236 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES),
237 XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES_LOG2),
238 XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, PAGESZ_LOG2_MIN),
239 XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ARF)
240 },
241 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES),
242 XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES_LOG2),
243 XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, PAGESZ_LOG2_MIN),
244 XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ARF)
245 },
246 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES),
247 XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES_LOG2),
248 XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, PAGESZ_LOG2_MIN),
249 XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ARF)
250 },
251 { XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES),
252 XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES_LOG2),
253 XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, PAGESZ_LOG2_MIN),
254 XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ARF)
255 }
256};
257
258/* Total number of entries: */
259#define ITLB_TOTAL_ENTRIES \
260 XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES) + \
261 XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES) + \
262 XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES) + \
263 XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES) + \
264 XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES) + \
265 XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES) + \
266 XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES)
267#define DTLB_TOTAL_ENTRIES \
268 XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES) + \
269 XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES) + \
270 XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES) + \
271 XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES) + \
272 XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES) + \
273 XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES) + \
274 XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES) + \
275 XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES) + \
276 XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES) + \
277 XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES)
278
279
280typedef struct {
281 unsigned va;
282 unsigned pa;
283 unsigned char asid;
284 unsigned char ca;
285 unsigned char way;
286 unsigned char index;
287 unsigned char pgsz_log2; /* 0 .. 32 */
288 unsigned char type; /* 0=ITLB 1=DTLB */
289} tlb_dump_entry_t;
290
291/* Return -1 if a precedes b, +1 if a follows b, 0 if same: */
292int cmp_tlb_dump_info( tlb_dump_entry_t *a, tlb_dump_entry_t *b )
293{
294 if (a->asid < b->asid) return -1;
295 if (a->asid > b->asid) return 1;
296 if (a->va < b->va) return -1;
297 if (a->va > b->va) return 1;
298 if (a->pa < b->pa) return -1;
299 if (a->pa > b->pa) return 1;
300 if (a->ca < b->ca) return -1;
301 if (a->ca > b->ca) return 1;
302 if (a->way < b->way) return -1;
303 if (a->way > b->way) return 1;
304 if (a->index < b->index) return -1;
305 if (a->index > b->index) return 1;
306 return 0;
307}
308
309void sort_tlb_dump_info( tlb_dump_entry_t *t, int n )
310{
311 int i, j;
312 /* Simple O(n*n) sort: */
313 for (i = 0; i < n-1; i++)
314 for (j = i+1; j < n; j++)
315 if (cmp_tlb_dump_info(t+i, t+j) > 0) {
316 tlb_dump_entry_t tmp = t[i];
317 t[i] = t[j];
318 t[j] = tmp;
319 }
320}
321
322
323static tlb_dump_entry_t itlb_dump_info[ITLB_TOTAL_ENTRIES];
324static tlb_dump_entry_t dtlb_dump_info[DTLB_TOTAL_ENTRIES];
325
326
327static inline char *way_type (int type)
328{
329 return type ? "autorefill" : "non-autorefill";
330}
331
332void print_entry (struct way_config_t *way_info,
333 unsigned int way,
334 unsigned int index,
335 unsigned int virtual,
336 unsigned int translation)
337{
338 char valid_chr;
339 unsigned int va, pa, asid, ca;
340
341 va = virtual &
342 ~((1 << (way_info->pgsz_log2 + way_info->indicies_log2)) - 1);
343 asid = virtual & ((1 << XCHAL_MMU_ASID_BITS) - 1);
344 pa = translation & ~((1 << way_info->pgsz_log2) - 1);
345 ca = translation & ((1 << XCHAL_MMU_CA_BITS) - 1);
346 valid_chr = asid ? 'V' : 'I';
347
348 /* Compute and incorporate the effect of the index bits on the
349 * va. It's more useful for kernel debugging, since we always
350 * want to know the effective va anyway. */
351
352 va += index << way_info->pgsz_log2;
353
354 printk ("\t[%d,%d] (%c) vpn 0x%.8x ppn 0x%.8x asid 0x%.2x am 0x%x\n",
355 way, index, valid_chr, va, pa, asid, ca);
356}
357
358void print_itlb_entry (struct way_config_t *way_info, int way, int index)
359{
360 print_entry (way_info, way, index,
361 read_itlb_virtual (way + (index << way_info->pgsz_log2)),
362 read_itlb_translation (way + (index << way_info->pgsz_log2)));
363}
364
365void print_dtlb_entry (struct way_config_t *way_info, int way, int index)
366{
367 print_entry (way_info, way, index,
368 read_dtlb_virtual (way + (index << way_info->pgsz_log2)),
369 read_dtlb_translation (way + (index << way_info->pgsz_log2)));
370}
371
372void dump_itlb (void)
373{
374 int way, index;
375
376 printk ("\nITLB: ways = %d\n", XCHAL_ITLB_WAYS);
377
378 for (way = 0; way < XCHAL_ITLB_WAYS; way++) {
379 printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n",
380 way, itlb[way].indicies,
381 itlb[way].pgsz_log2, way_type(itlb[way].arf));
382 for (index = 0; index < itlb[way].indicies; index++) {
383 print_itlb_entry(&itlb[way], way, index);
384 }
385 }
386}
387
388void dump_dtlb (void)
389{
390 int way, index;
391
392 printk ("\nDTLB: ways = %d\n", XCHAL_DTLB_WAYS);
393
394 for (way = 0; way < XCHAL_DTLB_WAYS; way++) {
395 printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n",
396 way, dtlb[way].indicies,
397 dtlb[way].pgsz_log2, way_type(dtlb[way].arf));
398 for (index = 0; index < dtlb[way].indicies; index++) {
399 print_dtlb_entry(&dtlb[way], way, index);
400 }
401 }
402}
403
404void dump_tlb (tlb_dump_entry_t *tinfo, struct way_config_t *config,
405 int entries, int ways, int type, int show_invalid)
406{
407 tlb_dump_entry_t *e = tinfo;
408 int way, i;
409
410 /* Gather all info: */
411 for (way = 0; way < ways; way++) {
412 struct way_config_t *cfg = config + way;
413 for (i = 0; i < cfg->indicies; i++) {
414 unsigned wayindex = way + (i << cfg->pgsz_log2);
415 unsigned vv = (type ? read_dtlb_virtual (wayindex)
416 : read_itlb_virtual (wayindex));
417 unsigned pp = (type ? read_dtlb_translation (wayindex)
418 : read_itlb_translation (wayindex));
419
420 /* Compute and incorporate the effect of the index bits on the
421 * va. It's more useful for kernel debugging, since we always
422 * want to know the effective va anyway. */
423
424 e->va = (vv & ~((1 << (cfg->pgsz_log2 + cfg->indicies_log2)) - 1));
425 e->va += (i << cfg->pgsz_log2);
426 e->pa = (pp & ~((1 << cfg->pgsz_log2) - 1));
427 e->asid = (vv & ((1 << XCHAL_MMU_ASID_BITS) - 1));
428 e->ca = (pp & ((1 << XCHAL_MMU_CA_BITS) - 1));
429 e->way = way;
430 e->index = i;
431 e->pgsz_log2 = cfg->pgsz_log2;
432 e->type = type;
433 e++;
434 }
435 }
436#if 1
437 /* Sort by ASID and VADDR: */
438 sort_tlb_dump_info (tinfo, entries);
439#endif
440
441 /* Display all sorted info: */
442 printk ("\n%cTLB dump:\n", (type ? 'D' : 'I'));
443 for (e = tinfo, i = 0; i < entries; i++, e++) {
444#if 0
445 if (e->asid == 0 && !show_invalid)
446 continue;
447#endif
448 printk ("%c way=%d i=%d ASID=%02X V=%08X -> P=%08X CA=%X (%d %cB)\n",
449 (e->type ? 'D' : 'I'), e->way, e->index,
450 e->asid, e->va, e->pa, e->ca,
451 (1 << (e->pgsz_log2 % 10)),
452 " kMG"[e->pgsz_log2 / 10]
453 );
454 }
455}
456
457void dump_tlbs2 (int showinv)
458{
459 dump_tlb (itlb_dump_info, itlb, ITLB_TOTAL_ENTRIES, XCHAL_ITLB_WAYS, 0, showinv);
460 dump_tlb (dtlb_dump_info, dtlb, DTLB_TOTAL_ENTRIES, XCHAL_DTLB_WAYS, 1, showinv);
461}
462
463void dump_all_tlbs (void)
464{
465 dump_tlbs2 (1);
466}
467
468void dump_valid_tlbs (void)
469{
470 dump_tlbs2 (0);
471}
472
473
474void dump_tlbs (void)
475{
476 dump_itlb();
477 dump_dtlb();
478}
479
480void dump_cache_tag(int dcache, int idx)
481{
482 int w, i, s, e;
483 unsigned long tag, index;
484 unsigned long num_lines, num_ways, cache_size, line_size;
485
486 num_ways = dcache ? XCHAL_DCACHE_WAYS : XCHAL_ICACHE_WAYS;
487 cache_size = dcache ? XCHAL_DCACHE_SIZE : XCHAL_ICACHE_SIZE;
488 line_size = dcache ? XCHAL_DCACHE_LINESIZE : XCHAL_ICACHE_LINESIZE;
489
490 num_lines = cache_size / num_ways;
491
492 s = 0; e = num_lines;
493
494 if (idx >= 0)
495 e = (s = idx * line_size) + 1;
496
497 for (i = s; i < e; i+= line_size) {
498 printk("\nline %#08x:", i);
499 for (w = 0; w < num_ways; w++) {
500 index = w * num_lines + i;
501 if (dcache)
502 __asm__ __volatile__("ldct %0, %1\n\t"
503 : "=a"(tag) : "a"(index));
504 else
505 __asm__ __volatile__("lict %0, %1\n\t"
506 : "=a"(tag) : "a"(index));
507
508 printk(" %#010lx", tag);
509 }
510 }
511 printk ("\n");
512}
513
514void dump_icache(int index)
515{
516 unsigned long data, addr;
517 int w, i;
518
519 const unsigned long num_ways = XCHAL_ICACHE_WAYS;
520 const unsigned long cache_size = XCHAL_ICACHE_SIZE;
521 const unsigned long line_size = XCHAL_ICACHE_LINESIZE;
522 const unsigned long num_lines = cache_size / num_ways / line_size;
523
524 for (w = 0; w < num_ways; w++) {
525 printk ("\nWay %d", w);
526
527 for (i = 0; i < line_size; i+= 4) {
528 addr = w * num_lines + index * line_size + i;
529 __asm__ __volatile__("licw %0, %1\n\t"
530 : "=a"(data) : "a"(addr));
531 printk(" %#010lx", data);
532 }
533 }
534 printk ("\n");
535}
536
537void dump_cache_tags(void)
538{
539 printk("Instruction cache\n");
540 dump_cache_tag(0, -1);
541 printk("Data cache\n");
542 dump_cache_tag(1, -1);
543}
544
545#endif
diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platform-iss/Makefile
new file mode 100644
index 000000000000..5b394e9620e5
--- /dev/null
+++ b/arch/xtensa/platform-iss/Makefile
@@ -0,0 +1,13 @@
1# $Id: Makefile,v 1.1.1.1 2002/08/28 16:10:14 aroll Exp $
2#
3# Makefile for the Xtensa Instruction Set Simulator (ISS)
4# "prom monitor" library routines under Linux.
5#
6# Note! Dependencies are done automagically by 'make dep', which also
7# removes any old dependencies. DON'T put your own dependencies here
8# unless it's something special (ie not a .c file).
9#
10# Note 2! The CFLAGS definitions are in the main makefile...
11
12obj-y = io.o console.o setup.o network.o
13
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c
new file mode 100644
index 000000000000..9e2b53f6a907
--- /dev/null
+++ b/arch/xtensa/platform-iss/console.c
@@ -0,0 +1,303 @@
1/*
2 * arch/xtensa/platform-iss/console.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001-2005 Tensilica Inc.
9 * Authors Christian Zankel, Joe Taylor
10 */
11
12#include <linux/module.h>
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/sched.h>
16#include <linux/console.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/mm.h>
20#include <linux/major.h>
21#include <linux/param.h>
22#include <linux/serial.h>
23#include <linux/serialP.h>
24#include <linux/console.h>
25
26#include <asm/uaccess.h>
27#include <asm/irq.h>
28
29#include <xtensa/simcall.h>
30
31#include <linux/tty.h>
32#include <linux/tty_flip.h>
33
34#ifdef SERIAL_INLINE
35#define _INLINE_ inline
36#endif
37
38#define SERIAL_MAX_NUM_LINES 1
39#define SERIAL_TIMER_VALUE (20 * HZ)
40
41static struct tty_driver *serial_driver;
42static struct timer_list serial_timer;
43
44static DEFINE_SPINLOCK(timer_lock);
45
46int errno;
47
48static int __simc (int a, int b, int c, int d, int e, int f)
49{
50 int ret;
51 __asm__ __volatile__ ("simcall\n"
52 "mov %0, a2\n"
53 "mov %1, a3\n" : "=a" (ret), "=a" (errno)
54 : : "a2", "a3");
55 return ret;
56}
57
58static char *serial_version = "0.1";
59static char *serial_name = "ISS serial driver";
60
61/*
62 * This routine is called whenever a serial port is opened. It
63 * enables interrupts for a serial port, linking in its async structure into
64 * the IRQ chain. It also performs the serial-specific
65 * initialization for the tty structure.
66 */
67
68static void rs_poll(unsigned long);
69
70static int rs_open(struct tty_struct *tty, struct file * filp)
71{
72 int line = tty->index;
73
74 if ((line < 0) || (line >= SERIAL_MAX_NUM_LINES))
75 return -ENODEV;
76
77 spin_lock(&timer_lock);
78
79 if (tty->count == 1) {
80 init_timer(&serial_timer);
81 serial_timer.data = (unsigned long) tty;
82 serial_timer.function = rs_poll;
83 mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
84 }
85 spin_unlock(&timer_lock);
86
87 return 0;
88}
89
90
91/*
92 * ------------------------------------------------------------
93 * iss_serial_close()
94 *
95 * This routine is called when the serial port gets closed. First, we
96 * wait for the last remaining data to be sent. Then, we unlink its
97 * async structure from the interrupt chain if necessary, and we free
98 * that IRQ if nothing is left in the chain.
99 * ------------------------------------------------------------
100 */
101static void rs_close(struct tty_struct *tty, struct file * filp)
102{
103 spin_lock(&timer_lock);
104 if (tty->count == 1)
105 del_timer_sync(&serial_timer);
106 spin_unlock(&timer_lock);
107}
108
109
110static int rs_write(struct tty_struct * tty,
111 const unsigned char *buf, int count)
112{
113 /* see drivers/char/serialX.c to reference original version */
114
115 __simc (SYS_write, 1, (unsigned long)buf, count, 0, 0);
116 return count;
117}
118
119static void rs_poll(unsigned long priv)
120{
121 struct tty_struct* tty = (struct tty_struct*) priv;
122
123 struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
124 int i = 0;
125 unsigned char c;
126
127 spin_lock(&timer_lock);
128
129 while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){
130 __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0);
131 tty->flip.count++;
132 *tty->flip.char_buf_ptr++ = c;
133 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
134 i++;
135 }
136
137 if (i)
138 tty_flip_buffer_push(tty);
139
140
141 mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
142 spin_unlock(&timer_lock);
143}
144
145
146static void rs_put_char(struct tty_struct *tty, unsigned char ch)
147{
148 char buf[2];
149
150 if (!tty)
151 return;
152
153 buf[0] = ch;
154 buf[1] = '\0'; /* Is this NULL necessary? */
155 __simc (SYS_write, 1, (unsigned long) buf, 1, 0, 0);
156}
157
158static void rs_flush_chars(struct tty_struct *tty)
159{
160}
161
162static int rs_write_room(struct tty_struct *tty)
163{
164 /* Let's say iss can always accept 2K characters.. */
165 return 2 * 1024;
166}
167
168static int rs_chars_in_buffer(struct tty_struct *tty)
169{
170 /* the iss doesn't buffer characters */
171 return 0;
172}
173
174static void rs_hangup(struct tty_struct *tty)
175{
176 /* Stub, once again.. */
177}
178
179static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
180{
181 /* Stub, once again.. */
182}
183
184static int rs_read_proc(char *page, char **start, off_t off, int count,
185 int *eof, void *data)
186{
187 int len = 0;
188 off_t begin = 0;
189
190 len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
191 *eof = 1;
192
193 if (off >= len + begin)
194 return 0;
195
196 *start = page + (off - begin);
197 return ((count < begin + len - off) ? count : begin + len - off);
198}
199
200
201int register_serial(struct serial_struct*);
202void unregister_serial(int);
203
204static struct tty_operations serial_ops = {
205 .open = rs_open,
206 .close = rs_close,
207 .write = rs_write,
208 .put_char = rs_put_char,
209 .flush_chars = rs_flush_chars,
210 .write_room = rs_write_room,
211 .chars_in_buffer = rs_chars_in_buffer,
212 .hangup = rs_hangup,
213 .wait_until_sent = rs_wait_until_sent,
214 .read_proc = rs_read_proc
215};
216
217int __init rs_init(void)
218{
219 serial_driver = alloc_tty_driver(1);
220
221 printk ("%s %s\n", serial_name, serial_version);
222
223 /* Initialize the tty_driver structure */
224
225 serial_driver->owner = THIS_MODULE;
226 serial_driver->driver_name = "iss_serial";
227 serial_driver->name = "ttyS";
228 serial_driver->major = TTY_MAJOR;
229 serial_driver->minor_start = 64;
230 serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
231 serial_driver->subtype = SERIAL_TYPE_NORMAL;
232 serial_driver->init_termios = tty_std_termios;
233 serial_driver->init_termios.c_cflag =
234 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
235 serial_driver->flags = TTY_DRIVER_REAL_RAW;
236
237 tty_set_operations(serial_driver, &serial_ops);
238
239 if (tty_register_driver(serial_driver))
240 panic("Couldn't register serial driver\n");
241 return 0;
242}
243
244
245static __exit void rs_exit(void)
246{
247 int error;
248
249 if ((error = tty_unregister_driver(serial_driver)))
250 printk("ISS_SERIAL: failed to unregister serial driver (%d)\n",
251 error);
252 put_tty_driver(serial_driver);
253}
254
255
256/* We use `late_initcall' instead of just `__initcall' as a workaround for
257 * the fact that (1) simcons_tty_init can't be called before tty_init,
258 * (2) tty_init is called via `module_init', (3) if statically linked,
259 * module_init == device_init, and (4) there's no ordering of init lists.
260 * We can do this easily because simcons is always statically linked, but
261 * other tty drivers that depend on tty_init and which must use
262 * `module_init' to declare their init routines are likely to be broken.
263 */
264
265late_initcall(rs_init);
266
267
268#ifdef CONFIG_SERIAL_CONSOLE
269
270static void iss_console_write(struct console *co, const char *s, unsigned count)
271{
272 int len = strlen(s);
273
274 if (s != 0 && *s != 0)
275 __simc (SYS_write, 1, (unsigned long)s,
276 count < len ? count : len,0,0);
277}
278
279static struct tty_driver* iss_console_device(struct console *c, int *index)
280{
281 *index = c->index;
282 return serial_driver;
283}
284
285
286static struct console sercons = {
287 .name = "ttyS",
288 .write = iss_console_write,
289 .device = iss_console_device,
290 .flags = CON_PRINTBUFFER,
291 .index = -1
292};
293
294static int __init iss_console_init(void)
295{
296 register_console(&sercons);
297 return 0;
298}
299
300console_initcall(iss_console_init);
301
302#endif /* CONFIG_SERIAL_CONSOLE */
303
diff --git a/arch/xtensa/platform-iss/io.c b/arch/xtensa/platform-iss/io.c
new file mode 100644
index 000000000000..5b161a5cb65f
--- /dev/null
+++ b/arch/xtensa/platform-iss/io.c
@@ -0,0 +1,32 @@
1/* This file isn't really needed right now. */
2
3#if 0
4
5#include <asm/io.h>
6#include <xtensa/simcall.h>
7
8extern int __simc ();
9
10
11char iss_serial_getc()
12{
13 char c;
14 __simc( SYS_read, 0, &c, 1 );
15 return c;
16}
17
18void iss_serial_putc( char c )
19{
20 __simc( SYS_write, 1, &c, 1 );
21}
22
23void iss_serial_puts( char *s )
24{
25 if( s != 0 && *s != 0 )
26 __simc( SYS_write, 1, s, strlen(s) );
27}
28
29/*#error Need I/O ports to specific hardware!*/
30
31#endif
32
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
new file mode 100644
index 000000000000..498d7dced1f4
--- /dev/null
+++ b/arch/xtensa/platform-iss/network.c
@@ -0,0 +1,855 @@
1/*
2 *
3 * arch/xtensa/platform-iss/network.c
4 *
5 * Platform specific initialization.
6 *
7 * Authors: Chris Zankel <chris@zankel.net>
8 * Based on work form the UML team.
9 *
10 * Copyright 2005 Tensilica Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 */
18
19#include <linux/config.h>
20#include <linux/list.h>
21#include <linux/irq.h>
22#include <linux/spinlock.h>
23#include <linux/slab.h>
24#include <linux/timer.h>
25#include <linux/if_ether.h>
26#include <linux/inetdevice.h>
27#include <linux/init.h>
28#include <linux/if_tun.h>
29#include <linux/etherdevice.h>
30#include <linux/interrupt.h>
31#include <linux/ioctl.h>
32#include <linux/bootmem.h>
33#include <linux/ethtool.h>
34#include <linux/rtnetlink.h>
35#include <linux/timer.h>
36
37#include <xtensa/simcall.h>
38
39#define DRIVER_NAME "iss-netdev"
40#define ETH_MAX_PACKET 1500
41#define ETH_HEADER_OTHER 14
42#define ISS_NET_TIMER_VALUE (2 * HZ)
43
44
45static DEFINE_SPINLOCK(opened_lock);
46static LIST_HEAD(opened);
47
48static DEFINE_SPINLOCK(devices_lock);
49static LIST_HEAD(devices);
50
51/* ------------------------------------------------------------------------- */
52
53/* We currently only support the TUNTAP transport protocol. */
54
55#define TRANSPORT_TUNTAP_NAME "tuntap"
56#define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET
57
58struct tuntap_info {
59 char dev_name[IFNAMSIZ];
60 int fixed_config;
61 unsigned char gw[ETH_ALEN];
62 int fd;
63};
64
65/* ------------------------------------------------------------------------- */
66
67
68/* This structure contains out private information for the driver. */
69
70struct iss_net_private {
71
72 struct list_head device_list;
73 struct list_head opened_list;
74
75 spinlock_t lock;
76 struct net_device *dev;
77 struct platform_device pdev;
78 struct timer_list tl;
79 struct net_device_stats stats;
80
81 struct timer_list timer;
82 unsigned int timer_val;
83
84 int index;
85 int mtu;
86
87 unsigned char mac[ETH_ALEN];
88 int have_mac;
89
90 struct {
91 union {
92 struct tuntap_info tuntap;
93 } info;
94
95 int (*open)(struct iss_net_private *lp);
96 void (*close)(struct iss_net_private *lp);
97 int (*read)(struct iss_net_private *lp, struct sk_buff **skb);
98 int (*write)(struct iss_net_private *lp, struct sk_buff **skb);
99 unsigned short (*protocol)(struct sk_buff *skb);
100 int (*poll)(struct iss_net_private *lp);
101 } tp;
102
103};
104
105/* ======================= ISS SIMCALL INTERFACE =========================== */
106
107/* Note: __simc must _not_ be declared inline! */
108
109static int errno;
110
111static int __simc (int a, int b, int c, int d, int e, int f)
112{
113 int ret;
114 __asm__ __volatile__ ("simcall\n"
115 "mov %0, a2\n"
116 "mov %1, a3\n" : "=a" (ret), "=a" (errno)
117 : : "a2", "a3");
118 return ret;
119}
120
121static int inline simc_open(char *file, int flags, int mode)
122{
123 return __simc(SYS_open, (int) file, flags, mode, 0, 0);
124}
125
126static int inline simc_close(int fd)
127{
128 return __simc(SYS_close, fd, 0, 0, 0, 0);
129}
130
131static int inline simc_ioctl(int fd, int request, void *arg)
132{
133 return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
134}
135
136static int inline simc_read(int fd, void *buf, size_t count)
137{
138 return __simc(SYS_read, fd, (int) buf, count, 0, 0);
139}
140
141static int inline simc_write(int fd, void *buf, size_t count)
142{
143 return __simc(SYS_write, fd, (int) buf, count, 0, 0);
144}
145
146static int inline simc_poll(int fd)
147{
148 struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
149
150 return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,0,0);
151}
152
153/* ================================ HELPERS ================================ */
154
155
156static char *split_if_spec(char *str, ...)
157{
158 char **arg, *end;
159 va_list ap;
160
161 va_start(ap, str);
162 while ((arg = va_arg(ap, char**)) != NULL) {
163 if (*str == '\0')
164 return NULL;
165 end = strchr(str, ',');
166 if (end != str)
167 *arg = str;
168 if (end == NULL)
169 return NULL;
170 *end ++ = '\0';
171 str = end;
172 }
173 va_end(ap);
174 return str;
175}
176
177
178#if 0
179/* Adjust SKB. */
180
181struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
182{
183 if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
184 struct sk_buff *skb2;
185
186 skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
187 dev_kfree_skb(skb);
188 skb = skb2;
189 }
190 if (skb != NULL)
191 skb_put(skb, extra);
192
193 return skb;
194}
195#endif
196
197/* Return the IP address as a string for a given device. */
198
199static void dev_ip_addr(void *d, char *buf, char *bin_buf)
200{
201 struct net_device *dev = d;
202 struct in_device *ip = dev->ip_ptr;
203 struct in_ifaddr *in;
204 u32 addr;
205
206 if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
207 printk(KERN_WARNING "Device not assigned an IP address!\n");
208 return;
209 }
210
211 addr = in->ifa_address;
212 sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
213 (addr >> 16) & 0xff, addr >> 24);
214
215 if (bin_buf) {
216 bin_buf[0] = addr & 0xff;
217 bin_buf[1] = (addr >> 8) & 0xff;
218 bin_buf[2] = (addr >> 16) & 0xff;
219 bin_buf[3] = addr >> 24;
220 }
221}
222
223/* Set Ethernet address of the specified device. */
224
225static void inline set_ether_mac(void *d, unsigned char *addr)
226{
227 struct net_device *dev = d;
228 memcpy(dev->dev_addr, addr, ETH_ALEN);
229}
230
231
232/* ======================= TUNTAP TRANSPORT INTERFACE ====================== */
233
234static int tuntap_open(struct iss_net_private *lp)
235{
236 struct ifreq ifr;
237 char *dev_name = lp->tp.info.tuntap.dev_name;
238 int err = -EINVAL;
239 int fd;
240
241 /* We currently only support a fixed configuration. */
242
243 if (!lp->tp.info.tuntap.fixed_config)
244 return -EINVAL;
245
246 if ((fd = simc_open("/dev/net/tun", 02, 0)) < 0) { /* O_RDWR */
247 printk("Failed to open /dev/net/tun, returned %d "
248 "(errno = %d)\n", fd, errno);
249 return fd;
250 }
251
252 memset(&ifr, 0, sizeof ifr);
253 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
254 strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name - 1);
255
256 if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
257 printk("Failed to set interface, returned %d "
258 "(errno = %d)\n", err, errno);
259 simc_close(fd);
260 return err;
261 }
262
263 lp->tp.info.tuntap.fd = fd;
264 return err;
265}
266
267static void tuntap_close(struct iss_net_private *lp)
268{
269#if 0
270 if (lp->tp.info.tuntap.fixed_config)
271 iter_addresses(lp->tp.info.tuntap.dev, close_addr, lp->host.dev_name);
272#endif
273 simc_close(lp->tp.info.tuntap.fd);
274 lp->tp.info.tuntap.fd = -1;
275}
276
277static int tuntap_read (struct iss_net_private *lp, struct sk_buff **skb)
278{
279#if 0
280 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
281 if (*skb == NULL)
282 return -ENOMEM;
283#endif
284
285 return simc_read(lp->tp.info.tuntap.fd,
286 (*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER);
287}
288
289static int tuntap_write (struct iss_net_private *lp, struct sk_buff **skb)
290{
291 return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
292}
293
294unsigned short tuntap_protocol(struct sk_buff *skb)
295{
296 return eth_type_trans(skb, skb->dev);
297}
298
299static int tuntap_poll(struct iss_net_private *lp)
300{
301 return simc_poll(lp->tp.info.tuntap.fd);
302}
303
304/*
305 * Currently only a device name is supported.
306 * ethX=tuntap[,[mac address][,[device name]]]
307 */
308
309static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
310{
311 const int len = strlen(TRANSPORT_TUNTAP_NAME);
312 char *dev_name = NULL, *mac_str = NULL, *rem = NULL;
313
314 /* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */
315
316 if (strncmp(init, TRANSPORT_TUNTAP_NAME, len))
317 return 0;
318
319 if (*(init += strlen(TRANSPORT_TUNTAP_NAME)) == ',') {
320 if ((rem=split_if_spec(init+1, &mac_str, &dev_name)) != NULL) {
321 printk("Extra garbage on specification : '%s'\n", rem);
322 return 0;
323 }
324 } else if (*init != '\0') {
325 printk("Invalid argument: %s. Skipping device!\n", init);
326 return 0;
327 }
328
329 if (dev_name) {
330 strncpy(lp->tp.info.tuntap.dev_name, dev_name,
331 sizeof lp->tp.info.tuntap.dev_name);
332 lp->tp.info.tuntap.fixed_config = 1;
333 } else
334 strcpy(lp->tp.info.tuntap.dev_name, TRANSPORT_TUNTAP_NAME);
335
336
337#if 0
338 if (setup_etheraddr(mac_str, lp->mac))
339 lp->have_mac = 1;
340#endif
341 lp->mtu = TRANSPORT_TUNTAP_MTU;
342
343 //lp->info.tuntap.gate_addr = gate_addr;
344
345 lp->tp.info.tuntap.fd = -1;
346
347 lp->tp.open = tuntap_open;
348 lp->tp.close = tuntap_close;
349 lp->tp.read = tuntap_read;
350 lp->tp.write = tuntap_write;
351 lp->tp.protocol = tuntap_protocol;
352 lp->tp.poll = tuntap_poll;
353
354 printk("TUN/TAP backend - ");
355#if 0
356 if (lp->host.gate_addr != NULL)
357 printk("IP = %s", lp->host.gate_addr);
358#endif
359 printk("\n");
360
361 return 1;
362}
363
364/* ================================ ISS NET ================================ */
365
366static int iss_net_rx(struct net_device *dev)
367{
368 struct iss_net_private *lp = dev->priv;
369 int pkt_len;
370 struct sk_buff *skb;
371
372 /* Check if there is any new data. */
373
374 if (lp->tp.poll(lp) == 0)
375 return 0;
376
377 /* Try to allocate memory, if it fails, try again next round. */
378
379 if ((skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER)) == NULL) {
380 lp->stats.rx_dropped++;
381 return 0;
382 }
383
384 skb_reserve(skb, 2);
385
386 /* Setup skb */
387
388 skb->dev = dev;
389 skb->mac.raw = skb->data;
390 pkt_len = lp->tp.read(lp, &skb);
391 skb_put(skb, pkt_len);
392
393 if (pkt_len > 0) {
394 skb_trim(skb, pkt_len);
395 skb->protocol = lp->tp.protocol(skb);
396 // netif_rx(skb);
397 netif_rx_ni(skb);
398
399 lp->stats.rx_bytes += skb->len;
400 lp->stats.rx_packets++;
401 return pkt_len;
402 }
403 kfree_skb(skb);
404 return pkt_len;
405}
406
407static int iss_net_poll(void)
408{
409 struct list_head *ele;
410 int err, ret = 0;
411
412 spin_lock(&opened_lock);
413
414 list_for_each(ele, &opened) {
415 struct iss_net_private *lp;
416
417 lp = list_entry(ele, struct iss_net_private, opened_list);
418
419 if (!netif_running(lp->dev))
420 break;
421
422 spin_lock(&lp->lock);
423
424 while ((err = iss_net_rx(lp->dev)) > 0)
425 ret++;
426
427 spin_unlock(&lp->lock);
428
429 if (err < 0) {
430 printk(KERN_ERR "Device '%s' read returned %d, "
431 "shutting it down\n", lp->dev->name, err);
432 dev_close(lp->dev);
433 } else {
434 // FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ);
435 }
436 }
437
438 spin_unlock(&opened_lock);
439 return ret;
440}
441
442
443static void iss_net_timer(unsigned long priv)
444{
445 struct iss_net_private* lp = (struct iss_net_private*) priv;
446
447 spin_lock(&lp->lock);
448
449 iss_net_poll();
450
451 mod_timer(&lp->timer, jiffies + lp->timer_val);
452
453 spin_unlock(&lp->lock);
454}
455
456
457static int iss_net_open(struct net_device *dev)
458{
459 struct iss_net_private *lp = dev->priv;
460 char addr[sizeof "255.255.255.255\0"];
461 int err;
462
463 spin_lock(&lp->lock);
464
465 if ((err = lp->tp.open(lp)) < 0)
466 goto out;
467
468 if (!lp->have_mac) {
469 dev_ip_addr(dev, addr, &lp->mac[2]);
470 set_ether_mac(dev, lp->mac);
471 }
472
473 netif_start_queue(dev);
474
475 /* clear buffer - it can happen that the host side of the interface
476 * is full when we gethere. In this case, new data is never queued,
477 * SIGIOs never arrive, and the net never works.
478 */
479 while ((err = iss_net_rx(dev)) > 0)
480 ;
481
482 spin_lock(&opened_lock);
483 list_add(&lp->opened_list, &opened);
484 spin_unlock(&opened_lock);
485
486 init_timer(&lp->timer);
487 lp->timer_val = ISS_NET_TIMER_VALUE;
488 lp->timer.data = (unsigned long) lp;
489 lp->timer.function = iss_net_timer;
490 mod_timer(&lp->timer, jiffies + lp->timer_val);
491
492out:
493 spin_unlock(&lp->lock);
494 return err;
495}
496
497static int iss_net_close(struct net_device *dev)
498{
499 struct iss_net_private *lp = dev->priv;
500printk("iss_net_close!\n");
501 netif_stop_queue(dev);
502 spin_lock(&lp->lock);
503
504 spin_lock(&opened_lock);
505 list_del(&opened);
506 spin_unlock(&opened_lock);
507
508 del_timer_sync(&lp->timer);
509
510 lp->tp.close(lp);
511
512 spin_unlock(&lp->lock);
513 return 0;
514}
515
516static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
517{
518 struct iss_net_private *lp = dev->priv;
519 unsigned long flags;
520 int len;
521
522 netif_stop_queue(dev);
523 spin_lock_irqsave(&lp->lock, flags);
524
525 len = lp->tp.write(lp, &skb);
526
527 if (len == skb->len) {
528 lp->stats.tx_packets++;
529 lp->stats.tx_bytes += skb->len;
530 dev->trans_start = jiffies;
531 netif_start_queue(dev);
532
533 /* this is normally done in the interrupt when tx finishes */
534 netif_wake_queue(dev);
535
536 } else if (len == 0) {
537 netif_start_queue(dev);
538 lp->stats.tx_dropped++;
539
540 } else {
541 netif_start_queue(dev);
542 printk(KERN_ERR "iss_net_start_xmit: failed(%d)\n", len);
543 }
544
545 spin_unlock_irqrestore(&lp->lock, flags);
546
547 dev_kfree_skb(skb);
548 return 0;
549}
550
551
552static struct net_device_stats *iss_net_get_stats(struct net_device *dev)
553{
554 struct iss_net_private *lp = dev->priv;
555 return &lp->stats;
556}
557
558static void iss_net_set_multicast_list(struct net_device *dev)
559{
560#if 0
561 if (dev->flags & IFF_PROMISC)
562 return;
563 else if (dev->mc_count)
564 dev->flags |= IFF_ALLMULTI;
565 else
566 dev->flags &= ~IFF_ALLMULTI;
567#endif
568}
569
570static void iss_net_tx_timeout(struct net_device *dev)
571{
572#if 0
573 dev->trans_start = jiffies;
574 netif_wake_queue(dev);
575#endif
576}
577
578static int iss_net_set_mac(struct net_device *dev, void *addr)
579{
580#if 0
581 struct iss_net_private *lp = dev->priv;
582 struct sockaddr *hwaddr = addr;
583
584 spin_lock(&lp->lock);
585 memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
586 spin_unlock(&lp->lock);
587#endif
588
589 return 0;
590}
591
592static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
593{
594#if 0
595 struct iss_net_private *lp = dev->priv;
596 int err = 0;
597
598 spin_lock(&lp->lock);
599
600 // FIXME not needed new_mtu = transport_set_mtu(new_mtu, &lp->user);
601
602 if (new_mtu < 0)
603 err = new_mtu;
604 else
605 dev->mtu = new_mtu;
606
607 spin_unlock(&lp->lock);
608 return err;
609#endif
610 return -EINVAL;
611}
612
613static int iss_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
614{
615#if 0
616 static const struct ethtool_drvinfo info = {
617 .cmd = ETHTOOL_GDRVINFO,
618 .driver = DRIVER_NAME,
619 .version = "42",
620 };
621 void *useraddr;
622 u32 ethcmd;
623
624 switch (cmd) {
625 case SIOCETHTOOL:
626 useraddr = ifr->ifr_data;
627 if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
628 return -EFAULT;
629
630 switch (ethcmd) {
631 case ETHTOOL_GDRVINFO:
632 if (copy_to_user(useraddr, &info, sizeof(info)))
633 return -EFAULT;
634 return 0;
635 default:
636 return -EOPNOTSUPP;
637 }
638 default:
639 return -EINVAL;
640 }
641#endif
642 return -EINVAL;
643}
644
645void iss_net_user_timer_expire(unsigned long _conn)
646{
647}
648
649
650static struct device_driver iss_net_driver = {
651 .name = DRIVER_NAME,
652 .bus = &platform_bus_type,
653};
654
655static int driver_registered;
656
657static int iss_net_configure(int index, char *init)
658{
659 struct net_device *dev;
660 struct iss_net_private *lp;
661 int err;
662
663 if ((dev = alloc_etherdev(sizeof *lp)) == NULL) {
664 printk(KERN_ERR "eth_configure: failed to allocate device\n");
665 return 1;
666 }
667
668 /* Initialize private element. */
669
670 lp = dev->priv;
671 *lp = ((struct iss_net_private) {
672 .device_list = LIST_HEAD_INIT(lp->device_list),
673 .opened_list = LIST_HEAD_INIT(lp->opened_list),
674 .lock = SPIN_LOCK_UNLOCKED,
675 .dev = dev,
676 .index = index,
677 //.fd = -1,
678 .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 },
679 .have_mac = 0,
680 });
681
682 /*
683 * Try all transport protocols.
684 * Note: more protocols can be added by adding '&& !X_init(lp, eth)'.
685 */
686
687 if (!tuntap_probe(lp, index, init)) {
688 printk("Invalid arguments. Skipping device!\n");
689 goto errout;
690 }
691
692 printk(KERN_INFO "Netdevice %d ", index);
693 if (lp->have_mac)
694 printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
695 lp->mac[0], lp->mac[1],
696 lp->mac[2], lp->mac[3],
697 lp->mac[4], lp->mac[5]);
698 printk(": ");
699
700 /* sysfs register */
701
702 if (!driver_registered) {
703 driver_register(&iss_net_driver);
704 driver_registered = 1;
705 }
706
707 spin_lock(&devices_lock);
708 list_add(&lp->device_list, &devices);
709 spin_unlock(&devices_lock);
710
711 lp->pdev.id = index;
712 lp->pdev.name = DRIVER_NAME;
713 platform_device_register(&lp->pdev);
714 SET_NETDEV_DEV(dev,&lp->pdev.dev);
715
716 /*
717 * If this name ends up conflicting with an existing registered
718 * netdevice, that is OK, register_netdev{,ice}() will notice this
719 * and fail.
720 */
721 snprintf(dev->name, sizeof dev->name, "eth%d", index);
722
723 dev->mtu = lp->mtu;
724 dev->open = iss_net_open;
725 dev->hard_start_xmit = iss_net_start_xmit;
726 dev->stop = iss_net_close;
727 dev->get_stats = iss_net_get_stats;
728 dev->set_multicast_list = iss_net_set_multicast_list;
729 dev->tx_timeout = iss_net_tx_timeout;
730 dev->set_mac_address = iss_net_set_mac;
731 dev->change_mtu = iss_net_change_mtu;
732 dev->do_ioctl = iss_net_ioctl;
733 dev->watchdog_timeo = (HZ >> 1);
734 dev->irq = -1;
735
736 rtnl_lock();
737 err = register_netdevice(dev);
738 rtnl_unlock();
739
740 if (err) {
741 printk("Error registering net device!\n");
742 /* XXX: should we call ->remove() here? */
743 free_netdev(dev);
744 return 1;
745 }
746
747 init_timer(&lp->tl);
748 lp->tl.function = iss_net_user_timer_expire;
749
750#if 0
751 if (lp->have_mac)
752 set_ether_mac(dev, lp->mac);
753#endif
754 return 0;
755
756errout:
757 // FIXME: unregister; free, etc..
758 return -EIO;
759
760}
761
762/* ------------------------------------------------------------------------- */
763
764/* Filled in during early boot */
765
766struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
767
768struct iss_net_init {
769 struct list_head list;
770 char *init; /* init string */
771 int index;
772};
773
774/*
775 * Parse the command line and look for 'ethX=...' fields, and register all
776 * those fields. They will be later initialized in iss_net_init.
777 */
778
779#define ERR KERN_ERR "iss_net_setup: "
780
781static int iss_net_setup(char *str)
782{
783 struct iss_net_private *device = NULL;
784 struct iss_net_init *new;
785 struct list_head *ele;
786 char *end;
787 int n;
788
789 n = simple_strtoul(str, &end, 0);
790 if (end == str) {
791 printk(ERR "Failed to parse '%s'\n", str);
792 return 1;
793 }
794 if (n < 0) {
795 printk(ERR "Device %d is negative\n", n);
796 return 1;
797 }
798 if (*(str = end) != '=') {
799 printk(ERR "Expected '=' after device number\n");
800 return 1;
801 }
802
803 spin_lock(&devices_lock);
804
805 list_for_each(ele, &devices) {
806 device = list_entry(ele, struct iss_net_private, device_list);
807 if (device->index == n)
808 break;
809 }
810
811 spin_unlock(&devices_lock);
812
813 if (device && device->index == n) {
814 printk(ERR "Device %d already configured\n", n);
815 return 1;
816 }
817
818 if ((new = alloc_bootmem(sizeof new)) == NULL) {
819 printk("Alloc_bootmem failed\n");
820 return 1;
821 }
822
823 INIT_LIST_HEAD(&new->list);
824 new->index = n;
825 new->init = str + 1;
826
827 list_add_tail(&new->list, &eth_cmd_line);
828 return 1;
829}
830
831#undef ERR
832
833__setup("eth", iss_net_setup);
834
835/*
836 * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
837 */
838
839static int iss_net_init(void)
840{
841 struct list_head *ele, *next;
842
843 /* Walk through all Ethernet devices specified in the command line. */
844
845 list_for_each_safe(ele, next, &eth_cmd_line) {
846 struct iss_net_init *eth;
847 eth = list_entry(ele, struct iss_net_init, list);
848 iss_net_configure(eth->index, eth->init);
849 }
850
851 return 1;
852}
853
854module_init(iss_net_init);
855
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c
new file mode 100644
index 000000000000..2e6dcbf0cc04
--- /dev/null
+++ b/arch/xtensa/platform-iss/setup.c
@@ -0,0 +1,112 @@
1/*
2 *
3 * arch/xtensa/platform-iss/setup.c
4 *
5 * Platform specific initialization.
6 *
7 * Authors: Chris Zankel <chris@zankel.net>
8 * Joe Taylor <joe@tensilica.com>
9 *
10 * Copyright 2001 - 2005 Tensilica Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 */
18#include <linux/config.h>
19#include <linux/stddef.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/errno.h>
23#include <linux/reboot.h>
24#include <linux/pci.h>
25#include <linux/kdev_t.h>
26#include <linux/types.h>
27#include <linux/major.h>
28#include <linux/blkdev.h>
29#include <linux/console.h>
30#include <linux/delay.h>
31#include <linux/stringify.h>
32#include <linux/notifier.h>
33
34#include <asm/platform.h>
35#include <asm/bootparam.h>
36
37
38void __init platform_init(bp_tag_t* bootparam)
39{
40
41}
42
43void platform_halt(void)
44{
45 printk (" ** Called platform_halt(), looping forever! **\n");
46 while (1);
47}
48
49void platform_power_off(void)
50{
51 printk (" ** Called platform_power_off(), looping forever! **\n");
52 while (1);
53}
54void platform_restart(void)
55{
56 /* Flush and reset the mmu, simulate a processor reset, and
57 * jump to the reset vector. */
58
59 __asm__ __volatile__("movi a2, 15\n\t"
60 "wsr a2, " __stringify(ICOUNTLEVEL) "\n\t"
61 "movi a2, 0\n\t"
62 "wsr a2, " __stringify(ICOUNT) "\n\t"
63 "wsr a2, " __stringify(IBREAKENABLE) "\n\t"
64 "wsr a2, " __stringify(LCOUNT) "\n\t"
65 "movi a2, 0x1f\n\t"
66 "wsr a2, " __stringify(PS) "\n\t"
67 "isync\n\t"
68 "jx %0\n\t"
69 :
70 : "a" (XCHAL_RESET_VECTOR_VADDR)
71 : "a2");
72
73 /* control never gets here */
74}
75
76extern void iss_net_poll(void);
77
78const char twirl[]="|/-\\|/-\\";
79
80void platform_heartbeat(void)
81{
82#if 0
83 static int i = 0, j = 0;
84
85 if (--i < 0) {
86 i = 99;
87 printk("\r%c\r", twirl[j++]);
88 if (j == 8)
89 j = 0;
90 }
91#endif
92}
93
94
95
96static int
97iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
98{
99 __asm__ __volatile__("movi a2, -1; simcall\n");
100 return NOTIFY_DONE;
101}
102
103static struct notifier_block iss_panic_block = {
104 iss_panic_event,
105 NULL,
106 0
107};
108
109void __init platform_setup(char **p_cmdline)
110{
111 notifier_chain_register(&panic_notifier_list, &iss_panic_block);
112}
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index 638db06de2be..3410b4d294b9 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -1871,20 +1871,22 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
1871 if (!arq_pool) 1871 if (!arq_pool)
1872 return -ENOMEM; 1872 return -ENOMEM;
1873 1873
1874 ad = kmalloc(sizeof(*ad), GFP_KERNEL); 1874 ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node);
1875 if (!ad) 1875 if (!ad)
1876 return -ENOMEM; 1876 return -ENOMEM;
1877 memset(ad, 0, sizeof(*ad)); 1877 memset(ad, 0, sizeof(*ad));
1878 1878
1879 ad->q = q; /* Identify what queue the data belongs to */ 1879 ad->q = q; /* Identify what queue the data belongs to */
1880 1880
1881 ad->hash = kmalloc(sizeof(struct list_head)*AS_HASH_ENTRIES,GFP_KERNEL); 1881 ad->hash = kmalloc_node(sizeof(struct list_head)*AS_HASH_ENTRIES,
1882 GFP_KERNEL, q->node);
1882 if (!ad->hash) { 1883 if (!ad->hash) {
1883 kfree(ad); 1884 kfree(ad);
1884 return -ENOMEM; 1885 return -ENOMEM;
1885 } 1886 }
1886 1887
1887 ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool); 1888 ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
1889 mempool_free_slab, arq_pool, q->node);
1888 if (!ad->arq_pool) { 1890 if (!ad->arq_pool) {
1889 kfree(ad->hash); 1891 kfree(ad->hash);
1890 kfree(ad); 1892 kfree(ad);
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index 7f79f3dd0165..4bc2fea73273 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -711,18 +711,20 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
711 if (!drq_pool) 711 if (!drq_pool)
712 return -ENOMEM; 712 return -ENOMEM;
713 713
714 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 714 dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
715 if (!dd) 715 if (!dd)
716 return -ENOMEM; 716 return -ENOMEM;
717 memset(dd, 0, sizeof(*dd)); 717 memset(dd, 0, sizeof(*dd));
718 718
719 dd->hash = kmalloc(sizeof(struct list_head)*DL_HASH_ENTRIES,GFP_KERNEL); 719 dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES,
720 GFP_KERNEL, q->node);
720 if (!dd->hash) { 721 if (!dd->hash) {
721 kfree(dd); 722 kfree(dd);
722 return -ENOMEM; 723 return -ENOMEM;
723 } 724 }
724 725
725 dd->drq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, drq_pool); 726 dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
727 mempool_free_slab, drq_pool, q->node);
726 if (!dd->drq_pool) { 728 if (!dd->drq_pool) {
727 kfree(dd->hash); 729 kfree(dd->hash);
728 kfree(dd); 730 kfree(dd);
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 53f7d846b747..47fd3659a061 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -40,7 +40,7 @@ static inline int major_to_index(int major)
40 40
41#ifdef CONFIG_PROC_FS 41#ifdef CONFIG_PROC_FS
42/* get block device names in somewhat random order */ 42/* get block device names in somewhat random order */
43int get_blkdev_list(char *p) 43int get_blkdev_list(char *p, int used)
44{ 44{
45 struct blk_major_name *n; 45 struct blk_major_name *n;
46 int i, len; 46 int i, len;
@@ -49,10 +49,18 @@ int get_blkdev_list(char *p)
49 49
50 down(&block_subsys_sem); 50 down(&block_subsys_sem);
51 for (i = 0; i < ARRAY_SIZE(major_names); i++) { 51 for (i = 0; i < ARRAY_SIZE(major_names); i++) {
52 for (n = major_names[i]; n; n = n->next) 52 for (n = major_names[i]; n; n = n->next) {
53 /*
54 * If the curent string plus the 5 extra characters
55 * in the line would run us off the page, then we're done
56 */
57 if ((len + used + strlen(n->name) + 5) >= PAGE_SIZE)
58 goto page_full;
53 len += sprintf(p+len, "%3d %s\n", 59 len += sprintf(p+len, "%3d %s\n",
54 n->major, n->name); 60 n->major, n->name);
61 }
55 } 62 }
63page_full:
56 up(&block_subsys_sem); 64 up(&block_subsys_sem);
57 65
58 return len; 66 return len;
@@ -582,10 +590,16 @@ struct seq_operations diskstats_op = {
582 .show = diskstats_show 590 .show = diskstats_show
583}; 591};
584 592
585
586struct gendisk *alloc_disk(int minors) 593struct gendisk *alloc_disk(int minors)
587{ 594{
588 struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL); 595 return alloc_disk_node(minors, -1);
596}
597
598struct gendisk *alloc_disk_node(int minors, int node_id)
599{
600 struct gendisk *disk;
601
602 disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
589 if (disk) { 603 if (disk) {
590 memset(disk, 0, sizeof(struct gendisk)); 604 memset(disk, 0, sizeof(struct gendisk));
591 if (!init_disk_stats(disk)) { 605 if (!init_disk_stats(disk)) {
@@ -594,7 +608,7 @@ struct gendisk *alloc_disk(int minors)
594 } 608 }
595 if (minors > 1) { 609 if (minors > 1) {
596 int size = (minors - 1) * sizeof(struct hd_struct *); 610 int size = (minors - 1) * sizeof(struct hd_struct *);
597 disk->part = kmalloc(size, GFP_KERNEL); 611 disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
598 if (!disk->part) { 612 if (!disk->part) {
599 kfree(disk); 613 kfree(disk);
600 return NULL; 614 return NULL;
@@ -610,6 +624,7 @@ struct gendisk *alloc_disk(int minors)
610} 624}
611 625
612EXPORT_SYMBOL(alloc_disk); 626EXPORT_SYMBOL(alloc_disk);
627EXPORT_SYMBOL(alloc_disk_node);
613 628
614struct kobject *get_disk(struct gendisk *disk) 629struct kobject *get_disk(struct gendisk *disk)
615{ 630{
diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c
index 6d7bcc9da9e7..6e278474f9a8 100644
--- a/drivers/block/ioctl.c
+++ b/drivers/block/ioctl.c
@@ -133,11 +133,9 @@ static int put_u64(unsigned long arg, u64 val)
133 return put_user(val, (u64 __user *)arg); 133 return put_user(val, (u64 __user *)arg);
134} 134}
135 135
136int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, 136static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
137 unsigned long arg) 137 unsigned cmd, unsigned long arg)
138{ 138{
139 struct block_device *bdev = inode->i_bdev;
140 struct gendisk *disk = bdev->bd_disk;
141 struct backing_dev_info *bdi; 139 struct backing_dev_info *bdi;
142 int ret, n; 140 int ret, n;
143 141
@@ -190,36 +188,72 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
190 return put_ulong(arg, bdev->bd_inode->i_size >> 9); 188 return put_ulong(arg, bdev->bd_inode->i_size >> 9);
191 case BLKGETSIZE64: 189 case BLKGETSIZE64:
192 return put_u64(arg, bdev->bd_inode->i_size); 190 return put_u64(arg, bdev->bd_inode->i_size);
191 }
192 return -ENOIOCTLCMD;
193}
194
195static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
196 struct gendisk *disk, unsigned cmd, unsigned long arg)
197{
198 int ret;
199 if (disk->fops->unlocked_ioctl)
200 return disk->fops->unlocked_ioctl(file, cmd, arg);
201
202 if (disk->fops->ioctl) {
203 lock_kernel();
204 ret = disk->fops->ioctl(inode, file, cmd, arg);
205 unlock_kernel();
206 return ret;
207 }
208
209 return -ENOTTY;
210}
211
212int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
213 unsigned long arg)
214{
215 struct block_device *bdev = inode->i_bdev;
216 struct gendisk *disk = bdev->bd_disk;
217 int ret, n;
218
219 switch(cmd) {
193 case BLKFLSBUF: 220 case BLKFLSBUF:
194 if (!capable(CAP_SYS_ADMIN)) 221 if (!capable(CAP_SYS_ADMIN))
195 return -EACCES; 222 return -EACCES;
196 if (disk->fops->ioctl) { 223
197 ret = disk->fops->ioctl(inode, file, cmd, arg); 224 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
198 /* -EINVAL to handle old uncorrected drivers */ 225 /* -EINVAL to handle old uncorrected drivers */
199 if (ret != -EINVAL && ret != -ENOTTY) 226 if (ret != -EINVAL && ret != -ENOTTY)
200 return ret; 227 return ret;
201 } 228
229 lock_kernel();
202 fsync_bdev(bdev); 230 fsync_bdev(bdev);
203 invalidate_bdev(bdev, 0); 231 invalidate_bdev(bdev, 0);
232 unlock_kernel();
204 return 0; 233 return 0;
234
205 case BLKROSET: 235 case BLKROSET:
206 if (disk->fops->ioctl) { 236 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
207 ret = disk->fops->ioctl(inode, file, cmd, arg); 237 /* -EINVAL to handle old uncorrected drivers */
208 /* -EINVAL to handle old uncorrected drivers */ 238 if (ret != -EINVAL && ret != -ENOTTY)
209 if (ret != -EINVAL && ret != -ENOTTY) 239 return ret;
210 return ret;
211 }
212 if (!capable(CAP_SYS_ADMIN)) 240 if (!capable(CAP_SYS_ADMIN))
213 return -EACCES; 241 return -EACCES;
214 if (get_user(n, (int __user *)(arg))) 242 if (get_user(n, (int __user *)(arg)))
215 return -EFAULT; 243 return -EFAULT;
244 lock_kernel();
216 set_device_ro(bdev, n); 245 set_device_ro(bdev, n);
246 unlock_kernel();
217 return 0; 247 return 0;
218 default:
219 if (disk->fops->ioctl)
220 return disk->fops->ioctl(inode, file, cmd, arg);
221 } 248 }
222 return -ENOTTY; 249
250 lock_kernel();
251 ret = blkdev_locked_ioctl(file, bdev, cmd, arg);
252 unlock_kernel();
253 if (ret != -ENOIOCTLCMD)
254 return ret;
255
256 return blkdev_driver_ioctl(inode, file, disk, cmd, arg);
223} 257}
224 258
225/* Most of the generic ioctls are handled in the normal fallback path. 259/* Most of the generic ioctls are handled in the normal fallback path.
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 81fe3a0c1fe7..fd94ea27d594 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -28,6 +28,7 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/swap.h> 29#include <linux/swap.h>
30#include <linux/writeback.h> 30#include <linux/writeback.h>
31#include <linux/blkdev.h>
31 32
32/* 33/*
33 * for max sense size 34 * for max sense size
@@ -716,7 +717,7 @@ struct request *blk_queue_find_tag(request_queue_t *q, int tag)
716{ 717{
717 struct blk_queue_tag *bqt = q->queue_tags; 718 struct blk_queue_tag *bqt = q->queue_tags;
718 719
719 if (unlikely(bqt == NULL || tag >= bqt->real_max_depth)) 720 if (unlikely(bqt == NULL || tag >= bqt->max_depth))
720 return NULL; 721 return NULL;
721 722
722 return bqt->tag_index[tag]; 723 return bqt->tag_index[tag];
@@ -774,9 +775,9 @@ EXPORT_SYMBOL(blk_queue_free_tags);
774static int 775static int
775init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) 776init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
776{ 777{
777 int bits, i;
778 struct request **tag_index; 778 struct request **tag_index;
779 unsigned long *tag_map; 779 unsigned long *tag_map;
780 int nr_ulongs;
780 781
781 if (depth > q->nr_requests * 2) { 782 if (depth > q->nr_requests * 2) {
782 depth = q->nr_requests * 2; 783 depth = q->nr_requests * 2;
@@ -788,24 +789,17 @@ init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
788 if (!tag_index) 789 if (!tag_index)
789 goto fail; 790 goto fail;
790 791
791 bits = (depth / BLK_TAGS_PER_LONG) + 1; 792 nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG;
792 tag_map = kmalloc(bits * sizeof(unsigned long), GFP_ATOMIC); 793 tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);
793 if (!tag_map) 794 if (!tag_map)
794 goto fail; 795 goto fail;
795 796
796 memset(tag_index, 0, depth * sizeof(struct request *)); 797 memset(tag_index, 0, depth * sizeof(struct request *));
797 memset(tag_map, 0, bits * sizeof(unsigned long)); 798 memset(tag_map, 0, nr_ulongs * sizeof(unsigned long));
798 tags->max_depth = depth; 799 tags->max_depth = depth;
799 tags->real_max_depth = bits * BITS_PER_LONG;
800 tags->tag_index = tag_index; 800 tags->tag_index = tag_index;
801 tags->tag_map = tag_map; 801 tags->tag_map = tag_map;
802 802
803 /*
804 * set the upper bits if the depth isn't a multiple of the word size
805 */
806 for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++)
807 __set_bit(i, tag_map);
808
809 return 0; 803 return 0;
810fail: 804fail:
811 kfree(tag_index); 805 kfree(tag_index);
@@ -870,32 +864,24 @@ int blk_queue_resize_tags(request_queue_t *q, int new_depth)
870 struct blk_queue_tag *bqt = q->queue_tags; 864 struct blk_queue_tag *bqt = q->queue_tags;
871 struct request **tag_index; 865 struct request **tag_index;
872 unsigned long *tag_map; 866 unsigned long *tag_map;
873 int bits, max_depth; 867 int max_depth, nr_ulongs;
874 868
875 if (!bqt) 869 if (!bqt)
876 return -ENXIO; 870 return -ENXIO;
877 871
878 /* 872 /*
879 * don't bother sizing down
880 */
881 if (new_depth <= bqt->real_max_depth) {
882 bqt->max_depth = new_depth;
883 return 0;
884 }
885
886 /*
887 * save the old state info, so we can copy it back 873 * save the old state info, so we can copy it back
888 */ 874 */
889 tag_index = bqt->tag_index; 875 tag_index = bqt->tag_index;
890 tag_map = bqt->tag_map; 876 tag_map = bqt->tag_map;
891 max_depth = bqt->real_max_depth; 877 max_depth = bqt->max_depth;
892 878
893 if (init_tag_map(q, bqt, new_depth)) 879 if (init_tag_map(q, bqt, new_depth))
894 return -ENOMEM; 880 return -ENOMEM;
895 881
896 memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *)); 882 memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));
897 bits = max_depth / BLK_TAGS_PER_LONG; 883 nr_ulongs = ALIGN(max_depth, BITS_PER_LONG) / BITS_PER_LONG;
898 memcpy(bqt->tag_map, tag_map, bits * sizeof(unsigned long)); 884 memcpy(bqt->tag_map, tag_map, nr_ulongs * sizeof(unsigned long));
899 885
900 kfree(tag_index); 886 kfree(tag_index);
901 kfree(tag_map); 887 kfree(tag_map);
@@ -925,11 +911,16 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
925 911
926 BUG_ON(tag == -1); 912 BUG_ON(tag == -1);
927 913
928 if (unlikely(tag >= bqt->real_max_depth)) 914 if (unlikely(tag >= bqt->max_depth))
915 /*
916 * This can happen after tag depth has been reduced.
917 * FIXME: how about a warning or info message here?
918 */
929 return; 919 return;
930 920
931 if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) { 921 if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
932 printk("attempt to clear non-busy tag (%d)\n", tag); 922 printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
923 __FUNCTION__, tag);
933 return; 924 return;
934 } 925 }
935 926
@@ -938,7 +929,8 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
938 rq->tag = -1; 929 rq->tag = -1;
939 930
940 if (unlikely(bqt->tag_index[tag] == NULL)) 931 if (unlikely(bqt->tag_index[tag] == NULL))
941 printk("tag %d is missing\n", tag); 932 printk(KERN_ERR "%s: tag %d is missing\n",
933 __FUNCTION__, tag);
942 934
943 bqt->tag_index[tag] = NULL; 935 bqt->tag_index[tag] = NULL;
944 bqt->busy--; 936 bqt->busy--;
@@ -967,24 +959,20 @@ EXPORT_SYMBOL(blk_queue_end_tag);
967int blk_queue_start_tag(request_queue_t *q, struct request *rq) 959int blk_queue_start_tag(request_queue_t *q, struct request *rq)
968{ 960{
969 struct blk_queue_tag *bqt = q->queue_tags; 961 struct blk_queue_tag *bqt = q->queue_tags;
970 unsigned long *map = bqt->tag_map; 962 int tag;
971 int tag = 0;
972 963
973 if (unlikely((rq->flags & REQ_QUEUED))) { 964 if (unlikely((rq->flags & REQ_QUEUED))) {
974 printk(KERN_ERR 965 printk(KERN_ERR
975 "request %p for device [%s] already tagged %d", 966 "%s: request %p for device [%s] already tagged %d",
976 rq, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag); 967 __FUNCTION__, rq,
968 rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
977 BUG(); 969 BUG();
978 } 970 }
979 971
980 for (map = bqt->tag_map; *map == -1UL; map++) { 972 tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
981 tag += BLK_TAGS_PER_LONG; 973 if (tag >= bqt->max_depth)
982 974 return 1;
983 if (tag >= bqt->max_depth)
984 return 1;
985 }
986 975
987 tag += ffz(*map);
988 __set_bit(tag, bqt->tag_map); 976 __set_bit(tag, bqt->tag_map);
989 977
990 rq->flags |= REQ_QUEUED; 978 rq->flags |= REQ_QUEUED;
@@ -1020,7 +1008,8 @@ void blk_queue_invalidate_tags(request_queue_t *q)
1020 rq = list_entry_rq(tmp); 1008 rq = list_entry_rq(tmp);
1021 1009
1022 if (rq->tag == -1) { 1010 if (rq->tag == -1) {
1023 printk("bad tag found on list\n"); 1011 printk(KERN_ERR
1012 "%s: bad tag found on list\n", __FUNCTION__);
1024 list_del_init(&rq->queuelist); 1013 list_del_init(&rq->queuelist);
1025 rq->flags &= ~REQ_QUEUED; 1014 rq->flags &= ~REQ_QUEUED;
1026 } else 1015 } else
@@ -1450,7 +1439,7 @@ EXPORT_SYMBOL(blk_remove_plug);
1450 */ 1439 */
1451void __generic_unplug_device(request_queue_t *q) 1440void __generic_unplug_device(request_queue_t *q)
1452{ 1441{
1453 if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) 1442 if (unlikely(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)))
1454 return; 1443 return;
1455 1444
1456 if (!blk_remove_plug(q)) 1445 if (!blk_remove_plug(q))
@@ -1645,7 +1634,8 @@ static int blk_init_free_list(request_queue_t *q)
1645 init_waitqueue_head(&rl->wait[WRITE]); 1634 init_waitqueue_head(&rl->wait[WRITE]);
1646 init_waitqueue_head(&rl->drain); 1635 init_waitqueue_head(&rl->drain);
1647 1636
1648 rl->rq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, request_cachep); 1637 rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
1638 mempool_free_slab, request_cachep, q->node);
1649 1639
1650 if (!rl->rq_pool) 1640 if (!rl->rq_pool)
1651 return -ENOMEM; 1641 return -ENOMEM;
@@ -1657,8 +1647,15 @@ static int __make_request(request_queue_t *, struct bio *);
1657 1647
1658request_queue_t *blk_alloc_queue(int gfp_mask) 1648request_queue_t *blk_alloc_queue(int gfp_mask)
1659{ 1649{
1660 request_queue_t *q = kmem_cache_alloc(requestq_cachep, gfp_mask); 1650 return blk_alloc_queue_node(gfp_mask, -1);
1651}
1652EXPORT_SYMBOL(blk_alloc_queue);
1653
1654request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id)
1655{
1656 request_queue_t *q;
1661 1657
1658 q = kmem_cache_alloc_node(requestq_cachep, gfp_mask, node_id);
1662 if (!q) 1659 if (!q)
1663 return NULL; 1660 return NULL;
1664 1661
@@ -1671,8 +1668,7 @@ request_queue_t *blk_alloc_queue(int gfp_mask)
1671 1668
1672 return q; 1669 return q;
1673} 1670}
1674 1671EXPORT_SYMBOL(blk_alloc_queue_node);
1675EXPORT_SYMBOL(blk_alloc_queue);
1676 1672
1677/** 1673/**
1678 * blk_init_queue - prepare a request queue for use with a block device 1674 * blk_init_queue - prepare a request queue for use with a block device
@@ -1705,13 +1701,22 @@ EXPORT_SYMBOL(blk_alloc_queue);
1705 * blk_init_queue() must be paired with a blk_cleanup_queue() call 1701 * blk_init_queue() must be paired with a blk_cleanup_queue() call
1706 * when the block device is deactivated (such as at module unload). 1702 * when the block device is deactivated (such as at module unload).
1707 **/ 1703 **/
1704
1708request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) 1705request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
1709{ 1706{
1710 request_queue_t *q = blk_alloc_queue(GFP_KERNEL); 1707 return blk_init_queue_node(rfn, lock, -1);
1708}
1709EXPORT_SYMBOL(blk_init_queue);
1710
1711request_queue_t *
1712blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
1713{
1714 request_queue_t *q = blk_alloc_queue_node(GFP_KERNEL, node_id);
1711 1715
1712 if (!q) 1716 if (!q)
1713 return NULL; 1717 return NULL;
1714 1718
1719 q->node = node_id;
1715 if (blk_init_free_list(q)) 1720 if (blk_init_free_list(q))
1716 goto out_init; 1721 goto out_init;
1717 1722
@@ -1754,12 +1759,11 @@ out_init:
1754 kmem_cache_free(requestq_cachep, q); 1759 kmem_cache_free(requestq_cachep, q);
1755 return NULL; 1760 return NULL;
1756} 1761}
1757 1762EXPORT_SYMBOL(blk_init_queue_node);
1758EXPORT_SYMBOL(blk_init_queue);
1759 1763
1760int blk_get_queue(request_queue_t *q) 1764int blk_get_queue(request_queue_t *q)
1761{ 1765{
1762 if (!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) { 1766 if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
1763 atomic_inc(&q->refcnt); 1767 atomic_inc(&q->refcnt);
1764 return 0; 1768 return 0;
1765 } 1769 }
@@ -1838,7 +1842,6 @@ static void __freed_request(request_queue_t *q, int rw)
1838 clear_queue_congested(q, rw); 1842 clear_queue_congested(q, rw);
1839 1843
1840 if (rl->count[rw] + 1 <= q->nr_requests) { 1844 if (rl->count[rw] + 1 <= q->nr_requests) {
1841 smp_mb();
1842 if (waitqueue_active(&rl->wait[rw])) 1845 if (waitqueue_active(&rl->wait[rw]))
1843 wake_up(&rl->wait[rw]); 1846 wake_up(&rl->wait[rw]);
1844 1847
@@ -1966,7 +1969,6 @@ static struct request *get_request_wait(request_queue_t *q, int rw)
1966 DEFINE_WAIT(wait); 1969 DEFINE_WAIT(wait);
1967 struct request *rq; 1970 struct request *rq;
1968 1971
1969 generic_unplug_device(q);
1970 do { 1972 do {
1971 struct request_list *rl = &q->rq; 1973 struct request_list *rl = &q->rq;
1972 1974
@@ -1978,6 +1980,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw)
1978 if (!rq) { 1980 if (!rq) {
1979 struct io_context *ioc; 1981 struct io_context *ioc;
1980 1982
1983 generic_unplug_device(q);
1981 io_schedule(); 1984 io_schedule();
1982 1985
1983 /* 1986 /*
@@ -2581,7 +2584,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
2581 spin_lock_prefetch(q->queue_lock); 2584 spin_lock_prefetch(q->queue_lock);
2582 2585
2583 barrier = bio_barrier(bio); 2586 barrier = bio_barrier(bio);
2584 if (barrier && (q->ordered == QUEUE_ORDERED_NONE)) { 2587 if (unlikely(barrier) && (q->ordered == QUEUE_ORDERED_NONE)) {
2585 err = -EOPNOTSUPP; 2588 err = -EOPNOTSUPP;
2586 goto end_io; 2589 goto end_io;
2587 } 2590 }
@@ -2682,7 +2685,7 @@ get_rq:
2682 /* 2685 /*
2683 * REQ_BARRIER implies no merging, but lets make it explicit 2686 * REQ_BARRIER implies no merging, but lets make it explicit
2684 */ 2687 */
2685 if (barrier) 2688 if (unlikely(barrier))
2686 req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE); 2689 req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
2687 2690
2688 req->errors = 0; 2691 req->errors = 0;
@@ -2806,7 +2809,7 @@ static inline void block_wait_queue_running(request_queue_t *q)
2806{ 2809{
2807 DEFINE_WAIT(wait); 2810 DEFINE_WAIT(wait);
2808 2811
2809 while (test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)) { 2812 while (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) {
2810 struct request_list *rl = &q->rq; 2813 struct request_list *rl = &q->rq;
2811 2814
2812 prepare_to_wait_exclusive(&rl->drain, &wait, 2815 prepare_to_wait_exclusive(&rl->drain, &wait,
@@ -2915,7 +2918,7 @@ end_io:
2915 goto end_io; 2918 goto end_io;
2916 } 2919 }
2917 2920
2918 if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) 2921 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
2919 goto end_io; 2922 goto end_io;
2920 2923
2921 block_wait_queue_running(q); 2924 block_wait_queue_running(q);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 6f011d0d8e97..b35e08876dd4 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -472,17 +472,11 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
472 */ 472 */
473static void loop_add_bio(struct loop_device *lo, struct bio *bio) 473static void loop_add_bio(struct loop_device *lo, struct bio *bio)
474{ 474{
475 unsigned long flags;
476
477 spin_lock_irqsave(&lo->lo_lock, flags);
478 if (lo->lo_biotail) { 475 if (lo->lo_biotail) {
479 lo->lo_biotail->bi_next = bio; 476 lo->lo_biotail->bi_next = bio;
480 lo->lo_biotail = bio; 477 lo->lo_biotail = bio;
481 } else 478 } else
482 lo->lo_bio = lo->lo_biotail = bio; 479 lo->lo_bio = lo->lo_biotail = bio;
483 spin_unlock_irqrestore(&lo->lo_lock, flags);
484
485 up(&lo->lo_bh_mutex);
486} 480}
487 481
488/* 482/*
@@ -492,14 +486,12 @@ static struct bio *loop_get_bio(struct loop_device *lo)
492{ 486{
493 struct bio *bio; 487 struct bio *bio;
494 488
495 spin_lock_irq(&lo->lo_lock);
496 if ((bio = lo->lo_bio)) { 489 if ((bio = lo->lo_bio)) {
497 if (bio == lo->lo_biotail) 490 if (bio == lo->lo_biotail)
498 lo->lo_biotail = NULL; 491 lo->lo_biotail = NULL;
499 lo->lo_bio = bio->bi_next; 492 lo->lo_bio = bio->bi_next;
500 bio->bi_next = NULL; 493 bio->bi_next = NULL;
501 } 494 }
502 spin_unlock_irq(&lo->lo_lock);
503 495
504 return bio; 496 return bio;
505} 497}
@@ -509,35 +501,28 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio)
509 struct loop_device *lo = q->queuedata; 501 struct loop_device *lo = q->queuedata;
510 int rw = bio_rw(old_bio); 502 int rw = bio_rw(old_bio);
511 503
512 if (!lo) 504 if (rw == READA)
513 goto out; 505 rw = READ;
506
507 BUG_ON(!lo || (rw != READ && rw != WRITE));
514 508
515 spin_lock_irq(&lo->lo_lock); 509 spin_lock_irq(&lo->lo_lock);
516 if (lo->lo_state != Lo_bound) 510 if (lo->lo_state != Lo_bound)
517 goto inactive; 511 goto out;
518 atomic_inc(&lo->lo_pending); 512 if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
519 spin_unlock_irq(&lo->lo_lock); 513 goto out;
520 514 lo->lo_pending++;
521 if (rw == WRITE) {
522 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
523 goto err;
524 } else if (rw == READA) {
525 rw = READ;
526 } else if (rw != READ) {
527 printk(KERN_ERR "loop: unknown command (%x)\n", rw);
528 goto err;
529 }
530 loop_add_bio(lo, old_bio); 515 loop_add_bio(lo, old_bio);
516 spin_unlock_irq(&lo->lo_lock);
517 up(&lo->lo_bh_mutex);
531 return 0; 518 return 0;
532err: 519
533 if (atomic_dec_and_test(&lo->lo_pending))
534 up(&lo->lo_bh_mutex);
535out: 520out:
521 if (lo->lo_pending == 0)
522 up(&lo->lo_bh_mutex);
523 spin_unlock_irq(&lo->lo_lock);
536 bio_io_error(old_bio, old_bio->bi_size); 524 bio_io_error(old_bio, old_bio->bi_size);
537 return 0; 525 return 0;
538inactive:
539 spin_unlock_irq(&lo->lo_lock);
540 goto out;
541} 526}
542 527
543/* 528/*
@@ -560,13 +545,11 @@ static void do_loop_switch(struct loop_device *, struct switch_request *);
560 545
561static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio) 546static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
562{ 547{
563 int ret;
564
565 if (unlikely(!bio->bi_bdev)) { 548 if (unlikely(!bio->bi_bdev)) {
566 do_loop_switch(lo, bio->bi_private); 549 do_loop_switch(lo, bio->bi_private);
567 bio_put(bio); 550 bio_put(bio);
568 } else { 551 } else {
569 ret = do_bio_filebacked(lo, bio); 552 int ret = do_bio_filebacked(lo, bio);
570 bio_endio(bio, bio->bi_size, ret); 553 bio_endio(bio, bio->bi_size, ret);
571 } 554 }
572} 555}
@@ -594,7 +577,7 @@ static int loop_thread(void *data)
594 set_user_nice(current, -20); 577 set_user_nice(current, -20);
595 578
596 lo->lo_state = Lo_bound; 579 lo->lo_state = Lo_bound;
597 atomic_inc(&lo->lo_pending); 580 lo->lo_pending = 1;
598 581
599 /* 582 /*
600 * up sem, we are running 583 * up sem, we are running
@@ -602,26 +585,37 @@ static int loop_thread(void *data)
602 up(&lo->lo_sem); 585 up(&lo->lo_sem);
603 586
604 for (;;) { 587 for (;;) {
605 down_interruptible(&lo->lo_bh_mutex); 588 int pending;
589
606 /* 590 /*
607 * could be upped because of tear-down, not because of 591 * interruptible just to not contribute to load avg
608 * pending work
609 */ 592 */
610 if (!atomic_read(&lo->lo_pending)) 593 if (down_interruptible(&lo->lo_bh_mutex))
594 continue;
595
596 spin_lock_irq(&lo->lo_lock);
597
598 /*
599 * could be upped because of tear-down, not pending work
600 */
601 if (unlikely(!lo->lo_pending)) {
602 spin_unlock_irq(&lo->lo_lock);
611 break; 603 break;
604 }
612 605
613 bio = loop_get_bio(lo); 606 bio = loop_get_bio(lo);
614 if (!bio) { 607 lo->lo_pending--;
615 printk("loop: missing bio\n"); 608 pending = lo->lo_pending;
616 continue; 609 spin_unlock_irq(&lo->lo_lock);
617 } 610
611 BUG_ON(!bio);
618 loop_handle_bio(lo, bio); 612 loop_handle_bio(lo, bio);
619 613
620 /* 614 /*
621 * upped both for pending work and tear-down, lo_pending 615 * upped both for pending work and tear-down, lo_pending
622 * will hit zero then 616 * will hit zero then
623 */ 617 */
624 if (atomic_dec_and_test(&lo->lo_pending)) 618 if (unlikely(!pending))
625 break; 619 break;
626 } 620 }
627 621
@@ -900,7 +894,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
900 894
901 spin_lock_irq(&lo->lo_lock); 895 spin_lock_irq(&lo->lo_lock);
902 lo->lo_state = Lo_rundown; 896 lo->lo_state = Lo_rundown;
903 if (atomic_dec_and_test(&lo->lo_pending)) 897 lo->lo_pending--;
898 if (!lo->lo_pending)
904 up(&lo->lo_bh_mutex); 899 up(&lo->lo_bh_mutex);
905 spin_unlock_irq(&lo->lo_lock); 900 spin_unlock_irq(&lo->lo_lock);
906 901
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index bc56770bcc90..7f3d78de265c 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -467,14 +467,12 @@ static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsign
467 * Queue a bio for processing by the low-level CD device. Must be called 467 * Queue a bio for processing by the low-level CD device. Must be called
468 * from process context. 468 * from process context.
469 */ 469 */
470static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_prio_read) 470static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
471{ 471{
472 spin_lock(&pd->iosched.lock); 472 spin_lock(&pd->iosched.lock);
473 if (bio_data_dir(bio) == READ) { 473 if (bio_data_dir(bio) == READ) {
474 pkt_add_list_last(bio, &pd->iosched.read_queue, 474 pkt_add_list_last(bio, &pd->iosched.read_queue,
475 &pd->iosched.read_queue_tail); 475 &pd->iosched.read_queue_tail);
476 if (high_prio_read)
477 pd->iosched.high_prio_read = 1;
478 } else { 476 } else {
479 pkt_add_list_last(bio, &pd->iosched.write_queue, 477 pkt_add_list_last(bio, &pd->iosched.write_queue,
480 &pd->iosched.write_queue_tail); 478 &pd->iosched.write_queue_tail);
@@ -490,15 +488,16 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_p
490 * requirements for CDRW drives: 488 * requirements for CDRW drives:
491 * - A cache flush command must be inserted before a read request if the 489 * - A cache flush command must be inserted before a read request if the
492 * previous request was a write. 490 * previous request was a write.
493 * - Switching between reading and writing is slow, so don't it more often 491 * - Switching between reading and writing is slow, so don't do it more often
494 * than necessary. 492 * than necessary.
493 * - Optimize for throughput at the expense of latency. This means that streaming
494 * writes will never be interrupted by a read, but if the drive has to seek
495 * before the next write, switch to reading instead if there are any pending
496 * read requests.
495 * - Set the read speed according to current usage pattern. When only reading 497 * - Set the read speed according to current usage pattern. When only reading
496 * from the device, it's best to use the highest possible read speed, but 498 * from the device, it's best to use the highest possible read speed, but
497 * when switching often between reading and writing, it's better to have the 499 * when switching often between reading and writing, it's better to have the
498 * same read and write speeds. 500 * same read and write speeds.
499 * - Reads originating from user space should have higher priority than reads
500 * originating from pkt_gather_data, because some process is usually waiting
501 * on reads of the first kind.
502 */ 501 */
503static void pkt_iosched_process_queue(struct pktcdvd_device *pd) 502static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
504{ 503{
@@ -512,21 +511,24 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
512 511
513 for (;;) { 512 for (;;) {
514 struct bio *bio; 513 struct bio *bio;
515 int reads_queued, writes_queued, high_prio_read; 514 int reads_queued, writes_queued;
516 515
517 spin_lock(&pd->iosched.lock); 516 spin_lock(&pd->iosched.lock);
518 reads_queued = (pd->iosched.read_queue != NULL); 517 reads_queued = (pd->iosched.read_queue != NULL);
519 writes_queued = (pd->iosched.write_queue != NULL); 518 writes_queued = (pd->iosched.write_queue != NULL);
520 if (!reads_queued)
521 pd->iosched.high_prio_read = 0;
522 high_prio_read = pd->iosched.high_prio_read;
523 spin_unlock(&pd->iosched.lock); 519 spin_unlock(&pd->iosched.lock);
524 520
525 if (!reads_queued && !writes_queued) 521 if (!reads_queued && !writes_queued)
526 break; 522 break;
527 523
528 if (pd->iosched.writing) { 524 if (pd->iosched.writing) {
529 if (high_prio_read || (!writes_queued && reads_queued)) { 525 int need_write_seek = 1;
526 spin_lock(&pd->iosched.lock);
527 bio = pd->iosched.write_queue;
528 spin_unlock(&pd->iosched.lock);
529 if (bio && (bio->bi_sector == pd->iosched.last_write))
530 need_write_seek = 0;
531 if (need_write_seek && reads_queued) {
530 if (atomic_read(&pd->cdrw.pending_bios) > 0) { 532 if (atomic_read(&pd->cdrw.pending_bios) > 0) {
531 VPRINTK("pktcdvd: write, waiting\n"); 533 VPRINTK("pktcdvd: write, waiting\n");
532 break; 534 break;
@@ -559,8 +561,10 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
559 561
560 if (bio_data_dir(bio) == READ) 562 if (bio_data_dir(bio) == READ)
561 pd->iosched.successive_reads += bio->bi_size >> 10; 563 pd->iosched.successive_reads += bio->bi_size >> 10;
562 else 564 else {
563 pd->iosched.successive_reads = 0; 565 pd->iosched.successive_reads = 0;
566 pd->iosched.last_write = bio->bi_sector + bio_sectors(bio);
567 }
564 if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) { 568 if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) {
565 if (pd->read_speed == pd->write_speed) { 569 if (pd->read_speed == pd->write_speed) {
566 pd->read_speed = MAX_SPEED; 570 pd->read_speed = MAX_SPEED;
@@ -765,7 +769,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
765 769
766 atomic_inc(&pkt->io_wait); 770 atomic_inc(&pkt->io_wait);
767 bio->bi_rw = READ; 771 bio->bi_rw = READ;
768 pkt_queue_bio(pd, bio, 0); 772 pkt_queue_bio(pd, bio);
769 frames_read++; 773 frames_read++;
770 } 774 }
771 775
@@ -1062,7 +1066,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1062 1066
1063 atomic_set(&pkt->io_wait, 1); 1067 atomic_set(&pkt->io_wait, 1);
1064 pkt->w_bio->bi_rw = WRITE; 1068 pkt->w_bio->bi_rw = WRITE;
1065 pkt_queue_bio(pd, pkt->w_bio, 0); 1069 pkt_queue_bio(pd, pkt->w_bio);
1066} 1070}
1067 1071
1068static void pkt_finish_packet(struct packet_data *pkt, int uptodate) 1072static void pkt_finish_packet(struct packet_data *pkt, int uptodate)
@@ -2120,7 +2124,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
2120 cloned_bio->bi_private = psd; 2124 cloned_bio->bi_private = psd;
2121 cloned_bio->bi_end_io = pkt_end_io_read_cloned; 2125 cloned_bio->bi_end_io = pkt_end_io_read_cloned;
2122 pd->stats.secs_r += bio->bi_size >> 9; 2126 pd->stats.secs_r += bio->bi_size >> 9;
2123 pkt_queue_bio(pd, cloned_bio, 1); 2127 pkt_queue_bio(pd, cloned_bio);
2124 return 0; 2128 return 0;
2125 } 2129 }
2126 2130
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 9075bbb56ad4..f766bc22c6bb 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -576,7 +576,7 @@ static void __exit hci_uart_exit(void)
576#endif 576#endif
577 577
578 /* Release tty registration of line discipline */ 578 /* Release tty registration of line discipline */
579 if ((err = tty_register_ldisc(N_HCI, NULL))) 579 if ((err = tty_unregister_ldisc(N_HCI)))
580 BT_ERR("Can't unregister HCI line discipline (%d)", err); 580 BT_ERR("Can't unregister HCI line discipline (%d)", err);
581} 581}
582 582
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 1dc4259213a6..777bc499bbbd 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -861,13 +861,18 @@ static void change_speed(struct async_struct *info,
861 861
862static void rs_put_char(struct tty_struct *tty, unsigned char ch) 862static void rs_put_char(struct tty_struct *tty, unsigned char ch)
863{ 863{
864 struct async_struct *info = (struct async_struct *)tty->driver_data; 864 struct async_struct *info;
865 unsigned long flags; 865 unsigned long flags;
866 866
867 if (!tty)
868 return;
869
870 info = tty->driver_data;
871
867 if (serial_paranoia_check(info, tty->name, "rs_put_char")) 872 if (serial_paranoia_check(info, tty->name, "rs_put_char"))
868 return; 873 return;
869 874
870 if (!tty || !info->xmit.buf) 875 if (!info->xmit.buf)
871 return; 876 return;
872 877
873 local_irq_save(flags); 878 local_irq_save(flags);
@@ -910,13 +915,18 @@ static void rs_flush_chars(struct tty_struct *tty)
910static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) 915static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count)
911{ 916{
912 int c, ret = 0; 917 int c, ret = 0;
913 struct async_struct *info = (struct async_struct *)tty->driver_data; 918 struct async_struct *info;
914 unsigned long flags; 919 unsigned long flags;
915 920
921 if (!tty)
922 return 0;
923
924 info = tty->driver_data;
925
916 if (serial_paranoia_check(info, tty->name, "rs_write")) 926 if (serial_paranoia_check(info, tty->name, "rs_write"))
917 return 0; 927 return 0;
918 928
919 if (!tty || !info->xmit.buf || !tmp_buf) 929 if (!info->xmit.buf || !tmp_buf)
920 return 0; 930 return 0;
921 931
922 local_save_flags(flags); 932 local_save_flags(flags);
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 88d1ad656e99..e0a53570fea1 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -45,6 +45,7 @@
45#include <asm/semaphore.h> 45#include <asm/semaphore.h>
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include <linux/compat.h>
48 49
49#define IPMI_DEVINTF_VERSION "v33" 50#define IPMI_DEVINTF_VERSION "v33"
50 51
@@ -500,10 +501,205 @@ static int ipmi_ioctl(struct inode *inode,
500 return rv; 501 return rv;
501} 502}
502 503
504#ifdef CONFIG_COMPAT
505
506/*
507 * The following code contains code for supporting 32-bit compatible
508 * ioctls on 64-bit kernels. This allows running 32-bit apps on the
509 * 64-bit kernel
510 */
511#define COMPAT_IPMICTL_SEND_COMMAND \
512 _IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
513#define COMPAT_IPMICTL_SEND_COMMAND_SETTIME \
514 _IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
515#define COMPAT_IPMICTL_RECEIVE_MSG \
516 _IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
517#define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC \
518 _IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
519
520struct compat_ipmi_msg {
521 u8 netfn;
522 u8 cmd;
523 u16 data_len;
524 compat_uptr_t data;
525};
526
527struct compat_ipmi_req {
528 compat_uptr_t addr;
529 compat_uint_t addr_len;
530 compat_long_t msgid;
531 struct compat_ipmi_msg msg;
532};
533
534struct compat_ipmi_recv {
535 compat_int_t recv_type;
536 compat_uptr_t addr;
537 compat_uint_t addr_len;
538 compat_long_t msgid;
539 struct compat_ipmi_msg msg;
540};
541
542struct compat_ipmi_req_settime {
543 struct compat_ipmi_req req;
544 compat_int_t retries;
545 compat_uint_t retry_time_ms;
546};
547
548/*
549 * Define some helper functions for copying IPMI data
550 */
551static long get_compat_ipmi_msg(struct ipmi_msg *p64,
552 struct compat_ipmi_msg __user *p32)
553{
554 compat_uptr_t tmp;
555
556 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
557 __get_user(p64->netfn, &p32->netfn) ||
558 __get_user(p64->cmd, &p32->cmd) ||
559 __get_user(p64->data_len, &p32->data_len) ||
560 __get_user(tmp, &p32->data))
561 return -EFAULT;
562 p64->data = compat_ptr(tmp);
563 return 0;
564}
565
566static long put_compat_ipmi_msg(struct ipmi_msg *p64,
567 struct compat_ipmi_msg __user *p32)
568{
569 if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
570 __put_user(p64->netfn, &p32->netfn) ||
571 __put_user(p64->cmd, &p32->cmd) ||
572 __put_user(p64->data_len, &p32->data_len))
573 return -EFAULT;
574 return 0;
575}
576
577static long get_compat_ipmi_req(struct ipmi_req *p64,
578 struct compat_ipmi_req __user *p32)
579{
580
581 compat_uptr_t tmp;
582
583 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
584 __get_user(tmp, &p32->addr) ||
585 __get_user(p64->addr_len, &p32->addr_len) ||
586 __get_user(p64->msgid, &p32->msgid) ||
587 get_compat_ipmi_msg(&p64->msg, &p32->msg))
588 return -EFAULT;
589 p64->addr = compat_ptr(tmp);
590 return 0;
591}
592
593static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
594 struct compat_ipmi_req_settime __user *p32)
595{
596 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
597 get_compat_ipmi_req(&p64->req, &p32->req) ||
598 __get_user(p64->retries, &p32->retries) ||
599 __get_user(p64->retry_time_ms, &p32->retry_time_ms))
600 return -EFAULT;
601 return 0;
602}
603
604static long get_compat_ipmi_recv(struct ipmi_recv *p64,
605 struct compat_ipmi_recv __user *p32)
606{
607 compat_uptr_t tmp;
608
609 if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
610 __get_user(p64->recv_type, &p32->recv_type) ||
611 __get_user(tmp, &p32->addr) ||
612 __get_user(p64->addr_len, &p32->addr_len) ||
613 __get_user(p64->msgid, &p32->msgid) ||
614 get_compat_ipmi_msg(&p64->msg, &p32->msg))
615 return -EFAULT;
616 p64->addr = compat_ptr(tmp);
617 return 0;
618}
619
620static long put_compat_ipmi_recv(struct ipmi_recv *p64,
621 struct compat_ipmi_recv __user *p32)
622{
623 if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
624 __put_user(p64->recv_type, &p32->recv_type) ||
625 __put_user(p64->addr_len, &p32->addr_len) ||
626 __put_user(p64->msgid, &p32->msgid) ||
627 put_compat_ipmi_msg(&p64->msg, &p32->msg))
628 return -EFAULT;
629 return 0;
630}
631
632/*
633 * Handle compatibility ioctls
634 */
635static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
636 unsigned long arg)
637{
638 int rc;
639 struct ipmi_file_private *priv = filep->private_data;
640
641 switch(cmd) {
642 case COMPAT_IPMICTL_SEND_COMMAND:
643 {
644 struct ipmi_req rp;
645
646 if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
647 return -EFAULT;
648
649 return handle_send_req(priv->user, &rp,
650 priv->default_retries,
651 priv->default_retry_time_ms);
652 }
653 case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
654 {
655 struct ipmi_req_settime sp;
656
657 if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
658 return -EFAULT;
659
660 return handle_send_req(priv->user, &sp.req,
661 sp.retries, sp.retry_time_ms);
662 }
663 case COMPAT_IPMICTL_RECEIVE_MSG:
664 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
665 {
666 struct ipmi_recv *precv64, recv64;
667
668 if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
669 return -EFAULT;
670
671 precv64 = compat_alloc_user_space(sizeof(recv64));
672 if (copy_to_user(precv64, &recv64, sizeof(recv64)))
673 return -EFAULT;
674
675 rc = ipmi_ioctl(filep->f_dentry->d_inode, filep,
676 ((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
677 ? IPMICTL_RECEIVE_MSG
678 : IPMICTL_RECEIVE_MSG_TRUNC),
679 (long) precv64);
680 if (rc != 0)
681 return rc;
682
683 if (copy_from_user(&recv64, precv64, sizeof(recv64)))
684 return -EFAULT;
685
686 if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
687 return -EFAULT;
688
689 return rc;
690 }
691 default:
692 return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg);
693 }
694}
695#endif
503 696
504static struct file_operations ipmi_fops = { 697static struct file_operations ipmi_fops = {
505 .owner = THIS_MODULE, 698 .owner = THIS_MODULE,
506 .ioctl = ipmi_ioctl, 699 .ioctl = ipmi_ioctl,
700#ifdef CONFIG_COMPAT
701 .compat_ioctl = compat_ipmi_ioctl,
702#endif
507 .open = ipmi_open, 703 .open = ipmi_open,
508 .release = ipmi_release, 704 .release = ipmi_release,
509 .fasync = ipmi_fasync, 705 .fasync = ipmi_fasync,
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 0c81652eaba6..1813d0d198f1 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -54,7 +54,9 @@ static int ipmi_init_msghandler(void);
54 54
55static int initialized = 0; 55static int initialized = 0;
56 56
57static struct proc_dir_entry *proc_ipmi_root = NULL; 57#ifdef CONFIG_PROC_FS
58struct proc_dir_entry *proc_ipmi_root = NULL;
59#endif /* CONFIG_PROC_FS */
58 60
59#define MAX_EVENTS_IN_QUEUE 25 61#define MAX_EVENTS_IN_QUEUE 25
60 62
@@ -124,11 +126,13 @@ struct ipmi_channel
124 unsigned char protocol; 126 unsigned char protocol;
125}; 127};
126 128
129#ifdef CONFIG_PROC_FS
127struct ipmi_proc_entry 130struct ipmi_proc_entry
128{ 131{
129 char *name; 132 char *name;
130 struct ipmi_proc_entry *next; 133 struct ipmi_proc_entry *next;
131}; 134};
135#endif
132 136
133#define IPMI_IPMB_NUM_SEQ 64 137#define IPMI_IPMB_NUM_SEQ 64
134#define IPMI_MAX_CHANNELS 8 138#define IPMI_MAX_CHANNELS 8
@@ -156,10 +160,13 @@ struct ipmi_smi
156 struct ipmi_smi_handlers *handlers; 160 struct ipmi_smi_handlers *handlers;
157 void *send_info; 161 void *send_info;
158 162
163#ifdef CONFIG_PROC_FS
159 /* A list of proc entries for this interface. This does not 164 /* A list of proc entries for this interface. This does not
160 need a lock, only one thread creates it and only one thread 165 need a lock, only one thread creates it and only one thread
161 destroys it. */ 166 destroys it. */
167 spinlock_t proc_entry_lock;
162 struct ipmi_proc_entry *proc_entries; 168 struct ipmi_proc_entry *proc_entries;
169#endif
163 170
164 /* A table of sequence numbers for this interface. We use the 171 /* A table of sequence numbers for this interface. We use the
165 sequence numbers for IPMB messages that go out of the 172 sequence numbers for IPMB messages that go out of the
@@ -1470,8 +1477,9 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
1470 read_proc_t *read_proc, write_proc_t *write_proc, 1477 read_proc_t *read_proc, write_proc_t *write_proc,
1471 void *data, struct module *owner) 1478 void *data, struct module *owner)
1472{ 1479{
1473 struct proc_dir_entry *file;
1474 int rv = 0; 1480 int rv = 0;
1481#ifdef CONFIG_PROC_FS
1482 struct proc_dir_entry *file;
1475 struct ipmi_proc_entry *entry; 1483 struct ipmi_proc_entry *entry;
1476 1484
1477 /* Create a list element. */ 1485 /* Create a list element. */
@@ -1497,10 +1505,13 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
1497 file->write_proc = write_proc; 1505 file->write_proc = write_proc;
1498 file->owner = owner; 1506 file->owner = owner;
1499 1507
1508 spin_lock(&smi->proc_entry_lock);
1500 /* Stick it on the list. */ 1509 /* Stick it on the list. */
1501 entry->next = smi->proc_entries; 1510 entry->next = smi->proc_entries;
1502 smi->proc_entries = entry; 1511 smi->proc_entries = entry;
1512 spin_unlock(&smi->proc_entry_lock);
1503 } 1513 }
1514#endif /* CONFIG_PROC_FS */
1504 1515
1505 return rv; 1516 return rv;
1506} 1517}
@@ -1509,6 +1520,7 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
1509{ 1520{
1510 int rv = 0; 1521 int rv = 0;
1511 1522
1523#ifdef CONFIG_PROC_FS
1512 sprintf(smi->proc_dir_name, "%d", num); 1524 sprintf(smi->proc_dir_name, "%d", num);
1513 smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root); 1525 smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
1514 if (!smi->proc_dir) 1526 if (!smi->proc_dir)
@@ -1531,14 +1543,17 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
1531 rv = ipmi_smi_add_proc_entry(smi, "version", 1543 rv = ipmi_smi_add_proc_entry(smi, "version",
1532 version_file_read_proc, NULL, 1544 version_file_read_proc, NULL,
1533 smi, THIS_MODULE); 1545 smi, THIS_MODULE);
1546#endif /* CONFIG_PROC_FS */
1534 1547
1535 return rv; 1548 return rv;
1536} 1549}
1537 1550
1538static void remove_proc_entries(ipmi_smi_t smi) 1551static void remove_proc_entries(ipmi_smi_t smi)
1539{ 1552{
1553#ifdef CONFIG_PROC_FS
1540 struct ipmi_proc_entry *entry; 1554 struct ipmi_proc_entry *entry;
1541 1555
1556 spin_lock(&smi->proc_entry_lock);
1542 while (smi->proc_entries) { 1557 while (smi->proc_entries) {
1543 entry = smi->proc_entries; 1558 entry = smi->proc_entries;
1544 smi->proc_entries = entry->next; 1559 smi->proc_entries = entry->next;
@@ -1547,7 +1562,9 @@ static void remove_proc_entries(ipmi_smi_t smi)
1547 kfree(entry->name); 1562 kfree(entry->name);
1548 kfree(entry); 1563 kfree(entry);
1549 } 1564 }
1565 spin_unlock(&smi->proc_entry_lock);
1550 remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); 1566 remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
1567#endif /* CONFIG_PROC_FS */
1551} 1568}
1552 1569
1553static int 1570static int
@@ -1694,6 +1711,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
1694 new_intf->seq_table[j].seqid = 0; 1711 new_intf->seq_table[j].seqid = 0;
1695 } 1712 }
1696 new_intf->curr_seq = 0; 1713 new_intf->curr_seq = 0;
1714#ifdef CONFIG_PROC_FS
1715 spin_lock_init(&(new_intf->proc_entry_lock));
1716#endif
1697 spin_lock_init(&(new_intf->waiting_msgs_lock)); 1717 spin_lock_init(&(new_intf->waiting_msgs_lock));
1698 INIT_LIST_HEAD(&(new_intf->waiting_msgs)); 1718 INIT_LIST_HEAD(&(new_intf->waiting_msgs));
1699 spin_lock_init(&(new_intf->events_lock)); 1719 spin_lock_init(&(new_intf->events_lock));
@@ -2747,16 +2767,13 @@ static struct timer_list ipmi_timer;
2747 the queue and this silliness can go away. */ 2767 the queue and this silliness can go away. */
2748#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME)) 2768#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
2749 2769
2750static volatile int stop_operation = 0; 2770static atomic_t stop_operation;
2751static volatile int timer_stopped = 0;
2752static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME; 2771static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
2753 2772
2754static void ipmi_timeout(unsigned long data) 2773static void ipmi_timeout(unsigned long data)
2755{ 2774{
2756 if (stop_operation) { 2775 if (atomic_read(&stop_operation))
2757 timer_stopped = 1;
2758 return; 2776 return;
2759 }
2760 2777
2761 ticks_to_req_ev--; 2778 ticks_to_req_ev--;
2762 if (ticks_to_req_ev == 0) { 2779 if (ticks_to_req_ev == 0) {
@@ -2766,8 +2783,7 @@ static void ipmi_timeout(unsigned long data)
2766 2783
2767 ipmi_timeout_handler(IPMI_TIMEOUT_TIME); 2784 ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
2768 2785
2769 ipmi_timer.expires += IPMI_TIMEOUT_JIFFIES; 2786 mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
2770 add_timer(&ipmi_timer);
2771} 2787}
2772 2788
2773 2789
@@ -3089,6 +3105,7 @@ static int ipmi_init_msghandler(void)
3089 ipmi_interfaces[i] = NULL; 3105 ipmi_interfaces[i] = NULL;
3090 } 3106 }
3091 3107
3108#ifdef CONFIG_PROC_FS
3092 proc_ipmi_root = proc_mkdir("ipmi", NULL); 3109 proc_ipmi_root = proc_mkdir("ipmi", NULL);
3093 if (!proc_ipmi_root) { 3110 if (!proc_ipmi_root) {
3094 printk(KERN_ERR PFX "Unable to create IPMI proc dir"); 3111 printk(KERN_ERR PFX "Unable to create IPMI proc dir");
@@ -3096,6 +3113,7 @@ static int ipmi_init_msghandler(void)
3096 } 3113 }
3097 3114
3098 proc_ipmi_root->owner = THIS_MODULE; 3115 proc_ipmi_root->owner = THIS_MODULE;
3116#endif /* CONFIG_PROC_FS */
3099 3117
3100 init_timer(&ipmi_timer); 3118 init_timer(&ipmi_timer);
3101 ipmi_timer.data = 0; 3119 ipmi_timer.data = 0;
@@ -3130,13 +3148,12 @@ static __exit void cleanup_ipmi(void)
3130 3148
3131 /* Tell the timer to stop, then wait for it to stop. This avoids 3149 /* Tell the timer to stop, then wait for it to stop. This avoids
3132 problems with race conditions removing the timer here. */ 3150 problems with race conditions removing the timer here. */
3133 stop_operation = 1; 3151 atomic_inc(&stop_operation);
3134 while (!timer_stopped) { 3152 del_timer_sync(&ipmi_timer);
3135 set_current_state(TASK_UNINTERRUPTIBLE);
3136 schedule_timeout(1);
3137 }
3138 3153
3154#ifdef CONFIG_PROC_FS
3139 remove_proc_entry(proc_ipmi_root->name, &proc_root); 3155 remove_proc_entry(proc_ipmi_root->name, &proc_root);
3156#endif /* CONFIG_PROC_FS */
3140 3157
3141 initialized = 0; 3158 initialized = 0;
3142 3159
@@ -3177,4 +3194,5 @@ EXPORT_SYMBOL(ipmi_get_my_address);
3177EXPORT_SYMBOL(ipmi_set_my_LUN); 3194EXPORT_SYMBOL(ipmi_set_my_LUN);
3178EXPORT_SYMBOL(ipmi_get_my_LUN); 3195EXPORT_SYMBOL(ipmi_get_my_LUN);
3179EXPORT_SYMBOL(ipmi_smi_add_proc_entry); 3196EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
3197EXPORT_SYMBOL(proc_ipmi_root);
3180EXPORT_SYMBOL(ipmi_user_set_run_to_completion); 3198EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index cb5cdc6f14bf..f951c30236c9 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -31,10 +31,13 @@
31 * with this program; if not, write to the Free Software Foundation, Inc., 31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 */ 33 */
34#include <asm/semaphore.h> 34#include <linux/config.h>
35#include <linux/kdev_t.h>
36#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/proc_fs.h>
37#include <linux/string.h> 38#include <linux/string.h>
39#include <linux/completion.h>
40#include <linux/kdev_t.h>
38#include <linux/ipmi.h> 41#include <linux/ipmi.h>
39#include <linux/ipmi_smi.h> 42#include <linux/ipmi_smi.h>
40 43
@@ -44,6 +47,18 @@
44/* Where to we insert our poweroff function? */ 47/* Where to we insert our poweroff function? */
45extern void (*pm_power_off)(void); 48extern void (*pm_power_off)(void);
46 49
50/* Definitions for controlling power off (if the system supports it). It
51 * conveniently matches the IPMI chassis control values. */
52#define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */
53#define IPMI_CHASSIS_POWER_CYCLE 0x02 /* power cycle */
54
55/* the IPMI data command */
56static int poweroff_control = IPMI_CHASSIS_POWER_DOWN;
57
58/* parameter definition to allow user to flag power cycle */
59module_param(poweroff_control, int, IPMI_CHASSIS_POWER_DOWN);
60MODULE_PARM_DESC(poweroff_control, " Set to 2 to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
61
47/* Stuff from the get device id command. */ 62/* Stuff from the get device id command. */
48static unsigned int mfg_id; 63static unsigned int mfg_id;
49static unsigned int prod_id; 64static unsigned int prod_id;
@@ -75,10 +90,10 @@ static struct ipmi_recv_msg halt_recv_msg =
75 90
76static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data) 91static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
77{ 92{
78 struct semaphore *sem = recv_msg->user_msg_data; 93 struct completion *comp = recv_msg->user_msg_data;
79 94
80 if (sem) 95 if (comp)
81 up(sem); 96 complete(comp);
82} 97}
83 98
84static struct ipmi_user_hndl ipmi_poweroff_handler = 99static struct ipmi_user_hndl ipmi_poweroff_handler =
@@ -91,27 +106,27 @@ static int ipmi_request_wait_for_response(ipmi_user_t user,
91 struct ipmi_addr *addr, 106 struct ipmi_addr *addr,
92 struct kernel_ipmi_msg *send_msg) 107 struct kernel_ipmi_msg *send_msg)
93{ 108{
94 int rv; 109 int rv;
95 struct semaphore sem; 110 struct completion comp;
96 111
97 sema_init (&sem, 0); 112 init_completion(&comp);
98 113
99 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &sem, 114 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
100 &halt_smi_msg, &halt_recv_msg, 0); 115 &halt_smi_msg, &halt_recv_msg, 0);
101 if (rv) 116 if (rv)
102 return rv; 117 return rv;
103 118
104 down (&sem); 119 wait_for_completion(&comp);
105 120
106 return halt_recv_msg.msg.data[0]; 121 return halt_recv_msg.msg.data[0];
107} 122}
108 123
109/* We are in run-to-completion mode, no semaphore is desired. */ 124/* We are in run-to-completion mode, no completion is desired. */
110static int ipmi_request_in_rc_mode(ipmi_user_t user, 125static int ipmi_request_in_rc_mode(ipmi_user_t user,
111 struct ipmi_addr *addr, 126 struct ipmi_addr *addr,
112 struct kernel_ipmi_msg *send_msg) 127 struct kernel_ipmi_msg *send_msg)
113{ 128{
114 int rv; 129 int rv;
115 130
116 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL, 131 rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
117 &halt_smi_msg, &halt_recv_msg, 0); 132 &halt_smi_msg, &halt_recv_msg, 0);
@@ -349,26 +364,38 @@ static void ipmi_poweroff_chassis (ipmi_user_t user)
349 smi_addr.channel = IPMI_BMC_CHANNEL; 364 smi_addr.channel = IPMI_BMC_CHANNEL;
350 smi_addr.lun = 0; 365 smi_addr.lun = 0;
351 366
352 printk(KERN_INFO PFX "Powering down via IPMI chassis control command\n"); 367 powercyclefailed:
368 printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n",
369 ((poweroff_control != IPMI_CHASSIS_POWER_CYCLE) ? "down" : "cycle"));
353 370
354 /* 371 /*
355 * Power down 372 * Power down
356 */ 373 */
357 send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST; 374 send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
358 send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD; 375 send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
359 data[0] = 0; /* Power down */ 376 data[0] = poweroff_control;
360 send_msg.data = data; 377 send_msg.data = data;
361 send_msg.data_len = sizeof(data); 378 send_msg.data_len = sizeof(data);
362 rv = ipmi_request_in_rc_mode(user, 379 rv = ipmi_request_in_rc_mode(user,
363 (struct ipmi_addr *) &smi_addr, 380 (struct ipmi_addr *) &smi_addr,
364 &send_msg); 381 &send_msg);
365 if (rv) { 382 if (rv) {
366 printk(KERN_ERR PFX "Unable to send chassis powerdown message," 383 switch (poweroff_control) {
367 " IPMI error 0x%x\n", rv); 384 case IPMI_CHASSIS_POWER_CYCLE:
368 goto out; 385 /* power cycle failed, default to power down */
386 printk(KERN_ERR PFX "Unable to send chassis power " \
387 "cycle message, IPMI error 0x%x\n", rv);
388 poweroff_control = IPMI_CHASSIS_POWER_DOWN;
389 goto powercyclefailed;
390
391 case IPMI_CHASSIS_POWER_DOWN:
392 default:
393 printk(KERN_ERR PFX "Unable to send chassis power " \
394 "down message, IPMI error 0x%x\n", rv);
395 break;
396 }
369 } 397 }
370 398
371 out:
372 return; 399 return;
373} 400}
374 401
@@ -430,7 +457,8 @@ static void ipmi_po_new_smi(int if_num)
430 if (ready) 457 if (ready)
431 return; 458 return;
432 459
433 rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL, &ipmi_user); 460 rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
461 &ipmi_user);
434 if (rv) { 462 if (rv) {
435 printk(KERN_ERR PFX "could not create IPMI user, error %d\n", 463 printk(KERN_ERR PFX "could not create IPMI user, error %d\n",
436 rv); 464 rv);
@@ -509,21 +537,84 @@ static struct ipmi_smi_watcher smi_watcher =
509}; 537};
510 538
511 539
540#ifdef CONFIG_PROC_FS
541/* displays properties to proc */
542static int proc_read_chassctrl(char *page, char **start, off_t off, int count,
543 int *eof, void *data)
544{
545 return sprintf(page, "%d\t[ 0=powerdown 2=powercycle ]\n",
546 poweroff_control);
547}
548
549/* process property writes from proc */
550static int proc_write_chassctrl(struct file *file, const char *buffer,
551 unsigned long count, void *data)
552{
553 int rv = count;
554 unsigned int newval = 0;
555
556 sscanf(buffer, "%d", &newval);
557 switch (newval) {
558 case IPMI_CHASSIS_POWER_CYCLE:
559 printk(KERN_INFO PFX "power cycle is now enabled\n");
560 poweroff_control = newval;
561 break;
562
563 case IPMI_CHASSIS_POWER_DOWN:
564 poweroff_control = IPMI_CHASSIS_POWER_DOWN;
565 break;
566
567 default:
568 rv = -EINVAL;
569 break;
570 }
571
572 return rv;
573}
574#endif /* CONFIG_PROC_FS */
575
512/* 576/*
513 * Startup and shutdown functions. 577 * Startup and shutdown functions.
514 */ 578 */
515static int ipmi_poweroff_init (void) 579static int ipmi_poweroff_init (void)
516{ 580{
517 int rv; 581 int rv;
582 struct proc_dir_entry *file;
518 583
519 printk ("Copyright (C) 2004 MontaVista Software -" 584 printk ("Copyright (C) 2004 MontaVista Software -"
520 " IPMI Powerdown via sys_reboot version " 585 " IPMI Powerdown via sys_reboot version "
521 IPMI_POWEROFF_VERSION ".\n"); 586 IPMI_POWEROFF_VERSION ".\n");
522 587
588 switch (poweroff_control) {
589 case IPMI_CHASSIS_POWER_CYCLE:
590 printk(KERN_INFO PFX "Power cycle is enabled.\n");
591 break;
592
593 case IPMI_CHASSIS_POWER_DOWN:
594 default:
595 poweroff_control = IPMI_CHASSIS_POWER_DOWN;
596 break;
597 }
598
523 rv = ipmi_smi_watcher_register(&smi_watcher); 599 rv = ipmi_smi_watcher_register(&smi_watcher);
524 if (rv) 600 if (rv) {
525 printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); 601 printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
602 goto out_err;
603 }
604
605#ifdef CONFIG_PROC_FS
606 file = create_proc_entry("poweroff_control", 0, proc_ipmi_root);
607 if (!file) {
608 printk(KERN_ERR PFX "Unable to create proc power control\n");
609 } else {
610 file->nlink = 1;
611 file->read_proc = proc_read_chassctrl;
612 file->write_proc = proc_write_chassctrl;
613 file->owner = THIS_MODULE;
614 }
615#endif
526 616
617 out_err:
527 return rv; 618 return rv;
528} 619}
529 620
@@ -532,6 +623,10 @@ static __exit void ipmi_poweroff_cleanup(void)
532{ 623{
533 int rv; 624 int rv;
534 625
626#ifdef CONFIG_PROC_FS
627 remove_proc_entry("poweroff_control", proc_ipmi_root);
628#endif
629
535 ipmi_smi_watcher_unregister(&smi_watcher); 630 ipmi_smi_watcher_unregister(&smi_watcher);
536 631
537 if (ready) { 632 if (ready) {
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index b3dbff1cf967..5079beda69b5 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -960,7 +960,7 @@ static char hdlc_unregister_fail[] __exitdata =
960static void __exit n_hdlc_exit(void) 960static void __exit n_hdlc_exit(void)
961{ 961{
962 /* Release tty registration of line discipline */ 962 /* Release tty registration of line discipline */
963 int status = tty_register_ldisc(N_HDLC, NULL); 963 int status = tty_unregister_ldisc(N_HDLC);
964 964
965 if (status) 965 if (status)
966 printk(hdlc_unregister_fail, status); 966 printk(hdlc_unregister_fail, status);
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 3883073ab48f..2291a87e8ada 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -200,7 +200,7 @@ static void __exit r3964_exit(void)
200 200
201 TRACE_M ("cleanup_module()"); 201 TRACE_M ("cleanup_module()");
202 202
203 status=tty_register_ldisc(N_R3964, NULL); 203 status=tty_unregister_ldisc(N_R3964);
204 204
205 if(status!=0) 205 if(status!=0)
206 { 206 {
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 8ce508b29865..5c843c9bf819 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -19,7 +19,7 @@
19 * 19 *
20 * Note, the TPM chip is not interrupt driven (only polling) 20 * Note, the TPM chip is not interrupt driven (only polling)
21 * and can have very long timeouts (minutes!). Hence the unusual 21 * and can have very long timeouts (minutes!). Hence the unusual
22 * calls to schedule_timeout. 22 * calls to msleep.
23 * 23 *
24 */ 24 */
25 25
@@ -28,19 +28,16 @@
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include "tpm.h" 29#include "tpm.h"
30 30
31#define TPM_MINOR 224 /* officially assigned */ 31enum tpm_const {
32 32 TPM_MINOR = 224, /* officially assigned */
33#define TPM_BUFSIZE 2048 33 TPM_BUFSIZE = 2048,
34 34 TPM_NUM_DEVICES = 256,
35/* PCI configuration addresses */ 35 TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
36#define PCI_GEN_PMCON_1 0xA0 36};
37#define PCI_GEN1_DEC 0xE4
38#define PCI_LPC_EN 0xE6
39#define PCI_GEN2_DEC 0xEC
40 37
41static LIST_HEAD(tpm_chip_list); 38static LIST_HEAD(tpm_chip_list);
42static DEFINE_SPINLOCK(driver_lock); 39static DEFINE_SPINLOCK(driver_lock);
43static int dev_mask[32]; 40static int dev_mask[TPM_NUM_MASK_ENTRIES];
44 41
45static void user_reader_timeout(unsigned long ptr) 42static void user_reader_timeout(unsigned long ptr)
46{ 43{
@@ -52,92 +49,17 @@ static void user_reader_timeout(unsigned long ptr)
52 up(&chip->buffer_mutex); 49 up(&chip->buffer_mutex);
53} 50}
54 51
55void tpm_time_expired(unsigned long ptr)
56{
57 int *exp = (int *) ptr;
58 *exp = 1;
59}
60
61EXPORT_SYMBOL_GPL(tpm_time_expired);
62
63/*
64 * Initialize the LPC bus and enable the TPM ports
65 */
66int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base)
67{
68 u32 lpcenable, tmp;
69 int is_lpcm = 0;
70
71 switch (pci_dev->vendor) {
72 case PCI_VENDOR_ID_INTEL:
73 switch (pci_dev->device) {
74 case PCI_DEVICE_ID_INTEL_82801CA_12:
75 case PCI_DEVICE_ID_INTEL_82801DB_12:
76 is_lpcm = 1;
77 break;
78 }
79 /* init ICH (enable LPC) */
80 pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable);
81 lpcenable |= 0x20000000;
82 pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable);
83
84 if (is_lpcm) {
85 pci_read_config_dword(pci_dev, PCI_GEN1_DEC,
86 &lpcenable);
87 if ((lpcenable & 0x20000000) == 0) {
88 dev_err(&pci_dev->dev,
89 "cannot enable LPC\n");
90 return -ENODEV;
91 }
92 }
93
94 /* initialize TPM registers */
95 pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp);
96
97 if (!is_lpcm)
98 tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0);
99 else
100 tmp =
101 (tmp & 0xFFFF0000) | (base & 0xFFF0) |
102 0x00000001;
103
104 pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp);
105
106 if (is_lpcm) {
107 pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1,
108 &tmp);
109 tmp |= 0x00000004; /* enable CLKRUN */
110 pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1,
111 tmp);
112 }
113 tpm_write_index(0x0D, 0x55); /* unlock 4F */
114 tpm_write_index(0x0A, 0x00); /* int disable */
115 tpm_write_index(0x08, base); /* base addr lo */
116 tpm_write_index(0x09, (base & 0xFF00) >> 8); /* base addr hi */
117 tpm_write_index(0x0D, 0xAA); /* lock 4F */
118 break;
119 case PCI_VENDOR_ID_AMD:
120 /* nothing yet */
121 break;
122 }
123
124 return 0;
125}
126
127EXPORT_SYMBOL_GPL(tpm_lpc_bus_init);
128
129/* 52/*
130 * Internal kernel interface to transmit TPM commands 53 * Internal kernel interface to transmit TPM commands
131 */ 54 */
132static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, 55static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
133 size_t bufsiz) 56 size_t bufsiz)
134{ 57{
135 ssize_t len; 58 ssize_t rc;
136 u32 count; 59 u32 count;
137 __be32 *native_size; 60 unsigned long stop;
138 61
139 native_size = (__force __be32 *) (buf + 2); 62 count = be32_to_cpu(*((__be32 *) (buf + 2)));
140 count = be32_to_cpu(*native_size);
141 63
142 if (count == 0) 64 if (count == 0)
143 return -ENODATA; 65 return -ENODATA;
@@ -149,53 +71,49 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
149 71
150 down(&chip->tpm_mutex); 72 down(&chip->tpm_mutex);
151 73
152 if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { 74 if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
153 dev_err(&chip->pci_dev->dev, 75 dev_err(&chip->pci_dev->dev,
154 "tpm_transmit: tpm_send: error %zd\n", len); 76 "tpm_transmit: tpm_send: error %zd\n", rc);
155 return len; 77 goto out;
156 } 78 }
157 79
158 down(&chip->timer_manipulation_mutex); 80 stop = jiffies + 2 * 60 * HZ;
159 chip->time_expired = 0;
160 init_timer(&chip->device_timer);
161 chip->device_timer.function = tpm_time_expired;
162 chip->device_timer.expires = jiffies + 2 * 60 * HZ;
163 chip->device_timer.data = (unsigned long) &chip->time_expired;
164 add_timer(&chip->device_timer);
165 up(&chip->timer_manipulation_mutex);
166
167 do { 81 do {
168 u8 status = inb(chip->vendor->base + 1); 82 u8 status = inb(chip->vendor->base + 1);
169 if ((status & chip->vendor->req_complete_mask) == 83 if ((status & chip->vendor->req_complete_mask) ==
170 chip->vendor->req_complete_val) { 84 chip->vendor->req_complete_val) {
171 down(&chip->timer_manipulation_mutex);
172 del_singleshot_timer_sync(&chip->device_timer);
173 up(&chip->timer_manipulation_mutex);
174 goto out_recv; 85 goto out_recv;
175 } 86 }
176 set_current_state(TASK_UNINTERRUPTIBLE); 87
177 schedule_timeout(TPM_TIMEOUT); 88 if ((status == chip->vendor->req_canceled)) {
89 dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
90 rc = -ECANCELED;
91 goto out;
92 }
93
94 msleep(TPM_TIMEOUT); /* CHECK */
178 rmb(); 95 rmb();
179 } while (!chip->time_expired); 96 } while (time_before(jiffies, stop));
180 97
181 98
182 chip->vendor->cancel(chip); 99 chip->vendor->cancel(chip);
183 dev_err(&chip->pci_dev->dev, "Time expired\n"); 100 dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
184 up(&chip->tpm_mutex); 101 rc = -ETIME;
185 return -EIO; 102 goto out;
186 103
187out_recv: 104out_recv:
188 len = chip->vendor->recv(chip, (u8 *) buf, bufsiz); 105 rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
189 if (len < 0) 106 if (rc < 0)
190 dev_err(&chip->pci_dev->dev, 107 dev_err(&chip->pci_dev->dev,
191 "tpm_transmit: tpm_recv: error %zd\n", len); 108 "tpm_transmit: tpm_recv: error %zd\n", rc);
109out:
192 up(&chip->tpm_mutex); 110 up(&chip->tpm_mutex);
193 return len; 111 return rc;
194} 112}
195 113
196#define TPM_DIGEST_SIZE 20 114#define TPM_DIGEST_SIZE 20
197#define CAP_PCR_RESULT_SIZE 18 115#define CAP_PCR_RESULT_SIZE 18
198static u8 cap_pcr[] = { 116static const u8 cap_pcr[] = {
199 0, 193, /* TPM_TAG_RQU_COMMAND */ 117 0, 193, /* TPM_TAG_RQU_COMMAND */
200 0, 0, 0, 22, /* length */ 118 0, 0, 0, 22, /* length */
201 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 119 0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -205,75 +123,94 @@ static u8 cap_pcr[] = {
205}; 123};
206 124
207#define READ_PCR_RESULT_SIZE 30 125#define READ_PCR_RESULT_SIZE 30
208static u8 pcrread[] = { 126static const u8 pcrread[] = {
209 0, 193, /* TPM_TAG_RQU_COMMAND */ 127 0, 193, /* TPM_TAG_RQU_COMMAND */
210 0, 0, 0, 14, /* length */ 128 0, 0, 0, 14, /* length */
211 0, 0, 0, 21, /* TPM_ORD_PcrRead */ 129 0, 0, 0, 21, /* TPM_ORD_PcrRead */
212 0, 0, 0, 0 /* PCR index */ 130 0, 0, 0, 0 /* PCR index */
213}; 131};
214 132
215static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) 133ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
134 char *buf)
216{ 135{
217 u8 data[READ_PCR_RESULT_SIZE]; 136 u8 data[READ_PCR_RESULT_SIZE];
218 ssize_t len; 137 ssize_t len;
219 int i, j, index, num_pcrs; 138 int i, j, num_pcrs;
139 __be32 index;
220 char *str = buf; 140 char *str = buf;
221 141
222 struct tpm_chip *chip = 142 struct tpm_chip *chip =
223 pci_get_drvdata(container_of(dev, struct pci_dev, dev)); 143 pci_get_drvdata(to_pci_dev(dev));
224 if (chip == NULL) 144 if (chip == NULL)
225 return -ENODEV; 145 return -ENODEV;
226 146
227 memcpy(data, cap_pcr, sizeof(cap_pcr)); 147 memcpy(data, cap_pcr, sizeof(cap_pcr));
228 if ((len = tpm_transmit(chip, data, sizeof(data))) 148 if ((len = tpm_transmit(chip, data, sizeof(data)))
229 < CAP_PCR_RESULT_SIZE) 149 < CAP_PCR_RESULT_SIZE) {
230 return len; 150 dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
151 "attempting to determine the number of PCRS\n",
152 be32_to_cpu(*((__be32 *) (data + 6))));
153 return 0;
154 }
231 155
232 num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14))); 156 num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
233 157
234 for (i = 0; i < num_pcrs; i++) { 158 for (i = 0; i < num_pcrs; i++) {
235 memcpy(data, pcrread, sizeof(pcrread)); 159 memcpy(data, pcrread, sizeof(pcrread));
236 index = cpu_to_be32(i); 160 index = cpu_to_be32(i);
237 memcpy(data + 10, &index, 4); 161 memcpy(data + 10, &index, 4);
238 if ((len = tpm_transmit(chip, data, sizeof(data))) 162 if ((len = tpm_transmit(chip, data, sizeof(data)))
239 < READ_PCR_RESULT_SIZE) 163 < READ_PCR_RESULT_SIZE){
240 return len; 164 dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
165 " attempting to read PCR %d of %d\n",
166 be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
167 goto out;
168 }
241 str += sprintf(str, "PCR-%02d: ", i); 169 str += sprintf(str, "PCR-%02d: ", i);
242 for (j = 0; j < TPM_DIGEST_SIZE; j++) 170 for (j = 0; j < TPM_DIGEST_SIZE; j++)
243 str += sprintf(str, "%02X ", *(data + 10 + j)); 171 str += sprintf(str, "%02X ", *(data + 10 + j));
244 str += sprintf(str, "\n"); 172 str += sprintf(str, "\n");
245 } 173 }
174out:
246 return str - buf; 175 return str - buf;
247} 176}
248 177EXPORT_SYMBOL_GPL(tpm_show_pcrs);
249static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
250 178
251#define READ_PUBEK_RESULT_SIZE 314 179#define READ_PUBEK_RESULT_SIZE 314
252static u8 readpubek[] = { 180static const u8 readpubek[] = {
253 0, 193, /* TPM_TAG_RQU_COMMAND */ 181 0, 193, /* TPM_TAG_RQU_COMMAND */
254 0, 0, 0, 30, /* length */ 182 0, 0, 0, 30, /* length */
255 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ 183 0, 0, 0, 124, /* TPM_ORD_ReadPubek */
256}; 184};
257 185
258static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf) 186ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
187 char *buf)
259{ 188{
260 u8 data[READ_PUBEK_RESULT_SIZE]; 189 u8 *data;
261 ssize_t len; 190 ssize_t len;
262 __be32 *native_val; 191 int i, rc;
263 int i;
264 char *str = buf; 192 char *str = buf;
265 193
266 struct tpm_chip *chip = 194 struct tpm_chip *chip =
267 pci_get_drvdata(container_of(dev, struct pci_dev, dev)); 195 pci_get_drvdata(to_pci_dev(dev));
268 if (chip == NULL) 196 if (chip == NULL)
269 return -ENODEV; 197 return -ENODEV;
270 198
199 data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
200 if (!data)
201 return -ENOMEM;
202
271 memcpy(data, readpubek, sizeof(readpubek)); 203 memcpy(data, readpubek, sizeof(readpubek));
272 memset(data + sizeof(readpubek), 0, 20); /* zero nonce */ 204 memset(data + sizeof(readpubek), 0, 20); /* zero nonce */
273 205
274 if ((len = tpm_transmit(chip, data, sizeof(data))) < 206 if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
275 READ_PUBEK_RESULT_SIZE) 207 READ_PUBEK_RESULT_SIZE) {
276 return len; 208 dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
209 "attempting to read the PUBEK\n",
210 be32_to_cpu(*((__be32 *) (data + 6))));
211 rc = 0;
212 goto out;
213 }
277 214
278 /* 215 /*
279 ignore header 10 bytes 216 ignore header 10 bytes
@@ -286,8 +223,6 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha
286 ignore checksum 20 bytes 223 ignore checksum 20 bytes
287 */ 224 */
288 225
289 native_val = (__force __be32 *) (data + 34);
290
291 str += 226 str +=
292 sprintf(str, 227 sprintf(str,
293 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n" 228 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -298,21 +233,23 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha
298 data[15], data[16], data[17], data[22], data[23], 233 data[15], data[16], data[17], data[22], data[23],
299 data[24], data[25], data[26], data[27], data[28], 234 data[24], data[25], data[26], data[27], data[28],
300 data[29], data[30], data[31], data[32], data[33], 235 data[29], data[30], data[31], data[32], data[33],
301 be32_to_cpu(*native_val) 236 be32_to_cpu(*((__be32 *) (data + 32))));
302 );
303 237
304 for (i = 0; i < 256; i++) { 238 for (i = 0; i < 256; i++) {
305 str += sprintf(str, "%02X ", data[i + 39]); 239 str += sprintf(str, "%02X ", data[i + 39]);
306 if ((i + 1) % 16 == 0) 240 if ((i + 1) % 16 == 0)
307 str += sprintf(str, "\n"); 241 str += sprintf(str, "\n");
308 } 242 }
309 return str - buf; 243 rc = str - buf;
244out:
245 kfree(data);
246 return rc;
310} 247}
311 248
312static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL); 249EXPORT_SYMBOL_GPL(tpm_show_pubek);
313 250
314#define CAP_VER_RESULT_SIZE 18 251#define CAP_VER_RESULT_SIZE 18
315static u8 cap_version[] = { 252static const u8 cap_version[] = {
316 0, 193, /* TPM_TAG_RQU_COMMAND */ 253 0, 193, /* TPM_TAG_RQU_COMMAND */
317 0, 0, 0, 18, /* length */ 254 0, 0, 0, 18, /* length */
318 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 255 0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -321,7 +258,7 @@ static u8 cap_version[] = {
321}; 258};
322 259
323#define CAP_MANUFACTURER_RESULT_SIZE 18 260#define CAP_MANUFACTURER_RESULT_SIZE 18
324static u8 cap_manufacturer[] = { 261static const u8 cap_manufacturer[] = {
325 0, 193, /* TPM_TAG_RQU_COMMAND */ 262 0, 193, /* TPM_TAG_RQU_COMMAND */
326 0, 0, 0, 22, /* length */ 263 0, 0, 0, 22, /* length */
327 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 264 0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -330,14 +267,15 @@ static u8 cap_manufacturer[] = {
330 0, 0, 1, 3 267 0, 0, 1, 3
331}; 268};
332 269
333static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf) 270ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
271 char *buf)
334{ 272{
335 u8 data[READ_PUBEK_RESULT_SIZE]; 273 u8 data[sizeof(cap_manufacturer)];
336 ssize_t len; 274 ssize_t len;
337 char *str = buf; 275 char *str = buf;
338 276
339 struct tpm_chip *chip = 277 struct tpm_chip *chip =
340 pci_get_drvdata(container_of(dev, struct pci_dev, dev)); 278 pci_get_drvdata(to_pci_dev(dev));
341 if (chip == NULL) 279 if (chip == NULL)
342 return -ENODEV; 280 return -ENODEV;
343 281
@@ -348,7 +286,7 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char
348 return len; 286 return len;
349 287
350 str += sprintf(str, "Manufacturer: 0x%x\n", 288 str += sprintf(str, "Manufacturer: 0x%x\n",
351 be32_to_cpu(*(data + 14))); 289 be32_to_cpu(*((__be32 *) (data + 14))));
352 290
353 memcpy(data, cap_version, sizeof(cap_version)); 291 memcpy(data, cap_version, sizeof(cap_version));
354 292
@@ -363,8 +301,20 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char
363 301
364 return str - buf; 302 return str - buf;
365} 303}
304EXPORT_SYMBOL_GPL(tpm_show_caps);
305
306ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
307 const char *buf, size_t count)
308{
309 struct tpm_chip *chip = dev_get_drvdata(dev);
310 if (chip == NULL)
311 return 0;
312
313 chip->vendor->cancel(chip);
314 return count;
315}
316EXPORT_SYMBOL_GPL(tpm_store_cancel);
366 317
367static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
368 318
369/* 319/*
370 * Device file system interface to the TPM 320 * Device file system interface to the TPM
@@ -422,24 +372,15 @@ EXPORT_SYMBOL_GPL(tpm_open);
422int tpm_release(struct inode *inode, struct file *file) 372int tpm_release(struct inode *inode, struct file *file)
423{ 373{
424 struct tpm_chip *chip = file->private_data; 374 struct tpm_chip *chip = file->private_data;
425
426 file->private_data = NULL;
427 375
428 spin_lock(&driver_lock); 376 spin_lock(&driver_lock);
377 file->private_data = NULL;
429 chip->num_opens--; 378 chip->num_opens--;
430 spin_unlock(&driver_lock); 379 del_singleshot_timer_sync(&chip->user_read_timer);
431
432 down(&chip->timer_manipulation_mutex);
433 if (timer_pending(&chip->user_read_timer))
434 del_singleshot_timer_sync(&chip->user_read_timer);
435 else if (timer_pending(&chip->device_timer))
436 del_singleshot_timer_sync(&chip->device_timer);
437 up(&chip->timer_manipulation_mutex);
438
439 kfree(chip->data_buffer);
440 atomic_set(&chip->data_pending, 0); 380 atomic_set(&chip->data_pending, 0);
441
442 pci_dev_put(chip->pci_dev); 381 pci_dev_put(chip->pci_dev);
382 kfree(chip->data_buffer);
383 spin_unlock(&driver_lock);
443 return 0; 384 return 0;
444} 385}
445 386
@@ -453,10 +394,8 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
453 394
454 /* cannot perform a write until the read has cleared 395 /* cannot perform a write until the read has cleared
455 either via tpm_read or a user_read_timer timeout */ 396 either via tpm_read or a user_read_timer timeout */
456 while (atomic_read(&chip->data_pending) != 0) { 397 while (atomic_read(&chip->data_pending) != 0)
457 set_current_state(TASK_UNINTERRUPTIBLE); 398 msleep(TPM_TIMEOUT);
458 schedule_timeout(TPM_TIMEOUT);
459 }
460 399
461 down(&chip->buffer_mutex); 400 down(&chip->buffer_mutex);
462 401
@@ -476,13 +415,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
476 up(&chip->buffer_mutex); 415 up(&chip->buffer_mutex);
477 416
478 /* Set a timeout by which the reader must come claim the result */ 417 /* Set a timeout by which the reader must come claim the result */
479 down(&chip->timer_manipulation_mutex); 418 mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
480 init_timer(&chip->user_read_timer);
481 chip->user_read_timer.function = user_reader_timeout;
482 chip->user_read_timer.data = (unsigned long) chip;
483 chip->user_read_timer.expires = jiffies + (60 * HZ);
484 add_timer(&chip->user_read_timer);
485 up(&chip->timer_manipulation_mutex);
486 419
487 return in_size; 420 return in_size;
488} 421}
@@ -493,29 +426,19 @@ ssize_t tpm_read(struct file * file, char __user * buf,
493 size_t size, loff_t * off) 426 size_t size, loff_t * off)
494{ 427{
495 struct tpm_chip *chip = file->private_data; 428 struct tpm_chip *chip = file->private_data;
496 int ret_size = -ENODATA; 429 int ret_size;
497 430
498 if (atomic_read(&chip->data_pending) != 0) { /* Result available */ 431 del_singleshot_timer_sync(&chip->user_read_timer);
499 down(&chip->timer_manipulation_mutex); 432 ret_size = atomic_read(&chip->data_pending);
500 del_singleshot_timer_sync(&chip->user_read_timer); 433 atomic_set(&chip->data_pending, 0);
501 up(&chip->timer_manipulation_mutex); 434 if (ret_size > 0) { /* relay data */
435 if (size < ret_size)
436 ret_size = size;
502 437
503 down(&chip->buffer_mutex); 438 down(&chip->buffer_mutex);
504 439 if (copy_to_user
505 ret_size = atomic_read(&chip->data_pending); 440 ((void __user *) buf, chip->data_buffer, ret_size))
506 atomic_set(&chip->data_pending, 0); 441 ret_size = -EFAULT;
507
508 if (ret_size == 0) /* timeout just occurred */
509 ret_size = -ETIME;
510 else if (ret_size > 0) { /* relay data */
511 if (size < ret_size)
512 ret_size = size;
513
514 if (copy_to_user((void __user *) buf,
515 chip->data_buffer, ret_size)) {
516 ret_size = -EFAULT;
517 }
518 }
519 up(&chip->buffer_mutex); 442 up(&chip->buffer_mutex);
520 } 443 }
521 444
@@ -542,13 +465,11 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
542 pci_set_drvdata(pci_dev, NULL); 465 pci_set_drvdata(pci_dev, NULL);
543 misc_deregister(&chip->vendor->miscdev); 466 misc_deregister(&chip->vendor->miscdev);
544 467
545 device_remove_file(&pci_dev->dev, &dev_attr_pubek); 468 sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
546 device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
547 device_remove_file(&pci_dev->dev, &dev_attr_caps);
548 469
549 pci_disable_device(pci_dev); 470 pci_disable_device(pci_dev);
550 471
551 dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32)); 472 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
552 473
553 kfree(chip); 474 kfree(chip);
554 475
@@ -590,10 +511,6 @@ int tpm_pm_resume(struct pci_dev *pci_dev)
590 if (chip == NULL) 511 if (chip == NULL)
591 return -ENODEV; 512 return -ENODEV;
592 513
593 spin_lock(&driver_lock);
594 tpm_lpc_bus_init(pci_dev, chip->vendor->base);
595 spin_unlock(&driver_lock);
596
597 return 0; 514 return 0;
598} 515}
599 516
@@ -622,17 +539,21 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
622 539
623 init_MUTEX(&chip->buffer_mutex); 540 init_MUTEX(&chip->buffer_mutex);
624 init_MUTEX(&chip->tpm_mutex); 541 init_MUTEX(&chip->tpm_mutex);
625 init_MUTEX(&chip->timer_manipulation_mutex);
626 INIT_LIST_HEAD(&chip->list); 542 INIT_LIST_HEAD(&chip->list);
627 543
544 init_timer(&chip->user_read_timer);
545 chip->user_read_timer.function = user_reader_timeout;
546 chip->user_read_timer.data = (unsigned long) chip;
547
628 chip->vendor = entry; 548 chip->vendor = entry;
629 549
630 chip->dev_num = -1; 550 chip->dev_num = -1;
631 551
632 for (i = 0; i < 32; i++) 552 for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
633 for (j = 0; j < 8; j++) 553 for (j = 0; j < 8 * sizeof(int); j++)
634 if ((dev_mask[i] & (1 << j)) == 0) { 554 if ((dev_mask[i] & (1 << j)) == 0) {
635 chip->dev_num = i * 32 + j; 555 chip->dev_num =
556 i * TPM_NUM_MASK_ENTRIES + j;
636 dev_mask[i] |= 1 << j; 557 dev_mask[i] |= 1 << j;
637 goto dev_num_search_complete; 558 goto dev_num_search_complete;
638 } 559 }
@@ -665,31 +586,20 @@ dev_num_search_complete:
665 return -ENODEV; 586 return -ENODEV;
666 } 587 }
667 588
589 spin_lock(&driver_lock);
590
668 pci_set_drvdata(pci_dev, chip); 591 pci_set_drvdata(pci_dev, chip);
669 592
670 list_add(&chip->list, &tpm_chip_list); 593 list_add(&chip->list, &tpm_chip_list);
671 594
672 device_create_file(&pci_dev->dev, &dev_attr_pubek); 595 spin_unlock(&driver_lock);
673 device_create_file(&pci_dev->dev, &dev_attr_pcrs);
674 device_create_file(&pci_dev->dev, &dev_attr_caps);
675
676 return 0;
677}
678 596
679EXPORT_SYMBOL_GPL(tpm_register_hardware); 597 sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
680 598
681static int __init init_tpm(void)
682{
683 return 0; 599 return 0;
684} 600}
685 601
686static void __exit cleanup_tpm(void) 602EXPORT_SYMBOL_GPL(tpm_register_hardware);
687{
688
689}
690
691module_init(init_tpm);
692module_exit(cleanup_tpm);
693 603
694MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); 604MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
695MODULE_DESCRIPTION("TPM Driver"); 605MODULE_DESCRIPTION("TPM Driver");
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index de0c796fce80..10cb450191a6 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -25,23 +25,38 @@
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/miscdevice.h> 26#include <linux/miscdevice.h>
27 27
28#define TPM_TIMEOUT msecs_to_jiffies(5) 28enum tpm_timeout {
29 TPM_TIMEOUT = 5, /* msecs */
30};
29 31
30/* TPM addresses */ 32/* TPM addresses */
31#define TPM_ADDR 0x4E 33enum tpm_addr {
32#define TPM_DATA 0x4F 34 TPM_ADDR = 0x4E,
35 TPM_DATA = 0x4F
36};
37
38extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
39 char *);
40extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
41 char *);
42extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
43 char *);
44extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
45 const char *, size_t);
33 46
34struct tpm_chip; 47struct tpm_chip;
35 48
36struct tpm_vendor_specific { 49struct tpm_vendor_specific {
37 u8 req_complete_mask; 50 u8 req_complete_mask;
38 u8 req_complete_val; 51 u8 req_complete_val;
52 u8 req_canceled;
39 u16 base; /* TPM base address */ 53 u16 base; /* TPM base address */
40 54
41 int (*recv) (struct tpm_chip *, u8 *, size_t); 55 int (*recv) (struct tpm_chip *, u8 *, size_t);
42 int (*send) (struct tpm_chip *, u8 *, size_t); 56 int (*send) (struct tpm_chip *, u8 *, size_t);
43 void (*cancel) (struct tpm_chip *); 57 void (*cancel) (struct tpm_chip *);
44 struct miscdevice miscdev; 58 struct miscdevice miscdev;
59 struct attribute_group *attr_group;
45}; 60};
46 61
47struct tpm_chip { 62struct tpm_chip {
@@ -58,8 +73,6 @@ struct tpm_chip {
58 73
59 struct timer_list user_read_timer; /* user needs to claim result */ 74 struct timer_list user_read_timer; /* user needs to claim result */
60 struct semaphore tpm_mutex; /* tpm is processing */ 75 struct semaphore tpm_mutex; /* tpm is processing */
61 struct timer_list device_timer; /* tpm is processing */
62 struct semaphore timer_manipulation_mutex;
63 76
64 struct tpm_vendor_specific *vendor; 77 struct tpm_vendor_specific *vendor;
65 78
@@ -78,9 +91,6 @@ static inline void tpm_write_index(int index, int value)
78 outb(value & 0xFF, TPM_DATA); 91 outb(value & 0xFF, TPM_DATA);
79} 92}
80 93
81extern void tpm_time_expired(unsigned long);
82extern int tpm_lpc_bus_init(struct pci_dev *, u16);
83
84extern int tpm_register_hardware(struct pci_dev *, 94extern int tpm_register_hardware(struct pci_dev *,
85 struct tpm_vendor_specific *); 95 struct tpm_vendor_specific *);
86extern int tpm_open(struct inode *, struct file *); 96extern int tpm_open(struct inode *, struct file *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index f9333e729b62..61fe14a77124 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -22,17 +22,23 @@
22#include "tpm.h" 22#include "tpm.h"
23 23
24/* Atmel definitions */ 24/* Atmel definitions */
25#define TPM_ATML_BASE 0x400 25enum tpm_atmel_addr {
26 TPM_ATMEL_BASE_ADDR_LO = 0x08,
27 TPM_ATMEL_BASE_ADDR_HI = 0x09
28};
26 29
27/* write status bits */ 30/* write status bits */
28#define ATML_STATUS_ABORT 0x01 31enum tpm_atmel_write_status {
29#define ATML_STATUS_LASTBYTE 0x04 32 ATML_STATUS_ABORT = 0x01,
30 33 ATML_STATUS_LASTBYTE = 0x04
34};
31/* read status bits */ 35/* read status bits */
32#define ATML_STATUS_BUSY 0x01 36enum tpm_atmel_read_status {
33#define ATML_STATUS_DATA_AVAIL 0x02 37 ATML_STATUS_BUSY = 0x01,
34#define ATML_STATUS_REWRITE 0x04 38 ATML_STATUS_DATA_AVAIL = 0x02,
35 39 ATML_STATUS_REWRITE = 0x04,
40 ATML_STATUS_READY = 0x08
41};
36 42
37static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count) 43static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
38{ 44{
@@ -121,13 +127,29 @@ static struct file_operations atmel_ops = {
121 .release = tpm_release, 127 .release = tpm_release,
122}; 128};
123 129
130static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
131static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
132static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
133static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
134
135static struct attribute* atmel_attrs[] = {
136 &dev_attr_pubek.attr,
137 &dev_attr_pcrs.attr,
138 &dev_attr_caps.attr,
139 &dev_attr_cancel.attr,
140 0,
141};
142
143static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
144
124static struct tpm_vendor_specific tpm_atmel = { 145static struct tpm_vendor_specific tpm_atmel = {
125 .recv = tpm_atml_recv, 146 .recv = tpm_atml_recv,
126 .send = tpm_atml_send, 147 .send = tpm_atml_send,
127 .cancel = tpm_atml_cancel, 148 .cancel = tpm_atml_cancel,
128 .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL, 149 .req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
129 .req_complete_val = ATML_STATUS_DATA_AVAIL, 150 .req_complete_val = ATML_STATUS_DATA_AVAIL,
130 .base = TPM_ATML_BASE, 151 .req_canceled = ATML_STATUS_READY,
152 .attr_group = &atmel_attr_grp,
131 .miscdev = { .fops = &atmel_ops, }, 153 .miscdev = { .fops = &atmel_ops, },
132}; 154};
133 155
@@ -136,14 +158,16 @@ static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
136{ 158{
137 u8 version[4]; 159 u8 version[4];
138 int rc = 0; 160 int rc = 0;
161 int lo, hi;
139 162
140 if (pci_enable_device(pci_dev)) 163 if (pci_enable_device(pci_dev))
141 return -EIO; 164 return -EIO;
142 165
143 if (tpm_lpc_bus_init(pci_dev, TPM_ATML_BASE)) { 166 lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO );
144 rc = -ENODEV; 167 hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI );
145 goto out_err; 168
146 } 169 tpm_atmel.base = (hi<<8)|lo;
170 dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
147 171
148 /* verify that it is an Atmel part */ 172 /* verify that it is an Atmel part */
149 if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' 173 if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
@@ -183,6 +207,7 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
183 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, 207 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
184 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, 208 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
185 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, 209 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
210 {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
186 {0,} 211 {0,}
187}; 212};
188 213
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 9cce833a0923..1a45e7dfc13b 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -22,43 +22,52 @@
22#include "tpm.h" 22#include "tpm.h"
23 23
24/* National definitions */ 24/* National definitions */
25#define TPM_NSC_BASE 0x360 25enum tpm_nsc_addr{
26#define TPM_NSC_IRQ 0x07 26 TPM_NSC_BASE = 0x360,
27 TPM_NSC_IRQ = 0x07,
28 TPM_NSC_BASE0_HI = 0x60,
29 TPM_NSC_BASE0_LO = 0x61,
30 TPM_NSC_BASE1_HI = 0x62,
31 TPM_NSC_BASE1_LO = 0x63
32};
27 33
28#define NSC_LDN_INDEX 0x07 34enum tpm_nsc_index {
29#define NSC_SID_INDEX 0x20 35 NSC_LDN_INDEX = 0x07,
30#define NSC_LDC_INDEX 0x30 36 NSC_SID_INDEX = 0x20,
31#define NSC_DIO_INDEX 0x60 37 NSC_LDC_INDEX = 0x30,
32#define NSC_CIO_INDEX 0x62 38 NSC_DIO_INDEX = 0x60,
33#define NSC_IRQ_INDEX 0x70 39 NSC_CIO_INDEX = 0x62,
34#define NSC_ITS_INDEX 0x71 40 NSC_IRQ_INDEX = 0x70,
41 NSC_ITS_INDEX = 0x71
42};
35 43
36#define NSC_STATUS 0x01 44enum tpm_nsc_status_loc {
37#define NSC_COMMAND 0x01 45 NSC_STATUS = 0x01,
38#define NSC_DATA 0x00 46 NSC_COMMAND = 0x01,
47 NSC_DATA = 0x00
48};
39 49
40/* status bits */ 50/* status bits */
41#define NSC_STATUS_OBF 0x01 /* output buffer full */ 51enum tpm_nsc_status {
42#define NSC_STATUS_IBF 0x02 /* input buffer full */ 52 NSC_STATUS_OBF = 0x01, /* output buffer full */
43#define NSC_STATUS_F0 0x04 /* F0 */ 53 NSC_STATUS_IBF = 0x02, /* input buffer full */
44#define NSC_STATUS_A2 0x08 /* A2 */ 54 NSC_STATUS_F0 = 0x04, /* F0 */
45#define NSC_STATUS_RDY 0x10 /* ready to receive command */ 55 NSC_STATUS_A2 = 0x08, /* A2 */
46#define NSC_STATUS_IBR 0x20 /* ready to receive data */ 56 NSC_STATUS_RDY = 0x10, /* ready to receive command */
47 57 NSC_STATUS_IBR = 0x20 /* ready to receive data */
58};
48/* command bits */ 59/* command bits */
49#define NSC_COMMAND_NORMAL 0x01 /* normal mode */ 60enum tpm_nsc_cmd_mode {
50#define NSC_COMMAND_EOC 0x03 61 NSC_COMMAND_NORMAL = 0x01, /* normal mode */
51#define NSC_COMMAND_CANCEL 0x22 62 NSC_COMMAND_EOC = 0x03,
52 63 NSC_COMMAND_CANCEL = 0x22
64};
53/* 65/*
54 * Wait for a certain status to appear 66 * Wait for a certain status to appear
55 */ 67 */
56static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) 68static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
57{ 69{
58 int expired = 0; 70 unsigned long stop;
59 struct timer_list status_timer =
60 TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
61 (unsigned long) &expired);
62 71
63 /* status immediately available check */ 72 /* status immediately available check */
64 *data = inb(chip->vendor->base + NSC_STATUS); 73 *data = inb(chip->vendor->base + NSC_STATUS);
@@ -66,17 +75,14 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
66 return 0; 75 return 0;
67 76
68 /* wait for status */ 77 /* wait for status */
69 add_timer(&status_timer); 78 stop = jiffies + 10 * HZ;
70 do { 79 do {
71 set_current_state(TASK_UNINTERRUPTIBLE); 80 msleep(TPM_TIMEOUT);
72 schedule_timeout(TPM_TIMEOUT);
73 *data = inb(chip->vendor->base + 1); 81 *data = inb(chip->vendor->base + 1);
74 if ((*data & mask) == val) { 82 if ((*data & mask) == val)
75 del_singleshot_timer_sync(&status_timer);
76 return 0; 83 return 0;
77 }
78 } 84 }
79 while (!expired); 85 while (time_before(jiffies, stop));
80 86
81 return -EBUSY; 87 return -EBUSY;
82} 88}
@@ -84,10 +90,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
84static int nsc_wait_for_ready(struct tpm_chip *chip) 90static int nsc_wait_for_ready(struct tpm_chip *chip)
85{ 91{
86 int status; 92 int status;
87 int expired = 0; 93 unsigned long stop;
88 struct timer_list status_timer =
89 TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
90 (unsigned long) &expired);
91 94
92 /* status immediately available check */ 95 /* status immediately available check */
93 status = inb(chip->vendor->base + NSC_STATUS); 96 status = inb(chip->vendor->base + NSC_STATUS);
@@ -97,19 +100,16 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
97 return 0; 100 return 0;
98 101
99 /* wait for status */ 102 /* wait for status */
100 add_timer(&status_timer); 103 stop = jiffies + 100;
101 do { 104 do {
102 set_current_state(TASK_UNINTERRUPTIBLE); 105 msleep(TPM_TIMEOUT);
103 schedule_timeout(TPM_TIMEOUT);
104 status = inb(chip->vendor->base + NSC_STATUS); 106 status = inb(chip->vendor->base + NSC_STATUS);
105 if (status & NSC_STATUS_OBF) 107 if (status & NSC_STATUS_OBF)
106 status = inb(chip->vendor->base + NSC_DATA); 108 status = inb(chip->vendor->base + NSC_DATA);
107 if (status & NSC_STATUS_RDY) { 109 if (status & NSC_STATUS_RDY)
108 del_singleshot_timer_sync(&status_timer);
109 return 0; 110 return 0;
110 }
111 } 111 }
112 while (!expired); 112 while (time_before(jiffies, stop));
113 113
114 dev_info(&chip->pci_dev->dev, "wait for ready failed\n"); 114 dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
115 return -EBUSY; 115 return -EBUSY;
@@ -228,30 +228,46 @@ static struct file_operations nsc_ops = {
228 .release = tpm_release, 228 .release = tpm_release,
229}; 229};
230 230
231static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
232static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
233static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
234static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel);
235
236static struct attribute * nsc_attrs[] = {
237 &dev_attr_pubek.attr,
238 &dev_attr_pcrs.attr,
239 &dev_attr_caps.attr,
240 &dev_attr_cancel.attr,
241 0,
242};
243
244static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
245
231static struct tpm_vendor_specific tpm_nsc = { 246static struct tpm_vendor_specific tpm_nsc = {
232 .recv = tpm_nsc_recv, 247 .recv = tpm_nsc_recv,
233 .send = tpm_nsc_send, 248 .send = tpm_nsc_send,
234 .cancel = tpm_nsc_cancel, 249 .cancel = tpm_nsc_cancel,
235 .req_complete_mask = NSC_STATUS_OBF, 250 .req_complete_mask = NSC_STATUS_OBF,
236 .req_complete_val = NSC_STATUS_OBF, 251 .req_complete_val = NSC_STATUS_OBF,
237 .base = TPM_NSC_BASE, 252 .req_canceled = NSC_STATUS_RDY,
253 .attr_group = &nsc_attr_grp,
238 .miscdev = { .fops = &nsc_ops, }, 254 .miscdev = { .fops = &nsc_ops, },
239
240}; 255};
241 256
242static int __devinit tpm_nsc_init(struct pci_dev *pci_dev, 257static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
243 const struct pci_device_id *pci_id) 258 const struct pci_device_id *pci_id)
244{ 259{
245 int rc = 0; 260 int rc = 0;
261 int lo, hi;
262
263 hi = tpm_read_index(TPM_NSC_BASE0_HI);
264 lo = tpm_read_index(TPM_NSC_BASE0_LO);
265
266 tpm_nsc.base = (hi<<8) | lo;
246 267
247 if (pci_enable_device(pci_dev)) 268 if (pci_enable_device(pci_dev))
248 return -EIO; 269 return -EIO;
249 270
250 if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) {
251 rc = -ENODEV;
252 goto out_err;
253 }
254
255 /* verify that it is a National part (SID) */ 271 /* verify that it is a National part (SID) */
256 if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { 272 if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
257 rc = -ENODEV; 273 rc = -ENODEV;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 31831030f73f..cc4b43bad703 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -251,7 +251,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
251 251
252static DEFINE_SPINLOCK(tty_ldisc_lock); 252static DEFINE_SPINLOCK(tty_ldisc_lock);
253static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); 253static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
254static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ 254static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */
255 255
256int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) 256int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
257{ 257{
@@ -262,24 +262,35 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
262 return -EINVAL; 262 return -EINVAL;
263 263
264 spin_lock_irqsave(&tty_ldisc_lock, flags); 264 spin_lock_irqsave(&tty_ldisc_lock, flags);
265 if (new_ldisc) { 265 tty_ldiscs[disc] = *new_ldisc;
266 tty_ldiscs[disc] = *new_ldisc; 266 tty_ldiscs[disc].num = disc;
267 tty_ldiscs[disc].num = disc; 267 tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
268 tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; 268 tty_ldiscs[disc].refcount = 0;
269 tty_ldiscs[disc].refcount = 0;
270 } else {
271 if(tty_ldiscs[disc].refcount)
272 ret = -EBUSY;
273 else
274 tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
275 }
276 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 269 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
277 270
278 return ret; 271 return ret;
279} 272}
280
281EXPORT_SYMBOL(tty_register_ldisc); 273EXPORT_SYMBOL(tty_register_ldisc);
282 274
275int tty_unregister_ldisc(int disc)
276{
277 unsigned long flags;
278 int ret = 0;
279
280 if (disc < N_TTY || disc >= NR_LDISCS)
281 return -EINVAL;
282
283 spin_lock_irqsave(&tty_ldisc_lock, flags);
284 if (tty_ldiscs[disc].refcount)
285 ret = -EBUSY;
286 else
287 tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
288 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
289
290 return ret;
291}
292EXPORT_SYMBOL(tty_unregister_ldisc);
293
283struct tty_ldisc *tty_ldisc_get(int disc) 294struct tty_ldisc *tty_ldisc_get(int disc)
284{ 295{
285 unsigned long flags; 296 unsigned long flags;
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 06a31da2381c..b53e2e2b5aee 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -414,6 +414,16 @@ config WATCHDOG_RIO
414 machines. The watchdog timeout period is normally one minute but 414 machines. The watchdog timeout period is normally one minute but
415 can be changed with a boot-time parameter. 415 can be changed with a boot-time parameter.
416 416
417# ppc64 RTAS watchdog
418config WATCHDOG_RTAS
419 tristate "RTAS watchdog"
420 depends on WATCHDOG && PPC_RTAS
421 help
422 This driver adds watchdog support for the RTAS watchdog.
423
424 To compile this driver as a module, choose M here. The module
425 will be called wdrtas.
426
417# 427#
418# ISA-based Watchdog Cards 428# ISA-based Watchdog Cards
419# 429#
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 1cd27efa35c1..c1838834ea7f 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
33obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o 33obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
34obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o 34obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
35obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o 35obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
36obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
36 37
37# Only one watchdog can succeed. We probe the hardware watchdog 38# Only one watchdog can succeed. We probe the hardware watchdog
38# drivers first, then the softdog driver. This means if your hardware 39# drivers first, then the softdog driver. This means if your hardware
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
new file mode 100644
index 000000000000..619e2ffca33f
--- /dev/null
+++ b/drivers/char/watchdog/wdrtas.c
@@ -0,0 +1,696 @@
1/*
2 * FIXME: add wdrtas_get_status and wdrtas_get_boot_status as soon as
3 * RTAS calls are available
4 */
5
6/*
7 * RTAS watchdog driver
8 *
9 * (C) Copyright IBM Corp. 2005
10 * device driver to exploit watchdog RTAS functions
11 *
12 * Authors : Utz Bacher <utz.bacher@de.ibm.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#include <linux/config.h>
30#include <linux/fs.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/miscdevice.h>
34#include <linux/module.h>
35#include <linux/notifier.h>
36#include <linux/reboot.h>
37#include <linux/types.h>
38#include <linux/watchdog.h>
39
40#include <asm/rtas.h>
41#include <asm/uaccess.h>
42
43#define WDRTAS_MAGIC_CHAR 42
44#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \
45 WDIOF_MAGICCLOSE)
46
47MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
48MODULE_DESCRIPTION("RTAS watchdog driver");
49MODULE_LICENSE("GPL");
50MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
51MODULE_ALIAS_MISCDEV(TEMP_MINOR);
52
53#ifdef CONFIG_WATCHDOG_NOWAYOUT
54static int wdrtas_nowayout = 1;
55#else
56static int wdrtas_nowayout = 0;
57#endif
58
59static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
60static char wdrtas_expect_close = 0;
61
62static int wdrtas_interval;
63
64#define WDRTAS_THERMAL_SENSOR 3
65static int wdrtas_token_get_sensor_state;
66#define WDRTAS_SURVEILLANCE_IND 9000
67static int wdrtas_token_set_indicator;
68#define WDRTAS_SP_SPI 28
69static int wdrtas_token_get_sp;
70static int wdrtas_token_event_scan;
71
72#define WDRTAS_DEFAULT_INTERVAL 300
73
74#define WDRTAS_LOGBUFFER_LEN 128
75static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN];
76
77
78/*** watchdog access functions */
79
80/**
81 * wdrtas_set_interval - sets the watchdog interval
82 * @interval: new interval
83 *
84 * returns 0 on success, <0 on failures
85 *
86 * wdrtas_set_interval sets the watchdog keepalive interval by calling the
87 * RTAS function set-indicator (surveillance). The unit of interval is
88 * seconds.
89 */
90static int
91wdrtas_set_interval(int interval)
92{
93 long result;
94 static int print_msg = 10;
95
96 /* rtas uses minutes */
97 interval = (interval + 59) / 60;
98
99 result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL,
100 WDRTAS_SURVEILLANCE_IND, 0, interval);
101 if ( (result < 0) && (print_msg) ) {
102 printk(KERN_ERR "wdrtas: setting the watchdog to %i "
103 "timeout failed: %li\n", interval, result);
104 print_msg--;
105 }
106
107 return result;
108}
109
110/**
111 * wdrtas_get_interval - returns the current watchdog interval
112 * @fallback_value: value (in seconds) to use, if the RTAS call fails
113 *
114 * returns the interval
115 *
116 * wdrtas_get_interval returns the current watchdog keepalive interval
117 * as reported by the RTAS function ibm,get-system-parameter. The unit
118 * of the return value is seconds.
119 */
120static int
121wdrtas_get_interval(int fallback_value)
122{
123 long result;
124 char value[4];
125
126 result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
127 WDRTAS_SP_SPI, (void *)__pa(&value), 4);
128 if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) ||
129 (result < 0) ) {
130 printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
131 "timeout (%li). Continuing\n", result);
132 return fallback_value;
133 }
134
135 /* rtas uses minutes */
136 return ((int)value[2]) * 60;
137}
138
139/**
140 * wdrtas_timer_start - starts watchdog
141 *
142 * wdrtas_timer_start starts the watchdog by calling the RTAS function
143 * set-interval (surveillance)
144 */
145static void
146wdrtas_timer_start(void)
147{
148 wdrtas_set_interval(wdrtas_interval);
149}
150
151/**
152 * wdrtas_timer_stop - stops watchdog
153 *
154 * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function
155 * set-interval (surveillance)
156 */
157static void
158wdrtas_timer_stop(void)
159{
160 wdrtas_set_interval(0);
161}
162
163/**
164 * wdrtas_log_scanned_event - logs an event we received during keepalive
165 *
166 * wdrtas_log_scanned_event prints a message to the log buffer dumping
167 * the results of the last event-scan call
168 */
169static void
170wdrtas_log_scanned_event(void)
171{
172 int i;
173
174 for (i = 0; i < WDRTAS_LOGBUFFER_LEN; i += 16)
175 printk(KERN_INFO "wdrtas: dumping event (line %i/%i), data = "
176 "%02x %02x %02x %02x %02x %02x %02x %02x "
177 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
178 (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
179 wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1],
180 wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3],
181 wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5],
182 wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7],
183 wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9],
184 wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11],
185 wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13],
186 wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
187}
188
189/**
190 * wdrtas_timer_keepalive - resets watchdog timer to keep system alive
191 *
192 * wdrtas_timer_keepalive restarts the watchdog timer by calling the
193 * RTAS function event-scan and repeats these calls as long as there are
194 * events available. All events will be dumped.
195 */
196static void
197wdrtas_timer_keepalive(void)
198{
199 long result;
200
201 do {
202 result = rtas_call(wdrtas_token_event_scan, 4, 1, NULL,
203 RTAS_EVENT_SCAN_ALL_EVENTS, 0,
204 (void *)__pa(wdrtas_logbuffer),
205 WDRTAS_LOGBUFFER_LEN);
206 if (result < 0)
207 printk(KERN_ERR "wdrtas: event-scan failed: %li\n",
208 result);
209 if (result == 0)
210 wdrtas_log_scanned_event();
211 } while (result == 0);
212}
213
214/**
215 * wdrtas_get_temperature - returns current temperature
216 *
217 * returns temperature or <0 on failures
218 *
219 * wdrtas_get_temperature returns the current temperature in Fahrenheit. It
220 * uses the RTAS call get-sensor-state, token 3 to do so
221 */
222static int
223wdrtas_get_temperature(void)
224{
225 long result;
226 int temperature = 0;
227
228 result = rtas_call(wdrtas_token_get_sensor_state, 2, 2,
229 (void *)__pa(&temperature),
230 WDRTAS_THERMAL_SENSOR, 0);
231
232 if (result < 0)
233 printk(KERN_WARNING "wdrtas: reading the thermal sensor "
234 "faild: %li\n", result);
235 else
236 temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */
237
238 return temperature;
239}
240
241/**
242 * wdrtas_get_status - returns the status of the watchdog
243 *
244 * returns a bitmask of defines WDIOF_... as defined in
245 * include/linux/watchdog.h
246 */
247static int
248wdrtas_get_status(void)
249{
250 return 0; /* TODO */
251}
252
253/**
254 * wdrtas_get_boot_status - returns the reason for the last boot
255 *
256 * returns a bitmask of defines WDIOF_... as defined in
257 * include/linux/watchdog.h, indicating why the watchdog rebooted the system
258 */
259static int
260wdrtas_get_boot_status(void)
261{
262 return 0; /* TODO */
263}
264
265/*** watchdog API and operations stuff */
266
267/* wdrtas_write - called when watchdog device is written to
268 * @file: file structure
269 * @buf: user buffer with data
270 * @len: amount to data written
271 * @ppos: position in file
272 *
273 * returns the number of successfully processed characters, which is always
274 * the number of bytes passed to this function
275 *
276 * wdrtas_write processes all the data given to it and looks for the magic
277 * character 'V'. This character allows the watchdog device to be closed
278 * properly.
279 */
280static ssize_t
281wdrtas_write(struct file *file, const char __user *buf,
282 size_t len, loff_t *ppos)
283{
284 int i;
285 char c;
286
287 if (!len)
288 goto out;
289
290 if (!wdrtas_nowayout) {
291 wdrtas_expect_close = 0;
292 /* look for 'V' */
293 for (i = 0; i < len; i++) {
294 if (get_user(c, buf + i))
295 return -EFAULT;
296 /* allow to close device */
297 if (c == 'V')
298 wdrtas_expect_close = WDRTAS_MAGIC_CHAR;
299 }
300 }
301
302 wdrtas_timer_keepalive();
303
304out:
305 return len;
306}
307
308/**
309 * wdrtas_ioctl - ioctl function for the watchdog device
310 * @inode: inode structure
311 * @file: file structure
312 * @cmd: command for ioctl
313 * @arg: argument pointer
314 *
315 * returns 0 on success, <0 on failure
316 *
317 * wdrtas_ioctl implements the watchdog API ioctls
318 */
319static int
320wdrtas_ioctl(struct inode *inode, struct file *file,
321 unsigned int cmd, unsigned long arg)
322{
323 int __user *argp = (void *)arg;
324 int i;
325 static struct watchdog_info wdinfo = {
326 .options = WDRTAS_SUPPORTED_MASK,
327 .firmware_version = 0,
328 .identity = "wdrtas"
329 };
330
331 switch (cmd) {
332 case WDIOC_GETSUPPORT:
333 if (copy_to_user(argp, &wdinfo, sizeof(wdinfo)))
334 return -EFAULT;
335 return 0;
336
337 case WDIOC_GETSTATUS:
338 i = wdrtas_get_status();
339 return put_user(i, argp);
340
341 case WDIOC_GETBOOTSTATUS:
342 i = wdrtas_get_boot_status();
343 return put_user(i, argp);
344
345 case WDIOC_GETTEMP:
346 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE)
347 return -EOPNOTSUPP;
348
349 i = wdrtas_get_temperature();
350 return put_user(i, argp);
351
352 case WDIOC_SETOPTIONS:
353 if (get_user(i, argp))
354 return -EFAULT;
355 if (i & WDIOS_DISABLECARD)
356 wdrtas_timer_stop();
357 if (i & WDIOS_ENABLECARD) {
358 wdrtas_timer_keepalive();
359 wdrtas_timer_start();
360 }
361 if (i & WDIOS_TEMPPANIC) {
362 /* not implemented. Done by H8 */
363 }
364 return 0;
365
366 case WDIOC_KEEPALIVE:
367 wdrtas_timer_keepalive();
368 return 0;
369
370 case WDIOC_SETTIMEOUT:
371 if (get_user(i, argp))
372 return -EFAULT;
373
374 if (wdrtas_set_interval(i))
375 return -EINVAL;
376
377 wdrtas_timer_keepalive();
378
379 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
380 wdrtas_interval = i;
381 else
382 wdrtas_interval = wdrtas_get_interval(i);
383 /* fallthrough */
384
385 case WDIOC_GETTIMEOUT:
386 return put_user(wdrtas_interval, argp);
387
388 default:
389 return -ENOIOCTLCMD;
390 }
391}
392
393/**
394 * wdrtas_open - open function of watchdog device
395 * @inode: inode structure
396 * @file: file structure
397 *
398 * returns 0 on success, -EBUSY if the file has been opened already, <0 on
399 * other failures
400 *
401 * function called when watchdog device is opened
402 */
403static int
404wdrtas_open(struct inode *inode, struct file *file)
405{
406 /* only open once */
407 if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {
408 atomic_dec(&wdrtas_miscdev_open);
409 return -EBUSY;
410 }
411
412 wdrtas_timer_start();
413 wdrtas_timer_keepalive();
414
415 return nonseekable_open(inode, file);
416}
417
418/**
419 * wdrtas_close - close function of watchdog device
420 * @inode: inode structure
421 * @file: file structure
422 *
423 * returns 0 on success
424 *
425 * close function. Always succeeds
426 */
427static int
428wdrtas_close(struct inode *inode, struct file *file)
429{
430 /* only stop watchdog, if this was announced using 'V' before */
431 if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)
432 wdrtas_timer_stop();
433 else {
434 printk(KERN_WARNING "wdrtas: got unexpected close. Watchdog "
435 "not stopped.\n");
436 wdrtas_timer_keepalive();
437 }
438
439 wdrtas_expect_close = 0;
440 atomic_dec(&wdrtas_miscdev_open);
441 return 0;
442}
443
444/**
445 * wdrtas_temp_read - gives back the temperature in fahrenheit
446 * @file: file structure
447 * @buf: user buffer
448 * @count: number of bytes to be read
449 * @ppos: position in file
450 *
451 * returns always 1 or -EFAULT in case of user space copy failures, <0 on
452 * other failures
453 *
454 * wdrtas_temp_read gives the temperature to the users by copying this
455 * value as one byte into the user space buffer. The unit is Fahrenheit...
456 */
457static ssize_t
458wdrtas_temp_read(struct file *file, char __user *buf,
459 size_t count, loff_t *ppos)
460{
461 int temperature = 0;
462
463 temperature = wdrtas_get_temperature();
464 if (temperature < 0)
465 return temperature;
466
467 if (copy_to_user(buf, &temperature, 1))
468 return -EFAULT;
469
470 return 1;
471}
472
473/**
474 * wdrtas_temp_open - open function of temperature device
475 * @inode: inode structure
476 * @file: file structure
477 *
478 * returns 0 on success, <0 on failure
479 *
480 * function called when temperature device is opened
481 */
482static int
483wdrtas_temp_open(struct inode *inode, struct file *file)
484{
485 return nonseekable_open(inode, file);
486}
487
488/**
489 * wdrtas_temp_close - close function of temperature device
490 * @inode: inode structure
491 * @file: file structure
492 *
493 * returns 0 on success
494 *
495 * close function. Always succeeds
496 */
497static int
498wdrtas_temp_close(struct inode *inode, struct file *file)
499{
500 return 0;
501}
502
503/**
504 * wdrtas_reboot - reboot notifier function
505 * @nb: notifier block structure
506 * @code: reboot code
507 * @ptr: unused
508 *
509 * returns NOTIFY_DONE
510 *
511 * wdrtas_reboot stops the watchdog in case of a reboot
512 */
513static int
514wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr)
515{
516 if ( (code==SYS_DOWN) || (code==SYS_HALT) )
517 wdrtas_timer_stop();
518
519 return NOTIFY_DONE;
520}
521
522/*** initialization stuff */
523
524static struct file_operations wdrtas_fops = {
525 .owner = THIS_MODULE,
526 .llseek = no_llseek,
527 .write = wdrtas_write,
528 .ioctl = wdrtas_ioctl,
529 .open = wdrtas_open,
530 .release = wdrtas_close,
531};
532
533static struct miscdevice wdrtas_miscdev = {
534 .minor = WATCHDOG_MINOR,
535 .name = "watchdog",
536 .fops = &wdrtas_fops,
537};
538
539static struct file_operations wdrtas_temp_fops = {
540 .owner = THIS_MODULE,
541 .llseek = no_llseek,
542 .read = wdrtas_temp_read,
543 .open = wdrtas_temp_open,
544 .release = wdrtas_temp_close,
545};
546
547static struct miscdevice wdrtas_tempdev = {
548 .minor = TEMP_MINOR,
549 .name = "temperature",
550 .fops = &wdrtas_temp_fops,
551};
552
553static struct notifier_block wdrtas_notifier = {
554 .notifier_call = wdrtas_reboot,
555};
556
557/**
558 * wdrtas_get_tokens - reads in RTAS tokens
559 *
560 * returns 0 on succes, <0 on failure
561 *
562 * wdrtas_get_tokens reads in the tokens for the RTAS calls used in
563 * this watchdog driver. It tolerates, if "get-sensor-state" and
564 * "ibm,get-system-parameter" are not available.
565 */
566static int
567wdrtas_get_tokens(void)
568{
569 wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");
570 if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {
571 printk(KERN_WARNING "wdrtas: couldn't get token for "
572 "get-sensor-state. Trying to continue without "
573 "temperature support.\n");
574 }
575
576 wdrtas_token_get_sp = rtas_token("ibm,get-system-parameter");
577 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) {
578 printk(KERN_WARNING "wdrtas: couldn't get token for "
579 "ibm,get-system-parameter. Trying to continue with "
580 "a default timeout value of %i seconds.\n",
581 WDRTAS_DEFAULT_INTERVAL);
582 }
583
584 wdrtas_token_set_indicator = rtas_token("set-indicator");
585 if (wdrtas_token_set_indicator == RTAS_UNKNOWN_SERVICE) {
586 printk(KERN_ERR "wdrtas: couldn't get token for "
587 "set-indicator. Terminating watchdog code.\n");
588 return -EIO;
589 }
590
591 wdrtas_token_event_scan = rtas_token("event-scan");
592 if (wdrtas_token_event_scan == RTAS_UNKNOWN_SERVICE) {
593 printk(KERN_ERR "wdrtas: couldn't get token for event-scan. "
594 "Terminating watchdog code.\n");
595 return -EIO;
596 }
597
598 return 0;
599}
600
601/**
602 * wdrtas_unregister_devs - unregisters the misc dev handlers
603 *
604 * wdrtas_register_devs unregisters the watchdog and temperature watchdog
605 * misc devs
606 */
607static void
608wdrtas_unregister_devs(void)
609{
610 misc_deregister(&wdrtas_miscdev);
611 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)
612 misc_deregister(&wdrtas_tempdev);
613}
614
615/**
616 * wdrtas_register_devs - registers the misc dev handlers
617 *
618 * returns 0 on succes, <0 on failure
619 *
620 * wdrtas_register_devs registers the watchdog and temperature watchdog
621 * misc devs
622 */
623static int
624wdrtas_register_devs(void)
625{
626 int result;
627
628 result = misc_register(&wdrtas_miscdev);
629 if (result) {
630 printk(KERN_ERR "wdrtas: couldn't register watchdog misc "
631 "device. Terminating watchdog code.\n");
632 return result;
633 }
634
635 if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) {
636 result = misc_register(&wdrtas_tempdev);
637 if (result) {
638 printk(KERN_WARNING "wdrtas: couldn't register "
639 "watchdog temperature misc device. Continuing "
640 "without temperature support.\n");
641 wdrtas_token_get_sensor_state = RTAS_UNKNOWN_SERVICE;
642 }
643 }
644
645 return 0;
646}
647
648/**
649 * wdrtas_init - init function of the watchdog driver
650 *
651 * returns 0 on succes, <0 on failure
652 *
653 * registers the file handlers and the reboot notifier
654 */
655static int __init
656wdrtas_init(void)
657{
658 if (wdrtas_get_tokens())
659 return -ENODEV;
660
661 if (wdrtas_register_devs())
662 return -ENODEV;
663
664 if (register_reboot_notifier(&wdrtas_notifier)) {
665 printk(KERN_ERR "wdrtas: could not register reboot notifier. "
666 "Terminating watchdog code.\n");
667 wdrtas_unregister_devs();
668 return -ENODEV;
669 }
670
671 if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
672 wdrtas_interval = WDRTAS_DEFAULT_INTERVAL;
673 else
674 wdrtas_interval = wdrtas_get_interval(WDRTAS_DEFAULT_INTERVAL);
675
676 return 0;
677}
678
679/**
680 * wdrtas_exit - exit function of the watchdog driver
681 *
682 * unregisters the file handlers and the reboot notifier
683 */
684static void __exit
685wdrtas_exit(void)
686{
687 if (!wdrtas_nowayout)
688 wdrtas_timer_stop();
689
690 wdrtas_unregister_devs();
691
692 unregister_reboot_notifier(&wdrtas_notifier);
693}
694
695module_init(wdrtas_init);
696module_exit(wdrtas_exit);
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index df1b721154d2..839b44a7e08b 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -23,12 +23,15 @@ setup_serial_console(struct pcdp_uart *uart)
23{ 23{
24#ifdef CONFIG_SERIAL_8250_CONSOLE 24#ifdef CONFIG_SERIAL_8250_CONSOLE
25 int mmio; 25 int mmio;
26 static char options[64]; 26 static char options[64], *p = options;
27 27
28 mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); 28 mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
29 snprintf(options, sizeof(options), "console=uart,%s,0x%lx,%lun%d", 29 p += sprintf(p, "console=uart,%s,0x%lx",
30 mmio ? "mmio" : "io", uart->addr.address, uart->baud, 30 mmio ? "mmio" : "io", uart->addr.address);
31 uart->bits ? uart->bits : 8); 31 if (uart->baud)
32 p += sprintf(p, ",%lu", uart->baud);
33 if (uart->bits)
34 p += sprintf(p, "n%d", uart->bits);
32 35
33 return early_serial_console_init(options); 36 return early_serial_console_init(options);
34#else 37#else
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
index 863bb6f768c3..1dc7c88b7b4d 100644
--- a/drivers/firmware/pcdp.h
+++ b/drivers/firmware/pcdp.h
@@ -2,7 +2,7 @@
2 * Definitions for PCDP-defined console devices 2 * Definitions for PCDP-defined console devices
3 * 3 *
4 * v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf 4 * v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf
5 * v2.0: http://www.dig64.org/specifications/DIG64_HCDPv20_042804.pdf 5 * v2.0: http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
6 * 6 *
7 * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P. 7 * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P.
8 * Khalid Aziz <khalid.aziz@hp.com> 8 * Khalid Aziz <khalid.aziz@hp.com>
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index ec943cad2314..1956af382cd8 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -33,7 +33,8 @@
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/i2c-algo-bit.h> 34#include <linux/i2c-algo-bit.h>
35 35
36#include <asm/hardware.h> /* Pick up IXP42000-specific bits */ 36#include <asm/hardware.h> /* Pick up IXP2000-specific bits */
37#include <asm/arch/gpio.h>
37 38
38static inline int ixp2000_scl_pin(void *data) 39static inline int ixp2000_scl_pin(void *data)
39{ 40{
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 39f3e9101ed4..0a31cfda08a0 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2657,16 +2657,63 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
2657} 2657}
2658 2658
2659static 2659static
2660int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
2661{
2662 struct cdrom_info *info = drive->driver_data;
2663 struct cdrom_device_info *cdi = &info->devinfo;
2664 struct packet_command cgc;
2665 int stat, attempts = 3, size = sizeof(*cap);
2666
2667 /*
2668 * ACER50 (and others?) require the full spec length mode sense
2669 * page capabilities size, but older drives break.
2670 */
2671 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2672 !strcmp(drive->id->model, "WPI CDS-32X")))
2673 size -= sizeof(cap->pad);
2674
2675 init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
2676 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2677 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2678 if (!stat)
2679 break;
2680 } while (--attempts);
2681 return stat;
2682}
2683
2684static
2685void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
2686{
2687 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
2688 if (!drive->id->model[0] &&
2689 !strncmp(drive->id->fw_rev, "241N", 4)) {
2690 CDROM_STATE_FLAGS(drive)->current_speed =
2691 (((unsigned int)cap->curspeed) + (176/2)) / 176;
2692 CDROM_CONFIG_FLAGS(drive)->max_speed =
2693 (((unsigned int)cap->maxspeed) + (176/2)) / 176;
2694 } else {
2695 CDROM_STATE_FLAGS(drive)->current_speed =
2696 (ntohs(cap->curspeed) + (176/2)) / 176;
2697 CDROM_CONFIG_FLAGS(drive)->max_speed =
2698 (ntohs(cap->maxspeed) + (176/2)) / 176;
2699 }
2700}
2701
2702static
2660int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) 2703int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
2661{ 2704{
2662 ide_drive_t *drive = (ide_drive_t*) cdi->handle; 2705 ide_drive_t *drive = (ide_drive_t*) cdi->handle;
2663 struct request_sense sense; 2706 struct request_sense sense;
2707 struct atapi_capabilities_page cap;
2664 int stat; 2708 int stat;
2665 2709
2666 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0) 2710 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
2667 return stat; 2711 return stat;
2668 2712
2669 cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed; 2713 if (!ide_cdrom_get_capabilities(drive, &cap)) {
2714 ide_cdrom_update_speed(drive, &cap);
2715 cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
2716 }
2670 return 0; 2717 return 0;
2671} 2718}
2672 2719
@@ -2869,31 +2916,6 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
2869} 2916}
2870 2917
2871static 2918static
2872int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
2873{
2874 struct cdrom_info *info = drive->driver_data;
2875 struct cdrom_device_info *cdi = &info->devinfo;
2876 struct packet_command cgc;
2877 int stat, attempts = 3, size = sizeof(*cap);
2878
2879 /*
2880 * ACER50 (and others?) require the full spec length mode sense
2881 * page capabilities size, but older drives break.
2882 */
2883 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2884 !strcmp(drive->id->model, "WPI CDS-32X")))
2885 size -= sizeof(cap->pad);
2886
2887 init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
2888 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2889 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2890 if (!stat)
2891 break;
2892 } while (--attempts);
2893 return stat;
2894}
2895
2896static
2897int ide_cdrom_probe_capabilities (ide_drive_t *drive) 2919int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2898{ 2920{
2899 struct cdrom_info *info = drive->driver_data; 2921 struct cdrom_info *info = drive->driver_data;
@@ -2978,20 +3000,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2978 } 3000 }
2979 } 3001 }
2980 3002
2981 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ 3003 ide_cdrom_update_speed(drive, &cap);
2982 if (!drive->id->model[0] &&
2983 !strncmp(drive->id->fw_rev, "241N", 4)) {
2984 CDROM_STATE_FLAGS(drive)->current_speed =
2985 (((unsigned int)cap.curspeed) + (176/2)) / 176;
2986 CDROM_CONFIG_FLAGS(drive)->max_speed =
2987 (((unsigned int)cap.maxspeed) + (176/2)) / 176;
2988 } else {
2989 CDROM_STATE_FLAGS(drive)->current_speed =
2990 (ntohs(cap.curspeed) + (176/2)) / 176;
2991 CDROM_CONFIG_FLAGS(drive)->max_speed =
2992 (ntohs(cap.maxspeed) + (176/2)) / 176;
2993 }
2994
2995 /* don't print speed if the drive reported 0. 3004 /* don't print speed if the drive reported 0.
2996 */ 3005 */
2997 printk(KERN_INFO "%s: ATAPI", drive->name); 3006 printk(KERN_INFO "%s: ATAPI", drive->name);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 3302cd8eab4c..d6f934886b04 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1215,7 +1215,8 @@ static int ide_disk_probe(struct device *dev)
1215 if (!idkp) 1215 if (!idkp)
1216 goto failed; 1216 goto failed;
1217 1217
1218 g = alloc_disk(1 << PARTN_BITS); 1218 g = alloc_disk_node(1 << PARTN_BITS,
1219 pcibus_to_node(drive->hwif->pci_dev->bus));
1219 if (!g) 1220 if (!g)
1220 goto out_free_idkp; 1221 goto out_free_idkp;
1221 1222
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index c949e98df4b6..9eab6426148e 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -661,10 +661,12 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
661 661
662 idefloppy_do_end_request(drive, 1, done >> 9); 662 idefloppy_do_end_request(drive, 1, done >> 9);
663 663
664#if IDEFLOPPY_DEBUG_BUGS
664 if (bcount) { 665 if (bcount) {
665 printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); 666 printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
666 idefloppy_write_zeros(drive, bcount); 667 idefloppy_write_zeros(drive, bcount);
667 } 668 }
669#endif
668} 670}
669 671
670static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc) 672static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
@@ -1048,6 +1050,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
1048 atapi_bcount_t bcount; 1050 atapi_bcount_t bcount;
1049 ide_handler_t *pkt_xfer_routine; 1051 ide_handler_t *pkt_xfer_routine;
1050 1052
1053#if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone
1054 and have lived on another thread's stack; that stack may have become
1055 unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */
1051#if IDEFLOPPY_DEBUG_BUGS 1056#if IDEFLOPPY_DEBUG_BUGS
1052 if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && 1057 if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD &&
1053 pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { 1058 pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
@@ -1055,6 +1060,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
1055 "Two request sense in serial were issued\n"); 1060 "Two request sense in serial were issued\n");
1056 } 1061 }
1057#endif /* IDEFLOPPY_DEBUG_BUGS */ 1062#endif /* IDEFLOPPY_DEBUG_BUGS */
1063#endif
1058 1064
1059 if (floppy->failed_pc == NULL && 1065 if (floppy->failed_pc == NULL &&
1060 pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) 1066 pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 5d876f53c697..7df85af75371 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -977,8 +977,9 @@ static int ide_init_queue(ide_drive_t *drive)
977 * limits and LBA48 we could raise it but as yet 977 * limits and LBA48 we could raise it but as yet
978 * do not. 978 * do not.
979 */ 979 */
980 980
981 q = blk_init_queue(do_ide_request, &ide_lock); 981 q = blk_init_queue_node(do_ide_request, &ide_lock,
982 pcibus_to_node(drive->hwif->pci_dev->bus));
982 if (!q) 983 if (!q)
983 return 1; 984 return 1;
984 985
@@ -1095,7 +1096,8 @@ static int init_irq (ide_hwif_t *hwif)
1095 hwgroup->hwif->next = hwif; 1096 hwgroup->hwif->next = hwif;
1096 spin_unlock_irq(&ide_lock); 1097 spin_unlock_irq(&ide_lock);
1097 } else { 1098 } else {
1098 hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL); 1099 hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL,
1100 pcibus_to_node(hwif->drives[0].hwif->pci_dev->bus));
1099 if (!hwgroup) 1101 if (!hwgroup)
1100 goto out_up; 1102 goto out_up;
1101 1103
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index f6b85222ba3d..79ca38469159 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -257,7 +257,7 @@ static int __init serport_init(void)
257 257
258static void __exit serport_exit(void) 258static void __exit serport_exit(void)
259{ 259{
260 tty_register_ldisc(N_MOUSE, NULL); 260 tty_unregister_ldisc(N_MOUSE);
261} 261}
262 262
263module_init(serport_init); 263module_init(serport_init);
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index ee3c869d9701..200a0688f717 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -122,14 +122,6 @@ static struct hash_cell *__get_uuid_cell(const char *str)
122/*----------------------------------------------------------------- 122/*-----------------------------------------------------------------
123 * Inserting, removing and renaming a device. 123 * Inserting, removing and renaming a device.
124 *---------------------------------------------------------------*/ 124 *---------------------------------------------------------------*/
125static inline char *kstrdup(const char *str)
126{
127 char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
128 if (r)
129 strcpy(r, str);
130 return r;
131}
132
133static struct hash_cell *alloc_cell(const char *name, const char *uuid, 125static struct hash_cell *alloc_cell(const char *name, const char *uuid,
134 struct mapped_device *md) 126 struct mapped_device *md)
135{ 127{
@@ -139,7 +131,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid,
139 if (!hc) 131 if (!hc)
140 return NULL; 132 return NULL;
141 133
142 hc->name = kstrdup(name); 134 hc->name = kstrdup(name, GFP_KERNEL);
143 if (!hc->name) { 135 if (!hc->name) {
144 kfree(hc); 136 kfree(hc);
145 return NULL; 137 return NULL;
@@ -149,7 +141,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid,
149 hc->uuid = NULL; 141 hc->uuid = NULL;
150 142
151 else { 143 else {
152 hc->uuid = kstrdup(uuid); 144 hc->uuid = kstrdup(uuid, GFP_KERNEL);
153 if (!hc->uuid) { 145 if (!hc->uuid) {
154 kfree(hc->name); 146 kfree(hc->name);
155 kfree(hc); 147 kfree(hc);
@@ -273,7 +265,7 @@ static int dm_hash_rename(const char *old, const char *new)
273 /* 265 /*
274 * duplicate new. 266 * duplicate new.
275 */ 267 */
276 new_name = kstrdup(new); 268 new_name = kstrdup(new, GFP_KERNEL);
277 if (!new_name) 269 if (!new_name)
278 return -ENOMEM; 270 return -ENOMEM;
279 271
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 84a49d2ec919..4adb2843f8be 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ir-common.c,v 1.8 2005/02/22 12:28:40 kraxel Exp $ 2 * $Id: ir-common.c,v 1.10 2005/05/22 19:23:39 nsh Exp $
3 * 3 *
4 * some common structs and functions to handle infrared remotes via 4 * some common structs and functions to handle infrared remotes via
5 * input layer ... 5 * input layer ...
@@ -131,10 +131,10 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
131 [ 18 ] = KEY_KP0, 131 [ 18 ] = KEY_KP0,
132 132
133 [ 0 ] = KEY_POWER, 133 [ 0 ] = KEY_POWER,
134 [ 27 ] = KEY_LANGUAGE, //MTS button 134// [ 27 ] = MTS button
135 [ 2 ] = KEY_TUNER, // TV/FM 135 [ 2 ] = KEY_TUNER, // TV/FM
136 [ 30 ] = KEY_VIDEO, 136 [ 30 ] = KEY_VIDEO,
137 [ 22 ] = KEY_INFO, //display button 137// [ 22 ] = display button
138 [ 4 ] = KEY_VOLUMEUP, 138 [ 4 ] = KEY_VOLUMEUP,
139 [ 8 ] = KEY_VOLUMEDOWN, 139 [ 8 ] = KEY_VOLUMEDOWN,
140 [ 12 ] = KEY_CHANNELUP, 140 [ 12 ] = KEY_CHANNELUP,
@@ -142,7 +142,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
142 [ 3 ] = KEY_ZOOM, // fullscreen 142 [ 3 ] = KEY_ZOOM, // fullscreen
143 [ 31 ] = KEY_SUBTITLE, // closed caption/teletext 143 [ 31 ] = KEY_SUBTITLE, // closed caption/teletext
144 [ 32 ] = KEY_SLEEP, 144 [ 32 ] = KEY_SLEEP,
145 [ 41 ] = KEY_SEARCH, //boss key 145// [ 41 ] = boss key
146 [ 20 ] = KEY_MUTE, 146 [ 20 ] = KEY_MUTE,
147 [ 43 ] = KEY_RED, 147 [ 43 ] = KEY_RED,
148 [ 44 ] = KEY_GREEN, 148 [ 44 ] = KEY_GREEN,
@@ -150,17 +150,17 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
150 [ 46 ] = KEY_BLUE, 150 [ 46 ] = KEY_BLUE,
151 [ 24 ] = KEY_KPPLUS, //fine tune + 151 [ 24 ] = KEY_KPPLUS, //fine tune +
152 [ 25 ] = KEY_KPMINUS, //fine tune - 152 [ 25 ] = KEY_KPMINUS, //fine tune -
153 [ 42 ] = KEY_ANGLE, //picture in picture 153// [ 42 ] = picture in picture
154 [ 33 ] = KEY_KPDOT, 154 [ 33 ] = KEY_KPDOT,
155 [ 19 ] = KEY_KPENTER, 155 [ 19 ] = KEY_KPENTER,
156 [ 17 ] = KEY_AGAIN, //recall 156// [ 17 ] = recall
157 [ 34 ] = KEY_BACK, 157 [ 34 ] = KEY_BACK,
158 [ 35 ] = KEY_PLAYPAUSE, 158 [ 35 ] = KEY_PLAYPAUSE,
159 [ 36 ] = KEY_NEXT, 159 [ 36 ] = KEY_NEXT,
160 [ 37 ] = KEY_T, //time shifting 160// [ 37 ] = time shifting
161 [ 38 ] = KEY_STOP, 161 [ 38 ] = KEY_STOP,
162 [ 39 ] = KEY_RECORD, 162 [ 39 ] = KEY_RECORD
163 [ 40 ] = KEY_SHUFFLE //snapshot 163// [ 40 ] = snapshot
164}; 164};
165EXPORT_SYMBOL_GPL(ir_codes_winfast); 165EXPORT_SYMBOL_GPL(ir_codes_winfast);
166 166
@@ -184,18 +184,30 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
184 [ 0x07 ] = KEY_KP7, // 7 184 [ 0x07 ] = KEY_KP7, // 7
185 [ 0x08 ] = KEY_KP8, // 8 185 [ 0x08 ] = KEY_KP8, // 8
186 [ 0x09 ] = KEY_KP9, // 9 186 [ 0x09 ] = KEY_KP9, // 9
187 [ 0x0a ] = KEY_TEXT, // keypad asterisk as well
187 [ 0x0b ] = KEY_RED, // red button 188 [ 0x0b ] = KEY_RED, // red button
188 [ 0x0c ] = KEY_OPTION, // black key without text 189 [ 0x0c ] = KEY_RADIO, // radio
189 [ 0x0d ] = KEY_MENU, // menu 190 [ 0x0d ] = KEY_MENU, // menu
191 [ 0x0e ] = KEY_SUBTITLE, // also the # key
190 [ 0x0f ] = KEY_MUTE, // mute 192 [ 0x0f ] = KEY_MUTE, // mute
191 [ 0x10 ] = KEY_VOLUMEUP, // volume + 193 [ 0x10 ] = KEY_VOLUMEUP, // volume +
192 [ 0x11 ] = KEY_VOLUMEDOWN, // volume - 194 [ 0x11 ] = KEY_VOLUMEDOWN, // volume -
193 [ 0x1e ] = KEY_NEXT, // skip >| 195 [ 0x12 ] = KEY_PREVIOUS, // previous channel
196 [ 0x14 ] = KEY_UP, // up
197 [ 0x15 ] = KEY_DOWN, // down
198 [ 0x16 ] = KEY_LEFT, // left
199 [ 0x17 ] = KEY_RIGHT, // right
200 [ 0x18 ] = KEY_VIDEO, // Videos
201 [ 0x19 ] = KEY_AUDIO, // Music
202 [ 0x1a ] = KEY_MHP, // Pictures - presume this means "Multimedia Home Platform"- no "PICTURES" key in input.h
203 [ 0x1b ] = KEY_EPG, // Guide
204 [ 0x1c ] = KEY_TV, // TV
205 [ 0x1e ] = KEY_NEXTSONG, // skip >|
194 [ 0x1f ] = KEY_EXIT, // back/exit 206 [ 0x1f ] = KEY_EXIT, // back/exit
195 [ 0x20 ] = KEY_CHANNELUP, // channel / program + 207 [ 0x20 ] = KEY_CHANNELUP, // channel / program +
196 [ 0x21 ] = KEY_CHANNELDOWN, // channel / program - 208 [ 0x21 ] = KEY_CHANNELDOWN, // channel / program -
197 [ 0x22 ] = KEY_CHANNEL, // source (old black remote) 209 [ 0x22 ] = KEY_CHANNEL, // source (old black remote)
198 [ 0x24 ] = KEY_PREVIOUS, // replay |< 210 [ 0x24 ] = KEY_PREVIOUSSONG, // replay |<
199 [ 0x25 ] = KEY_ENTER, // OK 211 [ 0x25 ] = KEY_ENTER, // OK
200 [ 0x26 ] = KEY_SLEEP, // minimize (old black remote) 212 [ 0x26 ] = KEY_SLEEP, // minimize (old black remote)
201 [ 0x29 ] = KEY_BLUE, // blue key 213 [ 0x29 ] = KEY_BLUE, // blue key
@@ -213,6 +225,39 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
213}; 225};
214EXPORT_SYMBOL(ir_codes_hauppauge_new); 226EXPORT_SYMBOL(ir_codes_hauppauge_new);
215 227
228IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
229 [ 2 ] = KEY_KP0,
230 [ 1 ] = KEY_KP1,
231 [ 11 ] = KEY_KP2,
232 [ 27 ] = KEY_KP3,
233 [ 5 ] = KEY_KP4,
234 [ 9 ] = KEY_KP5,
235 [ 21 ] = KEY_KP6,
236 [ 6 ] = KEY_KP7,
237 [ 10 ] = KEY_KP8,
238 [ 18 ] = KEY_KP9,
239
240 [ 3 ] = KEY_TUNER, // TV/FM
241 [ 7 ] = KEY_SEARCH, // scan
242 [ 28 ] = KEY_ZOOM, // full screen
243 [ 30 ] = KEY_POWER,
244 [ 23 ] = KEY_VOLUMEDOWN,
245 [ 31 ] = KEY_VOLUMEUP,
246 [ 20 ] = KEY_CHANNELDOWN,
247 [ 22 ] = KEY_CHANNELUP,
248 [ 24 ] = KEY_MUTE,
249
250 [ 0 ] = KEY_LIST, // source
251 [ 19 ] = KEY_INFO, // loop
252 [ 16 ] = KEY_LAST, // +100
253 [ 13 ] = KEY_CLEAR, // reset
254 [ 12 ] = BTN_RIGHT, // fun++
255 [ 4 ] = BTN_LEFT, // fun--
256 [ 14 ] = KEY_GOTO, // function
257 [ 15 ] = KEY_STOP, // freeze
258};
259EXPORT_SYMBOL(ir_codes_pixelview);
260
216/* -------------------------------------------------------------------------- */ 261/* -------------------------------------------------------------------------- */
217 262
218static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) 263static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
@@ -379,3 +424,4 @@ EXPORT_SYMBOL_GPL(ir_decode_biphase);
379 * c-basic-offset: 8 424 * c-basic-offset: 8
380 * End: 425 * End:
381 */ 426 */
427
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index cb826c9adfe7..c04fd11526e0 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -403,7 +403,7 @@ static struct file_operations video_fops =
403 .llseek = no_llseek, 403 .llseek = no_llseek,
404}; 404};
405 405
406void vv_callback(struct saa7146_dev *dev, unsigned long status) 406static void vv_callback(struct saa7146_dev *dev, unsigned long status)
407{ 407{
408 u32 isr = status; 408 u32 isr = status;
409 409
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 4983e1b1bb1d..01387f883cdf 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -27,9 +27,9 @@ source "drivers/media/dvb/ttpci/Kconfig"
27 27
28comment "Supported USB Adapters" 28comment "Supported USB Adapters"
29 depends on DVB_CORE && USB 29 depends on DVB_CORE && USB
30source "drivers/media/dvb/dvb-usb/Kconfig"
30source "drivers/media/dvb/ttusb-budget/Kconfig" 31source "drivers/media/dvb/ttusb-budget/Kconfig"
31source "drivers/media/dvb/ttusb-dec/Kconfig" 32source "drivers/media/dvb/ttusb-dec/Kconfig"
32source "drivers/media/dvb/dibusb/Kconfig"
33source "drivers/media/dvb/cinergyT2/Kconfig" 33source "drivers/media/dvb/cinergyT2/Kconfig"
34 34
35comment "Supported FlexCopII (B2C2) Adapters" 35comment "Supported FlexCopII (B2C2) Adapters"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 520fc3902819..3c6ff1619103 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/ cinergyT2/ 5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 99bd675df955..fafd0ab3a28f 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -6,6 +6,7 @@ config DVB_B2C2_FLEXCOP
6 select DVB_MT312 6 select DVB_MT312
7 select DVB_NXT2002 7 select DVB_NXT2002
8 select DVB_STV0297 8 select DVB_STV0297
9 select DVB_BCM3510
9 help 10 help
10 Support for the digital TV receiver chip made by B2C2 Inc. included in 11 Support for the digital TV receiver chip made by B2C2 Inc. included in
11 Technisats PCI cards and USB boxes. 12 Technisats PCI cards and USB boxes.
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 71be400e9aeb..0410cc96a48e 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -10,6 +10,7 @@
10#include "stv0299.h" 10#include "stv0299.h"
11#include "mt352.h" 11#include "mt352.h"
12#include "nxt2002.h" 12#include "nxt2002.h"
13#include "bcm3510.h"
13#include "stv0297.h" 14#include "stv0297.h"
14#include "mt312.h" 15#include "mt312.h"
15 16
@@ -285,21 +286,25 @@ static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_front
285} 286}
286 287
287static struct mt352_config samsung_tdtc9251dh0_config = { 288static struct mt352_config samsung_tdtc9251dh0_config = {
288
289 .demod_address = 0x0f, 289 .demod_address = 0x0f,
290 .demod_init = samsung_tdtc9251dh0_demod_init, 290 .demod_init = samsung_tdtc9251dh0_demod_init,
291 .pll_set = samsung_tdtc9251dh0_pll_set, 291 .pll_set = samsung_tdtc9251dh0_pll_set,
292}; 292};
293 293
294static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) 294static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
295{ 295{
296 struct flexcop_device *fc = fe->dvb->priv; 296 struct flexcop_device *fc = fe->dvb->priv;
297 return request_firmware(fw, name, fc->dev); 297 return request_firmware(fw, name, fc->dev);
298} 298}
299 299
300static struct nxt2002_config samsung_tbmv_config = { 300static struct nxt2002_config samsung_tbmv_config = {
301 .demod_address = 0x0a, 301 .demod_address = 0x0a,
302 .request_firmware = nxt2002_request_firmware, 302 .request_firmware = flexcop_fe_request_firmware,
303};
304
305static struct bcm3510_config air2pc_atsc_first_gen_config = {
306 .demod_address = 0x0f,
307 .request_firmware = flexcop_fe_request_firmware,
303}; 308};
304 309
305static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 310static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -354,11 +359,16 @@ int flexcop_frontend_init(struct flexcop_device *fc)
354 fc->dev_type = FC_AIR_DVB; 359 fc->dev_type = FC_AIR_DVB;
355 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); 360 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
356 } else 361 } else
357 /* try the air atsc (nxt2002) */ 362 /* try the air atsc 2nd generation (nxt2002) */
358 if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { 363 if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
359 fc->dev_type = FC_AIR_ATSC; 364 fc->dev_type = FC_AIR_ATSC2;
360 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); 365 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
361 } else 366 } else
367 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
368 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
369 fc->dev_type = FC_AIR_ATSC1;
370 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
371 } else
362 /* try the cable dvb (stv0297) */ 372 /* try the cable dvb (stv0297) */
363 if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) { 373 if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) {
364 fc->dev_type = FC_CABLE; 374 fc->dev_type = FC_CABLE;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 19e06da46774..23082545651f 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -45,11 +45,12 @@ const char *flexcop_revision_names[] = {
45 45
46const char *flexcop_device_names[] = { 46const char *flexcop_device_names[] = {
47 "Unkown device", 47 "Unkown device",
48 "AirStar 2 DVB-T", 48 "Air2PC/AirStar 2 DVB-T",
49 "AirStar 2 ATSC", 49 "Air2PC/AirStar 2 ATSC 1st generation",
50 "SkyStar 2 DVB-S", 50 "Air2PC/AirStar 2 ATSC 2nd generation",
51 "SkyStar 2 DVB-S (old version)", 51 "Sky2PC/SkyStar 2 DVB-S",
52 "CableStar 2 DVB-C", 52 "Sky2PC/SkyStar 2 DVB-S (old version)",
53 "Cable2PC/CableStar 2 DVB-C",
53}; 54};
54 55
55const char *flexcop_bus_names[] = { 56const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 5e131be55cb3..75b50f21afe6 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -21,7 +21,8 @@ extern const char *flexcop_revision_names[];
21typedef enum { 21typedef enum {
22 FC_UNK = 0, 22 FC_UNK = 0,
23 FC_AIR_DVB, 23 FC_AIR_DVB,
24 FC_AIR_ATSC, 24 FC_AIR_ATSC1,
25 FC_AIR_ATSC2,
25 FC_SKY, 26 FC_SKY,
26 FC_SKY_OLD, 27 FC_SKY_OLD,
27 FC_CABLE, 28 FC_CABLE,
diff --git a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig
deleted file mode 100644
index 74dfc73ae5b0..000000000000
--- a/drivers/media/dvb/dibusb/Kconfig
+++ /dev/null
@@ -1,62 +0,0 @@
1config DVB_DIBUSB
2 tristate "DiBcom USB DVB-T devices (see help for a complete device list)"
3 depends on DVB_CORE && USB
4 select FW_LOADER
5 select DVB_DIB3000MB
6 select DVB_DIB3000MC
7 select DVB_MT352
8 help
9 Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
10 DiBcom (http://www.dibcom.fr) and C&E.
11
12 Devices supported by this driver:
13
14 TwinhanDTV USB-Ter (VP7041)
15 TwinhanDTV Magic Box (VP7041e)
16 KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
17 Hama DVB-T USB-Box
18 DiBcom reference devices (non-public)
19 Ultima Electronic/Artec T1 USB TVBOX
20 Compro Videomate DVB-U2000 - DVB-T USB
21 Grandtec DVB-T USB
22 Avermedia AverTV DVBT USB
23 Artec T1 USB1.1 and USB2.0 boxes
24 Yakumo/Typhoon DVB-T USB2.0
25 Hanftek UMT-010 USB2.0
26 Hauppauge WinTV NOVA-T USB2
27
28 The VP7041 seems to be identical to "CTS Portable" (Chinese
29 Television System).
30
31 These devices can be understood as budget ones, they "only" deliver
32 (a part of) the MPEG2 transport stream.
33
34 A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
35 details.
36
37 Say Y if you own such a device and want to use it. You should build it as
38 a module.
39
40config DVB_DIBUSB_MISDESIGNED_DEVICES
41 bool "Enable support for some misdesigned (see help) devices, which identify with wrong IDs"
42 depends on DVB_DIBUSB
43 help
44 Somehow Artec/Ultima Electronic forgot to program the eeprom of some of their
45 USB1.1/USB2.0 devices.
46 So comes that they identify with the default Vendor and Product ID of the Cypress
47 CY7C64613 (AN2235) or Cypress FX2.
48
49 Affected device IDs:
50 0x0574:0x2235 (Artec T1 USB1.1, cold)
51 0x04b4:0x8613 (Artec T1 USB2.0, cold)
52 0x0574:0x1002 (Artec T1 USB2.0, warm)
53 0x0574:0x2131 (aged DiBcom USB1.1 test device)
54
55 Say Y if your device has one of the mentioned IDs.
56
57config DVB_DIBCOM_DEBUG
58 bool "Enable extended debug support for DiBcom USB device"
59 depends on DVB_DIBUSB
60 help
61 Say Y if you want to enable debuging. See modinfo dvb-dibusb for
62 debug levels.
diff --git a/drivers/media/dvb/dibusb/Makefile b/drivers/media/dvb/dibusb/Makefile
deleted file mode 100644
index e941c508624e..000000000000
--- a/drivers/media/dvb/dibusb/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1dvb-dibusb-objs = dvb-dibusb-core.o \
2 dvb-dibusb-dvb.o \
3 dvb-dibusb-fe-i2c.o \
4 dvb-dibusb-firmware.o \
5 dvb-dibusb-remote.o \
6 dvb-dibusb-usb.o \
7 dvb-fe-dtt200u.o
8
9obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
10
11EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
deleted file mode 100644
index 26235f9247e4..000000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-core.c
+++ /dev/null
@@ -1,558 +0,0 @@
1/*
2 * Driver for mobile USB Budget DVB-T devices based on reference
3 * design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * dvb-dibusb-core.c
6 *
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8 *
9 * based on GPL code from DiBcom, which has
10 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
11 *
12 * Remote control code added by David Matthews (dm@prolingua.co.uk)
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation, version 2.
17 *
18 * Acknowledgements
19 *
20 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
21 * sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
22 *
23 * see Documentation/dvb/README.dibusb for more information
24 */
25#include "dvb-dibusb.h"
26
27#include <linux/moduleparam.h>
28
29/* debug */
30int dvb_dibusb_debug;
31module_param_named(debug, dvb_dibusb_debug, int, 0644);
32
33#ifdef CONFIG_DVB_DIBCOM_DEBUG
34#define DBSTATUS ""
35#else
36#define DBSTATUS " (debugging is not enabled)"
37#endif
38MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS);
39#undef DBSTATUS
40
41static int pid_parse;
42module_param(pid_parse, int, 0644);
43MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
44
45static int rc_query_interval = 100;
46module_param(rc_query_interval, int, 0644);
47MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
48
49static int rc_key_repeat_count = 2;
50module_param(rc_key_repeat_count, int, 0644);
51MODULE_PARM_DESC(rc_key_repeat_count, "how many key repeats will be dropped before passing the key event again (default: 2)");
52
53/* Vendor IDs */
54#define USB_VID_ADSTECH 0x06e1
55#define USB_VID_ANCHOR 0x0547
56#define USB_VID_AVERMEDIA 0x14aa
57#define USB_VID_COMPRO 0x185b
58#define USB_VID_COMPRO_UNK 0x145f
59#define USB_VID_CYPRESS 0x04b4
60#define USB_VID_DIBCOM 0x10b8
61#define USB_VID_EMPIA 0xeb1a
62#define USB_VID_GRANDTEC 0x5032
63#define USB_VID_HANFTEK 0x15f4
64#define USB_VID_HAUPPAUGE 0x2040
65#define USB_VID_HYPER_PALTEK 0x1025
66#define USB_VID_IMC_NETWORKS 0x13d3
67#define USB_VID_TWINHAN 0x1822
68#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
69
70/* Product IDs */
71#define USB_PID_ADSTECH_USB2_COLD 0xa333
72#define USB_PID_ADSTECH_USB2_WARM 0xa334
73#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
74#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
75#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
76#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
77#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
78#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
79#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
80#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
81#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
82#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
83#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
84#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
85#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
86#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
87#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
88#define USB_PID_TWINHAN_VP7041_COLD 0x3201
89#define USB_PID_TWINHAN_VP7041_WARM 0x3202
90#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
91#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
92#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
93#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
94#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
95#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
96#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
97#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
98#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
99#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
100#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
101#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
102#define USB_PID_YAKUMO_DTT200U_COLD 0x0201
103#define USB_PID_YAKUMO_DTT200U_WARM 0x0301
104#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
105#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
106
107/* USB Driver stuff
108 * table of devices that this driver is working with
109 *
110 * ATTENTION: Never ever change the order of this table, the particular
111 * devices depend on this order
112 *
113 * Each entry is used as a reference in the device_struct. Currently this is
114 * the only non-redundant way of assigning USB ids to actual devices I'm aware
115 * of, because there is only one place in the code where the assignment of
116 * vendor and product id is done, here.
117 */
118static struct usb_device_id dib_table [] = {
119/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
120/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
121/* 02 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_COLD) },
122/* 03 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_WARM) },
123
124/* 04 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
125/* 05 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
126/* 06 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
127/* 07 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
128/* 08 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
129/* 09 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
130/* 10 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
131/* 11 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
132/* 12 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
133/* 13 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
134/* 14 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
135/* 15 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
136/* 16 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
137/* 17 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
138/* 18 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
139/* 19 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_COLD) },
140/* 20 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_WARM) },
141/* 21 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
142/* 22 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
143/* 23 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
144/* 24 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
145/* 25 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
146/* 26 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
147/* 27 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
148
149/* 28 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
150/* 29 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
151
152/* 30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
153/* 31 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
154/* 32 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
155/* 33 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
156/*
157 * activate the following define when you have one of the devices and want to
158 * build it from build-2.6 in dvb-kernel
159 */
160// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
161#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
162/* 34 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
163/* 35 */ { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
164/* 36 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
165/* 37 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_DIBCOM_ANCHOR_2135_COLD) },
166#endif
167 { } /* Terminating entry */
168};
169
170MODULE_DEVICE_TABLE (usb, dib_table);
171
172static struct dibusb_usb_controller dibusb_usb_ctrl[] = {
173 { .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
174 { .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
175 { .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
176};
177
178struct dibusb_tuner dibusb_tuner[] = {
179 { DIBUSB_TUNER_CABLE_THOMSON,
180 0x61
181 },
182 { DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
183 0x60
184 },
185 { DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
186 0x61
187 },
188 { DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
189 0x60
190 },
191};
192
193static struct dibusb_demod dibusb_demod[] = {
194 { DIBUSB_DIB3000MB,
195 16,
196 { 0x8, 0 },
197 },
198 { DIBUSB_DIB3000MC,
199 32,
200 { 0x9, 0xa, 0xb, 0xc },
201 },
202 { DIBUSB_MT352,
203 254,
204 { 0xf, 0 },
205 },
206 { DTT200U_FE,
207 8,
208 { 0xff,0 }, /* there is no i2c bus in this device */
209 }
210};
211
212static struct dibusb_device_class dibusb_device_classes[] = {
213 { .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
214 .firmware = "dvb-dibusb-5.0.0.11.fw",
215 .pipe_cmd = 0x01, .pipe_data = 0x02,
216 .urb_count = 7, .urb_buffer_size = 4096,
217 DIBUSB_RC_NEC_PROTOCOL,
218 &dibusb_demod[DIBUSB_DIB3000MB],
219 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
220 },
221 { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
222 "dvb-dibusb-an2235-1.fw",
223 0x01, 0x02,
224 7, 4096,
225 DIBUSB_RC_NEC_PROTOCOL,
226 &dibusb_demod[DIBUSB_DIB3000MB],
227 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
228 },
229 { DIBUSB2_0,&dibusb_usb_ctrl[2],
230 "dvb-dibusb-6.0.0.5.fw",
231 0x01, 0x06,
232 7, 4096,
233 DIBUSB_RC_NEC_PROTOCOL,
234 &dibusb_demod[DIBUSB_DIB3000MC],
235 &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
236 },
237 { UMT2_0, &dibusb_usb_ctrl[2],
238 "dvb-dibusb-umt-2.fw",
239 0x01, 0x06,
240 20, 512,
241 DIBUSB_RC_NO,
242 &dibusb_demod[DIBUSB_MT352],
243 &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
244 },
245 { DIBUSB2_0B,&dibusb_usb_ctrl[2],
246 "dvb-dibusb-adstech-usb2-1.fw",
247 0x01, 0x06,
248 7, 4096,
249 DIBUSB_RC_NEC_PROTOCOL,
250 &dibusb_demod[DIBUSB_DIB3000MB],
251 &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
252 },
253 { NOVAT_USB2,&dibusb_usb_ctrl[2],
254 "dvb-dibusb-nova-t-1.fw",
255 0x01, 0x06,
256 7, 4096,
257 DIBUSB_RC_HAUPPAUGE_PROTO,
258 &dibusb_demod[DIBUSB_DIB3000MC],
259 &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
260 },
261 { DTT200U,&dibusb_usb_ctrl[2],
262 "dvb-dtt200u-1.fw",
263 0x01, 0x02,
264 7, 4096,
265 DIBUSB_RC_NO,
266 &dibusb_demod[DTT200U_FE],
267 NULL, /* no explicit tuner/pll-programming necessary (it has the ENV57H1XD5) */
268 },
269};
270
271static struct dibusb_usb_device dibusb_devices[] = {
272 { "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
273 &dibusb_device_classes[DIBUSB1_1],
274 { &dib_table[19], &dib_table[21], NULL},
275 { &dib_table[20], &dib_table[22], NULL},
276 },
277 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
278 &dibusb_device_classes[DIBUSB1_1],
279 { &dib_table[11], NULL },
280 { &dib_table[12], NULL },
281 },
282 { "Grandtec USB1.1 DVB-T",
283 &dibusb_device_classes[DIBUSB1_1],
284 { &dib_table[13], &dib_table[15], NULL },
285 { &dib_table[14], &dib_table[16], NULL },
286 },
287 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
288 &dibusb_device_classes[DIBUSB1_1],
289 { &dib_table[7], NULL },
290 { &dib_table[8], NULL },
291 },
292 { "Artec T1 USB1.1 TVBOX with AN2135",
293 &dibusb_device_classes[DIBUSB1_1],
294 { &dib_table[23], NULL },
295 { &dib_table[24], NULL },
296 },
297 { "Artec T1 USB1.1 TVBOX with AN2235",
298 &dibusb_device_classes[DIBUSB1_1_AN2235],
299 { &dib_table[25], NULL },
300 { &dib_table[26], NULL },
301 },
302 { "Avermedia AverTV DVBT USB1.1",
303 &dibusb_device_classes[DIBUSB1_1],
304 { &dib_table[0], NULL },
305 { &dib_table[1], NULL },
306 },
307 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
308 &dibusb_device_classes[DIBUSB1_1],
309 { &dib_table[4], &dib_table[6], NULL},
310 { &dib_table[5], NULL },
311 },
312 { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
313 &dibusb_device_classes[DIBUSB1_1],
314 { &dib_table[17], NULL },
315 { &dib_table[18], NULL },
316 },
317 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
318 &dibusb_device_classes[DIBUSB2_0],
319 { &dib_table[9], NULL },
320 { &dib_table[10], NULL },
321 },
322 { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
323 &dibusb_device_classes[DIBUSB2_0],
324 { &dib_table[27], NULL },
325 { NULL },
326 },
327 { "Hauppauge WinTV NOVA-T USB2",
328 &dibusb_device_classes[NOVAT_USB2],
329 { &dib_table[30], NULL },
330 { &dib_table[31], NULL },
331 },
332 { "DTT200U (Yakumo/Hama/Typhoon) DVB-T USB2.0",
333 &dibusb_device_classes[DTT200U],
334 { &dib_table[2], NULL },
335 { &dib_table[3], NULL },
336 },
337 { "Hanftek UMT-010 DVB-T USB2.0",
338 &dibusb_device_classes[UMT2_0],
339 { &dib_table[28], NULL },
340 { &dib_table[29], NULL },
341 },
342 { "KWorld/ADSTech Instant DVB-T USB 2.0",
343 &dibusb_device_classes[DIBUSB2_0B],
344 { &dib_table[32], NULL },
345 { &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */
346 },
347#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
348 { "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
349 &dibusb_device_classes[DIBUSB1_1_AN2235],
350 { &dib_table[34], NULL },
351 { NULL },
352 },
353 { "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
354 &dibusb_device_classes[DTT200U],
355 { &dib_table[35], NULL },
356 { &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
357 },
358 { "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
359 &dibusb_device_classes[DIBUSB1_1],
360 { &dib_table[37], NULL },
361 { NULL },
362 },
363#endif
364};
365
366static int dibusb_exit(struct usb_dibusb *dib)
367{
368 deb_info("init_state before exiting everything: %x\n",dib->init_state);
369 dibusb_remote_exit(dib);
370 dibusb_fe_exit(dib);
371 dibusb_i2c_exit(dib);
372 dibusb_dvb_exit(dib);
373 dibusb_urb_exit(dib);
374 deb_info("init_state should be zero now: %x\n",dib->init_state);
375 dib->init_state = DIBUSB_STATE_INIT;
376 kfree(dib);
377 return 0;
378}
379
380static int dibusb_init(struct usb_dibusb *dib)
381{
382 int ret = 0;
383 sema_init(&dib->usb_sem, 1);
384 sema_init(&dib->i2c_sem, 1);
385
386 dib->init_state = DIBUSB_STATE_INIT;
387
388 if ((ret = dibusb_urb_init(dib)) ||
389 (ret = dibusb_dvb_init(dib)) ||
390 (ret = dibusb_i2c_init(dib))) {
391 dibusb_exit(dib);
392 return ret;
393 }
394
395 if ((ret = dibusb_fe_init(dib)))
396 err("could not initialize a frontend.");
397
398 if ((ret = dibusb_remote_init(dib)))
399 err("could not initialize remote control.");
400
401 return 0;
402}
403
404static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev)
405{
406 int i;
407
408 /* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB
409 * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad
410 * idea and make this quirk necessary.
411 */
412 if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) {
413 info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal.");
414 for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
415 if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) {
416 dev = &dibusb_devices[i];
417 break;
418 }
419 }
420 }
421
422 return dev;
423}
424
425static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
426{
427 int i,j;
428 struct dibusb_usb_device *dev = NULL;
429 *cold = -1;
430
431 for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
432 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
433 deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
434 if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
435 dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
436 *cold = 1;
437 dev = &dibusb_devices[i];
438 break;
439 }
440 }
441
442 if (dev != NULL)
443 break;
444
445 for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
446 deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
447 if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
448 dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
449 *cold = 0;
450 dev = &dibusb_devices[i];
451 break;
452 }
453 }
454 }
455
456 if (dev != NULL)
457 dev = dibusb_device_class_quirk(udev,dev);
458
459 return dev;
460}
461
462/*
463 * USB
464 */
465static int dibusb_probe(struct usb_interface *intf,
466 const struct usb_device_id *id)
467{
468 struct usb_device *udev = interface_to_usbdev(intf);
469 struct usb_dibusb *dib = NULL;
470 struct dibusb_usb_device *dibdev = NULL;
471
472 int ret = -ENOMEM,cold=0;
473
474 if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) {
475 err("something went very wrong, "
476 "unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct));
477 return -ENODEV;
478 }
479
480 if (cold == 1) {
481 info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
482 ret = dibusb_loadfirmware(udev,dibdev);
483 } else {
484 info("found a '%s' in warm state.",dibdev->name);
485 dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
486 if (dib == NULL) {
487 err("no memory");
488 return ret;
489 }
490 memset(dib,0,sizeof(struct usb_dibusb));
491
492 dib->udev = udev;
493 dib->dibdev = dibdev;
494
495 /* store parameters to structures */
496 dib->rc_query_interval = rc_query_interval;
497 dib->pid_parse = pid_parse;
498 dib->rc_key_repeat_count = rc_key_repeat_count;
499
500 usb_set_intfdata(intf, dib);
501
502 ret = dibusb_init(dib);
503 }
504
505 if (ret == 0)
506 info("%s successfully initialized and connected.",dibdev->name);
507 else
508 info("%s error while loading driver (%d)",dibdev->name,ret);
509 return ret;
510}
511
512static void dibusb_disconnect(struct usb_interface *intf)
513{
514 struct usb_dibusb *dib = usb_get_intfdata(intf);
515 const char *name = DRIVER_DESC;
516
517 usb_set_intfdata(intf,NULL);
518 if (dib != NULL && dib->dibdev != NULL) {
519 name = dib->dibdev->name;
520 dibusb_exit(dib);
521 }
522 info("%s successfully deinitialized and disconnected.",name);
523
524}
525
526/* usb specific object needed to register this driver with the usb subsystem */
527static struct usb_driver dibusb_driver = {
528 .owner = THIS_MODULE,
529 .name = DRIVER_DESC,
530 .probe = dibusb_probe,
531 .disconnect = dibusb_disconnect,
532 .id_table = dib_table,
533};
534
535/* module stuff */
536static int __init usb_dibusb_init(void)
537{
538 int result;
539 if ((result = usb_register(&dibusb_driver))) {
540 err("usb_register failed. Error number %d",result);
541 return result;
542 }
543
544 return 0;
545}
546
547static void __exit usb_dibusb_exit(void)
548{
549 /* deregister this driver from the USB subsystem */
550 usb_deregister(&dibusb_driver);
551}
552
553module_init (usb_dibusb_init);
554module_exit (usb_dibusb_exit);
555
556MODULE_AUTHOR(DRIVER_AUTHOR);
557MODULE_DESCRIPTION(DRIVER_DESC);
558MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
deleted file mode 100644
index 400b439e804e..000000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
+++ /dev/null
@@ -1,185 +0,0 @@
1/*
2 * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for initializing and handling the
10 * linux-dvb API.
11 */
12#include "dvb-dibusb.h"
13
14#include <linux/usb.h>
15#include <linux/version.h>
16
17static u32 urb_compl_count;
18
19/*
20 * MPEG2 TS DVB stuff
21 */
22void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
23{
24 struct usb_dibusb *dib = urb->context;
25
26 deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib->feedcount,urb->status,
27 urb->actual_length);
28
29 urb_compl_count++;
30 if (urb_compl_count % 1000 == 0)
31 deb_info("%d urbs completed so far.\n",urb_compl_count);
32
33 switch (urb->status) {
34 case 0: /* success */
35 case -ETIMEDOUT: /* NAK */
36 break;
37 case -ECONNRESET: /* kill */
38 case -ENOENT:
39 case -ESHUTDOWN:
40 return;
41 default: /* error */
42 deb_ts("urb completition error %d.", urb->status);
43 break;
44 }
45
46 if (dib->feedcount > 0 && urb->actual_length > 0) {
47 if (dib->init_state & DIBUSB_STATE_DVB)
48 dvb_dmx_swfilter(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length);
49 } else
50 deb_ts("URB dropped because of feedcount.\n");
51
52 usb_submit_urb(urb,GFP_ATOMIC);
53}
54
55static int dibusb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
56{
57 struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
58 int newfeedcount;
59
60 if (dib == NULL)
61 return -ENODEV;
62
63 newfeedcount = dib->feedcount + (onoff ? 1 : -1);
64
65 /*
66 * stop feed before setting a new pid if there will be no pid anymore
67 */
68 if (newfeedcount == 0) {
69 deb_ts("stop feeding\n");
70 if (dib->xfer_ops.fifo_ctrl != NULL) {
71 if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) {
72 err("error while inhibiting fifo.");
73 return -ENODEV;
74 }
75 }
76 dibusb_streaming(dib,0);
77 }
78
79 dib->feedcount = newfeedcount;
80
81 /* activate the pid on the device specific pid_filter */
82 deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
83 if (dib->pid_parse && dib->xfer_ops.pid_ctrl != NULL)
84 dib->xfer_ops.pid_ctrl(dib->fe,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
85
86 /*
87 * start the feed if this was the first pid to set and there is still a pid
88 * for reception.
89 */
90 if (dib->feedcount == onoff && dib->feedcount > 0) {
91
92 deb_ts("controlling pid parser\n");
93 if (dib->xfer_ops.pid_parse != NULL) {
94 if (dib->xfer_ops.pid_parse(dib->fe,dib->pid_parse) < 0) {
95 err("could not handle pid_parser");
96 }
97 }
98
99 deb_ts("start feeding\n");
100 if (dib->xfer_ops.fifo_ctrl != NULL) {
101 if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) {
102 err("error while enabling fifo.");
103 return -ENODEV;
104 }
105 }
106 dibusb_streaming(dib,1);
107 }
108 return 0;
109}
110
111static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
112{
113 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
114 return dibusb_ctrl_feed(dvbdmxfeed,1);
115}
116
117static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
118{
119 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
120 return dibusb_ctrl_feed(dvbdmxfeed,0);
121}
122
123int dibusb_dvb_init(struct usb_dibusb *dib)
124{
125 int ret;
126
127 urb_compl_count = 0;
128
129 if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC,
130 THIS_MODULE)) < 0) {
131 deb_info("dvb_register_adapter failed: error %d", ret);
132 goto err;
133 }
134 dib->adapter.priv = dib;
135
136/* i2c is done in dibusb_i2c_init */
137
138 dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
139
140 dib->demux.priv = (void *)dib;
141 /* get pidcount from demod */
142 dib->demux.feednum = dib->demux.filternum = 255;
143 dib->demux.start_feed = dibusb_start_feed;
144 dib->demux.stop_feed = dibusb_stop_feed;
145 dib->demux.write_to_decoder = NULL;
146 if ((ret = dvb_dmx_init(&dib->demux)) < 0) {
147 err("dvb_dmx_init failed: error %d",ret);
148 goto err_dmx;
149 }
150
151 dib->dmxdev.filternum = dib->demux.filternum;
152 dib->dmxdev.demux = &dib->demux.dmx;
153 dib->dmxdev.capabilities = 0;
154 if ((ret = dvb_dmxdev_init(&dib->dmxdev, &dib->adapter)) < 0) {
155 err("dvb_dmxdev_init failed: error %d",ret);
156 goto err_dmx_dev;
157 }
158
159 dvb_net_init(&dib->adapter, &dib->dvb_net, &dib->demux.dmx);
160
161 goto success;
162err_dmx_dev:
163 dvb_dmx_release(&dib->demux);
164err_dmx:
165 dvb_unregister_adapter(&dib->adapter);
166err:
167 return ret;
168success:
169 dib->init_state |= DIBUSB_STATE_DVB;
170 return 0;
171}
172
173int dibusb_dvb_exit(struct usb_dibusb *dib)
174{
175 if (dib->init_state & DIBUSB_STATE_DVB) {
176 dib->init_state &= ~DIBUSB_STATE_DVB;
177 deb_info("unregistering DVB part\n");
178 dvb_net_release(&dib->dvb_net);
179 dib->demux.dmx.close(&dib->demux.dmx);
180 dvb_dmxdev_release(&dib->dmxdev);
181 dvb_dmx_release(&dib->demux);
182 dvb_unregister_adapter(&dib->adapter);
183 }
184 return 0;
185}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
deleted file mode 100644
index 5a71b88797d9..000000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
+++ /dev/null
@@ -1,582 +0,0 @@
1/*
2 * dvb-dibusb-fe-i2c.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for attaching, initializing of an appropriate
10 * demodulator/frontend. I2C-stuff is also located here.
11 *
12 */
13#include "dvb-dibusb.h"
14
15#include <linux/usb.h>
16
17static int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr,
18 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
19{
20 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
21 /* write only ? */
22 int wo = (rbuf == NULL || rlen == 0),
23 len = 2 + wlen + (wo ? 0 : 2);
24
25 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
26 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
27
28 memcpy(&sndbuf[2],wbuf,wlen);
29
30 if (!wo) {
31 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
32 sndbuf[wlen+3] = rlen & 0xff;
33 }
34
35 return dibusb_readwrite_usb(dib,sndbuf,len,rbuf,rlen);
36}
37
38/*
39 * I2C master xfer function
40 */
41static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
42{
43 struct usb_dibusb *dib = i2c_get_adapdata(adap);
44 int i;
45
46 if (down_interruptible(&dib->i2c_sem) < 0)
47 return -EAGAIN;
48
49 if (num > 2)
50 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
51
52 for (i = 0; i < num; i++) {
53 /* write/read request */
54 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
55 if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,
56 msg[i+1].buf,msg[i+1].len) < 0)
57 break;
58 i++;
59 } else
60 if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
61 break;
62 }
63
64 up(&dib->i2c_sem);
65 return i;
66}
67
68static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
69{
70 return I2C_FUNC_I2C;
71}
72
73static struct i2c_algorithm dibusb_algo = {
74 .name = "DiBcom USB i2c algorithm",
75 .id = I2C_ALGO_BIT,
76 .master_xfer = dibusb_i2c_xfer,
77 .functionality = dibusb_i2c_func,
78};
79
80static int dibusb_general_demod_init(struct dvb_frontend *fe);
81static u8 dibusb_general_pll_addr(struct dvb_frontend *fe);
82static int dibusb_general_pll_init(struct dvb_frontend *fe, u8 pll_buf[5]);
83static int dibusb_general_pll_set(struct dvb_frontend *fe,
84 struct dvb_frontend_parameters* params, u8 pll_buf[5]);
85
86static struct mt352_config mt352_hanftek_umt_010_config = {
87 .demod_address = 0x1e,
88 .demod_init = dibusb_general_demod_init,
89 .pll_set = dibusb_general_pll_set,
90};
91
92static int dibusb_tuner_quirk(struct usb_dibusb *dib)
93{
94 switch (dib->dibdev->dev_cl->id) {
95 case DIBUSB1_1: /* some these device have the ENV77H11D5 and some the THOMSON CABLE */
96 case DIBUSB1_1_AN2235: { /* actually its this device, but in warm state they are indistinguishable */
97 struct dibusb_tuner *t;
98 u8 b[2] = { 0,0 } ,b2[1];
99 struct i2c_msg msg[2] = {
100 { .flags = 0, .buf = b, .len = 2 },
101 { .flags = I2C_M_RD, .buf = b2, .len = 1},
102 };
103
104 t = &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5];
105
106 msg[0].addr = msg[1].addr = t->pll_addr;
107
108 if (dib->xfer_ops.tuner_pass_ctrl != NULL)
109 dib->xfer_ops.tuner_pass_ctrl(dib->fe,1,t->pll_addr);
110 dibusb_i2c_xfer(&dib->i2c_adap,msg,2);
111 if (dib->xfer_ops.tuner_pass_ctrl != NULL)
112 dib->xfer_ops.tuner_pass_ctrl(dib->fe,0,t->pll_addr);
113
114 if (b2[0] == 0xfe)
115 info("this device has the Thomson Cable onboard. Which is default.");
116 else {
117 dib->tuner = t;
118 info("this device has the Panasonic ENV77H11D5 onboard.");
119 }
120 break;
121 }
122 default:
123 break;
124 }
125 return 0;
126}
127
128int dibusb_fe_init(struct usb_dibusb* dib)
129{
130 struct dib3000_config demod_cfg;
131 int i;
132
133 if (dib->init_state & DIBUSB_STATE_I2C) {
134 for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod->i2c_addrs) / sizeof(unsigned char) &&
135 dib->dibdev->dev_cl->demod->i2c_addrs[i] != 0; i++) {
136
137 demod_cfg.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
138 demod_cfg.pll_addr = dibusb_general_pll_addr;
139 demod_cfg.pll_set = dibusb_general_pll_set;
140 demod_cfg.pll_init = dibusb_general_pll_init;
141
142 deb_info("demod id: %d %d\n",dib->dibdev->dev_cl->demod->id,DTT200U_FE);
143
144 switch (dib->dibdev->dev_cl->demod->id) {
145 case DIBUSB_DIB3000MB:
146 dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
147 break;
148 case DIBUSB_DIB3000MC:
149 dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
150 break;
151 case DIBUSB_MT352:
152 mt352_hanftek_umt_010_config.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
153 dib->fe = mt352_attach(&mt352_hanftek_umt_010_config, &dib->i2c_adap);
154 break;
155 case DTT200U_FE:
156 dib->fe = dtt200u_fe_attach(dib,&dib->xfer_ops);
157 break;
158 }
159 if (dib->fe != NULL) {
160 info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]);
161 break;
162 }
163 }
164 /* if a frontend was found */
165 if (dib->fe != NULL) {
166 if (dib->fe->ops->sleep != NULL)
167 dib->fe_sleep = dib->fe->ops->sleep;
168 dib->fe->ops->sleep = dibusb_hw_sleep;
169
170 if (dib->fe->ops->init != NULL )
171 dib->fe_init = dib->fe->ops->init;
172 dib->fe->ops->init = dibusb_hw_wakeup;
173
174 /* setting the default tuner */
175 dib->tuner = dib->dibdev->dev_cl->tuner;
176
177 /* check which tuner is mounted on this device, in case this is unsure */
178 dibusb_tuner_quirk(dib);
179 }
180 }
181 if (dib->fe == NULL) {
182 err("A frontend driver was not found for device '%s'.",
183 dib->dibdev->name);
184 return -ENODEV;
185 } else {
186 if (dvb_register_frontend(&dib->adapter, dib->fe)) {
187 err("Frontend registration failed.");
188 if (dib->fe->ops->release)
189 dib->fe->ops->release(dib->fe);
190 dib->fe = NULL;
191 return -ENODEV;
192 }
193 }
194
195 return 0;
196}
197
198int dibusb_fe_exit(struct usb_dibusb *dib)
199{
200 if (dib->fe != NULL)
201 dvb_unregister_frontend(dib->fe);
202 return 0;
203}
204
205int dibusb_i2c_init(struct usb_dibusb *dib)
206{
207 int ret = 0;
208
209 dib->adapter.priv = dib;
210
211 strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
212#ifdef I2C_ADAP_CLASS_TV_DIGITAL
213 dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
214#else
215 dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
216#endif
217 dib->i2c_adap.algo = &dibusb_algo;
218 dib->i2c_adap.algo_data = NULL;
219 dib->i2c_adap.id = I2C_ALGO_BIT;
220
221 i2c_set_adapdata(&dib->i2c_adap, dib);
222
223 if ((ret = i2c_add_adapter(&dib->i2c_adap)) < 0)
224 err("could not add i2c adapter");
225
226 dib->init_state |= DIBUSB_STATE_I2C;
227
228 return ret;
229}
230
231int dibusb_i2c_exit(struct usb_dibusb *dib)
232{
233 if (dib->init_state & DIBUSB_STATE_I2C)
234 i2c_del_adapter(&dib->i2c_adap);
235 dib->init_state &= ~DIBUSB_STATE_I2C;
236 return 0;
237}
238
239
240/* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */
241static int thomson_cable_eu_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
242{
243 u32 tfreq = (fep->frequency + 36125000) / 62500;
244 int vu,p0,p1,p2;
245
246 if (fep->frequency > 403250000)
247 vu = 1, p2 = 1, p1 = 0, p0 = 1;
248 else if (fep->frequency > 115750000)
249 vu = 0, p2 = 1, p1 = 1, p0 = 0;
250 else if (fep->frequency > 44250000)
251 vu = 0, p2 = 0, p1 = 1, p0 = 1;
252 else
253 return -EINVAL;
254
255 pllbuf[0] = (tfreq >> 8) & 0x7f;
256 pllbuf[1] = tfreq & 0xff;
257 pllbuf[2] = 0x8e;
258 pllbuf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
259 return 0;
260}
261
262static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
263{
264 u32 freq_khz = fep->frequency / 1000;
265 u32 tfreq = ((freq_khz + 36125)*6 + 500) / 1000;
266 u8 TA, T210, R210, ctrl1, cp210, p4321;
267 if (freq_khz > 858000) {
268 err("frequency cannot be larger than 858 MHz.");
269 return -EINVAL;
270 }
271
272 // contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0
273 TA = 1;
274 T210 = 0;
275 R210 = 0x2;
276 ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210;
277
278// ******** CHARGE PUMP CONFIG vs RF FREQUENCIES *****************
279 if (freq_khz < 470000)
280 cp210 = 2; // VHF Low and High band ch E12 to E4 to E12
281 else if (freq_khz < 526000)
282 cp210 = 4; // UHF band Ch E21 to E27
283 else // if (freq < 862000000)
284 cp210 = 5; // UHF band ch E28 to E69
285
286//********************* BW select *******************************
287 if (freq_khz < 153000)
288 p4321 = 1; // BW selected for VHF low
289 else if (freq_khz < 470000)
290 p4321 = 2; // BW selected for VHF high E5 to E12
291 else // if (freq < 862000000)
292 p4321 = 4; // BW selection for UHF E21 to E69
293
294 pllbuf[0] = (tfreq >> 8) & 0xff;
295 pllbuf[1] = (tfreq >> 0) & 0xff;
296 pllbuf[2] = 0xff & ctrl1;
297 pllbuf[3] = (cp210 << 5) | (p4321);
298
299 return 0;
300}
301
302/*
303 * 7 6 5 4 3 2 1 0
304 * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
305 *
306 * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
307 * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
308 *
309 * Control byte 1 1 T/A=1 T2 T1 T0 R2 R1 R0
310 * 1 T/A=0 0 0 ATC AL2 AL1 AL0
311 *
312 * Control byte 2 CP2 CP1 CP0 BS5 BS4 BS3 BS2 BS1
313 *
314 * MA0/1 = programmable address bits
315 * R/~W = read/write bit (0 for writing)
316 * N14-0 = programmable LO frequency
317 *
318 * T/A = test AGC bit (0 = next 6 bits AGC setting,
319 * 1 = next 6 bits test and reference divider ratio settings)
320 * T2-0 = test bits
321 * R2-0 = reference divider ratio and programmable frequency step
322 * ATC = AGC current setting and time constant
323 * ATC = 0: AGC current = 220nA, AGC time constant = 2s
324 * ATC = 1: AGC current = 9uA, AGC time constant = 50ms
325 * AL2-0 = AGC take-over point bits
326 * CP2-0 = charge pump current
327 * BS5-1 = PMOS ports control bits;
328 * BSn = 0 corresponding port is off, high-impedance state (at power-on)
329 * BSn = 1 corresponding port is on
330 */
331static int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4])
332{
333 pllbuf[0] = 0x0b;
334 pllbuf[1] = 0xf5;
335 pllbuf[2] = 0x85;
336 pllbuf[3] = 0xab;
337 return 0;
338}
339
340static int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend_parameters *fep,u8 pllbuf[4])
341{
342 int tuner_frequency = 0;
343 u8 band, cp, filter;
344
345 // determine charge pump
346 tuner_frequency = fep->frequency + 36166000;
347 if (tuner_frequency < 87000000)
348 return -EINVAL;
349 else if (tuner_frequency < 130000000)
350 cp = 3;
351 else if (tuner_frequency < 160000000)
352 cp = 5;
353 else if (tuner_frequency < 200000000)
354 cp = 6;
355 else if (tuner_frequency < 290000000)
356 cp = 3;
357 else if (tuner_frequency < 420000000)
358 cp = 5;
359 else if (tuner_frequency < 480000000)
360 cp = 6;
361 else if (tuner_frequency < 620000000)
362 cp = 3;
363 else if (tuner_frequency < 830000000)
364 cp = 5;
365 else if (tuner_frequency < 895000000)
366 cp = 7;
367 else
368 return -EINVAL;
369
370 // determine band
371 if (fep->frequency < 49000000)
372 return -EINVAL;
373 else if (fep->frequency < 161000000)
374 band = 1;
375 else if (fep->frequency < 444000000)
376 band = 2;
377 else if (fep->frequency < 861000000)
378 band = 4;
379 else
380 return -EINVAL;
381
382 // setup PLL filter
383 switch (fep->u.ofdm.bandwidth) {
384 case BANDWIDTH_6_MHZ:
385 case BANDWIDTH_7_MHZ:
386 filter = 0;
387 break;
388 case BANDWIDTH_8_MHZ:
389 filter = 1;
390 break;
391 default:
392 return -EINVAL;
393 }
394
395 // calculate divisor
396 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
397 tuner_frequency = (((fep->frequency / 1000) * 6) + 217496) / 1000;
398
399 // setup tuner buffer
400 pllbuf[0] = (tuner_frequency >> 8) & 0x7f;
401 pllbuf[1] = tuner_frequency & 0xff;
402 pllbuf[2] = 0xca;
403 pllbuf[3] = (cp << 5) | (filter << 3) | band;
404 return 0;
405}
406
407/*
408 * 7 6 5 4 3 2 1 0
409 * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
410 *
411 * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
412 * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
413 *
414 * Control byte 1 CP T2 T1 T0 RSA RSB OS
415 *
416 * Band Switch byte X X X P4 P3 P2 P1 P0
417 *
418 * Auxiliary byte ATC AL2 AL1 AL0 0 0 0 0
419 *
420 * Address: MA1 MA0 Address
421 * 0 0 c0
422 * 0 1 c2 (always valid)
423 * 1 0 c4
424 * 1 1 c6
425 */
426static int lg_tdtp_e102p_tua6034(struct dvb_frontend_parameters* fep, u8 pllbuf[4])
427{
428 u32 div;
429 u8 p210, p3;
430
431#define TUNER_MUL 62500
432
433 div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
434// div = ((fep->frequency/1000 + 36166) * 6) / 1000;
435
436 if (fep->frequency < 174500000)
437 p210 = 1; // not supported by the tdtp_e102p
438 else if (fep->frequency < 230000000) // VHF
439 p210 = 2;
440 else
441 p210 = 4;
442
443 if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
444 p3 = 0;
445 else
446 p3 = 1;
447
448 pllbuf[0] = (div >> 8) & 0x7f;
449 pllbuf[1] = div & 0xff;
450 pllbuf[2] = 0xce;
451// pllbuf[2] = 0xcc;
452 pllbuf[3] = (p3 << 3) | p210;
453
454 return 0;
455}
456
457static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe)
458{
459 static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
460 static u8 mt352_reset[] = { 0x50, 0x80 };
461 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
462 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
463 static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
464
465 static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
466 static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
467 static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
468 static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
469 static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
470
471 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
472 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
473
474 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
475 udelay(2000);
476 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
477 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
478
479 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
480 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
481
482 mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
483 mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
484 mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
485 mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
486 mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
487
488 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
489 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
490
491 return 0;
492}
493
494static int dibusb_general_demod_init(struct dvb_frontend *fe)
495{
496 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
497 switch (dib->dibdev->dev_cl->id) {
498 case UMT2_0:
499 return lg_tdtp_e102p_mt352_demod_init(fe);
500 default: /* other device classes do not have device specific demod inits */
501 break;
502 }
503 return 0;
504}
505
506static u8 dibusb_general_pll_addr(struct dvb_frontend *fe)
507{
508 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
509 return dib->tuner->pll_addr;
510}
511
512static int dibusb_pll_i2c_helper(struct usb_dibusb *dib, u8 pll_buf[5], u8 buf[4])
513{
514 if (pll_buf == NULL) {
515 struct i2c_msg msg = {
516 .addr = dib->tuner->pll_addr,
517 .flags = 0,
518 .buf = buf,
519 .len = sizeof(buf)
520 };
521 if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
522 return -EIO;
523 msleep(1);
524 } else {
525 pll_buf[0] = dib->tuner->pll_addr << 1;
526 memcpy(&pll_buf[1],buf,4);
527 }
528
529 return 0;
530}
531
532static int dibusb_general_pll_init(struct dvb_frontend *fe,
533 u8 pll_buf[5])
534{
535 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
536 u8 buf[4];
537 int ret=0;
538 switch (dib->tuner->id) {
539 case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
540 ret = panasonic_cofdm_env77h11d5_tda6650_init(fe,buf);
541 break;
542 default:
543 break;
544 }
545
546 if (ret)
547 return ret;
548
549 return dibusb_pll_i2c_helper(dib,pll_buf,buf);
550}
551
552static int dibusb_general_pll_set(struct dvb_frontend *fe,
553 struct dvb_frontend_parameters *fep, u8 pll_buf[5])
554{
555 struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
556 u8 buf[4];
557 int ret=0;
558
559 switch (dib->tuner->id) {
560 case DIBUSB_TUNER_CABLE_THOMSON:
561 ret = thomson_cable_eu_pll_set(fep, buf);
562 break;
563 case DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5:
564 ret = panasonic_cofdm_env57h1xd5_pll_set(fep, buf);
565 break;
566 case DIBUSB_TUNER_CABLE_LG_TDTP_E102P:
567 ret = lg_tdtp_e102p_tua6034(fep, buf);
568 break;
569 case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
570 ret = panasonic_cofdm_env77h11d5_tda6650_set(fep,buf);
571 break;
572 default:
573 warn("no pll programming routine found for tuner %d.\n",dib->tuner->id);
574 ret = -ENODEV;
575 break;
576 }
577
578 if (ret)
579 return ret;
580
581 return dibusb_pll_i2c_helper(dib,pll_buf,buf);
582}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
deleted file mode 100644
index 504ba47afdf3..000000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
+++ /dev/null
@@ -1,87 +0,0 @@
1/*
2 * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for downloading the firmware to the device.
10 */
11#include "dvb-dibusb.h"
12
13#include <linux/firmware.h>
14#include <linux/usb.h>
15
16/*
17 * load a firmware packet to the device
18 */
19static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
20{
21 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
22 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
23}
24
25int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev)
26{
27 const struct firmware *fw = NULL;
28 u16 addr;
29 u8 *b,*p;
30 int ret = 0,i;
31
32 if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) {
33 err("did not find the firmware file. (%s) "
34 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
35 dibdev->dev_cl->firmware);
36 return ret;
37 }
38
39 info("downloading firmware from file '%s'.",dibdev->dev_cl->firmware);
40
41 p = kmalloc(fw->size,GFP_KERNEL);
42 if (p != NULL) {
43 u8 reset;
44 /*
45 * you cannot use the fw->data as buffer for
46 * usb_control_msg, a new buffer has to be
47 * created
48 */
49 memcpy(p,fw->data,fw->size);
50
51 /* stop the CPU */
52 reset = 1;
53 if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1)
54 err("could not stop the USB controller CPU.");
55 for(i = 0; p[i+3] == 0 && i < fw->size; ) {
56 b = (u8 *) &p[i];
57 addr = *((u16 *) &b[1]);
58
59 ret = dibusb_writemem(udev,addr,&b[4],b[0]);
60
61 if (ret != b[0]) {
62 err("error while transferring firmware "
63 "(transferred size: %d, block size: %d)",
64 ret,b[0]);
65 ret = -EINVAL;
66 break;
67 }
68 i += 5 + b[0];
69 }
70 /* length in ret */
71 if (ret > 0)
72 ret = 0;
73 /* restart the CPU */
74 reset = 0;
75 if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) {
76 err("could not restart the USB controller CPU.");
77 ret = -EINVAL;
78 }
79
80 kfree(p);
81 } else {
82 ret = -ENOMEM;
83 }
84 release_firmware(fw);
85
86 return ret;
87}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
deleted file mode 100644
index 9dc8b15517b7..000000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
+++ /dev/null
@@ -1,316 +0,0 @@
1/*
2 * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for handling the event device on the software
10 * side and the remote control on the hardware side.
11 */
12#include "dvb-dibusb.h"
13
14/* Table to map raw key codes to key events. This should not be hard-wired
15 into the kernel. */
16static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] =
17{
18 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
19 { 0x00, 0xff, 0x16, KEY_POWER },
20 { 0x00, 0xff, 0x10, KEY_MUTE },
21 { 0x00, 0xff, 0x03, KEY_1 },
22 { 0x00, 0xff, 0x01, KEY_2 },
23 { 0x00, 0xff, 0x06, KEY_3 },
24 { 0x00, 0xff, 0x09, KEY_4 },
25 { 0x00, 0xff, 0x1d, KEY_5 },
26 { 0x00, 0xff, 0x1f, KEY_6 },
27 { 0x00, 0xff, 0x0d, KEY_7 },
28 { 0x00, 0xff, 0x19, KEY_8 },
29 { 0x00, 0xff, 0x1b, KEY_9 },
30 { 0x00, 0xff, 0x15, KEY_0 },
31 { 0x00, 0xff, 0x05, KEY_CHANNELUP },
32 { 0x00, 0xff, 0x02, KEY_CHANNELDOWN },
33 { 0x00, 0xff, 0x1e, KEY_VOLUMEUP },
34 { 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN },
35 { 0x00, 0xff, 0x11, KEY_RECORD },
36 { 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
37 { 0x00, 0xff, 0x14, KEY_PLAY },
38 { 0x00, 0xff, 0x1a, KEY_STOP },
39 { 0x00, 0xff, 0x40, KEY_REWIND },
40 { 0x00, 0xff, 0x12, KEY_FASTFORWARD },
41 { 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
42 { 0x00, 0xff, 0x4c, KEY_PAUSE },
43 { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */
44 { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
45 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
46 { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */
47 { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */
48 { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */
49 { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */
50 { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */
51 { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */
52 /* Key codes for the KWorld/ADSTech/JetWay remote. */
53 { 0x86, 0x6b, 0x12, KEY_POWER },
54 { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */
55 { 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */
56 { 0x86, 0x6b, 0x0b, KEY_EPG },
57 { 0x86, 0x6b, 0x10, KEY_MUTE },
58 { 0x86, 0x6b, 0x01, KEY_1 },
59 { 0x86, 0x6b, 0x02, KEY_2 },
60 { 0x86, 0x6b, 0x03, KEY_3 },
61 { 0x86, 0x6b, 0x04, KEY_4 },
62 { 0x86, 0x6b, 0x05, KEY_5 },
63 { 0x86, 0x6b, 0x06, KEY_6 },
64 { 0x86, 0x6b, 0x07, KEY_7 },
65 { 0x86, 0x6b, 0x08, KEY_8 },
66 { 0x86, 0x6b, 0x09, KEY_9 },
67 { 0x86, 0x6b, 0x0a, KEY_0 },
68 { 0x86, 0x6b, 0x18, KEY_ZOOM },
69 { 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */
70 { 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */
71 { 0x86, 0x6b, 0x00, KEY_UNDO },
72 { 0x86, 0x6b, 0x1d, KEY_RECORD },
73 { 0x86, 0x6b, 0x0d, KEY_STOP },
74 { 0x86, 0x6b, 0x0e, KEY_PAUSE },
75 { 0x86, 0x6b, 0x16, KEY_PLAY },
76 { 0x86, 0x6b, 0x11, KEY_BACK },
77 { 0x86, 0x6b, 0x19, KEY_FORWARD },
78 { 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */
79 { 0x86, 0x6b, 0x15, KEY_ESC },
80 { 0x86, 0x6b, 0x1a, KEY_UP },
81 { 0x86, 0x6b, 0x1e, KEY_DOWN },
82 { 0x86, 0x6b, 0x1f, KEY_LEFT },
83 { 0x86, 0x6b, 0x1b, KEY_RIGHT },
84};
85
86/* Hauppauge NOVA-T USB2 keys */
87static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = {
88 { 0xddf, KEY_GOTO },
89 { 0xdef, KEY_POWER },
90 { 0xce7, KEY_TV },
91 { 0xcc7, KEY_VIDEO },
92 { 0xccf, KEY_AUDIO },
93 { 0xcd7, KEY_MEDIA },
94 { 0xcdf, KEY_EPG },
95 { 0xca7, KEY_UP },
96 { 0xc67, KEY_RADIO },
97 { 0xcb7, KEY_LEFT },
98 { 0xd2f, KEY_OK },
99 { 0xcbf, KEY_RIGHT },
100 { 0xcff, KEY_BACK },
101 { 0xcaf, KEY_DOWN },
102 { 0xc6f, KEY_MENU },
103 { 0xc87, KEY_VOLUMEUP },
104 { 0xc8f, KEY_VOLUMEDOWN },
105 { 0xc97, KEY_CHANNEL },
106 { 0xc7f, KEY_MUTE },
107 { 0xd07, KEY_CHANNELUP },
108 { 0xd0f, KEY_CHANNELDOWN },
109 { 0xdbf, KEY_RECORD },
110 { 0xdb7, KEY_STOP },
111 { 0xd97, KEY_REWIND },
112 { 0xdaf, KEY_PLAY },
113 { 0xda7, KEY_FASTFORWARD },
114 { 0xd27, KEY_LAST }, /* Skip backwards */
115 { 0xd87, KEY_PAUSE },
116 { 0xcf7, KEY_NEXT },
117 { 0xc07, KEY_0 },
118 { 0xc0f, KEY_1 },
119 { 0xc17, KEY_2 },
120 { 0xc1f, KEY_3 },
121 { 0xc27, KEY_4 },
122 { 0xc2f, KEY_5 },
123 { 0xc37, KEY_6 },
124 { 0xc3f, KEY_7 },
125 { 0xc47, KEY_8 },
126 { 0xc4f, KEY_9 },
127 { 0xc57, KEY_KPASTERISK },
128 { 0xc77, KEY_GRAVE }, /* # */
129 { 0xc5f, KEY_RED },
130 { 0xd77, KEY_GREEN },
131 { 0xdc7, KEY_YELLOW },
132 { 0xd4f, KEY_BLUE},
133};
134
135static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5])
136{
137 int i;
138 switch (rb[0]) {
139 case DIBUSB_RC_NEC_KEY_PRESSED:
140 /* rb[1-3] is the actual key, rb[4] is a checksum */
141 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
142 rb[1], rb[2], rb[3], rb[4]);
143
144 if ((0xff - rb[3]) != rb[4]) {
145 deb_rc("remote control checksum failed.\n");
146 break;
147 }
148
149 /* See if we can match the raw key code. */
150 for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) {
151 if (nec_rc_keys[i].c0 == rb[1] &&
152 nec_rc_keys[i].c1 == rb[2] &&
153 nec_rc_keys[i].c2 == rb[3]) {
154
155 dib->last_event = nec_rc_keys[i].key;
156 return 1;
157 }
158 }
159 break;
160 case DIBUSB_RC_NEC_KEY_REPEATED:
161 /* rb[1]..rb[4] are always zero.*/
162 /* Repeats often seem to occur so for the moment just ignore this. */
163 return 0;
164 case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
165 default:
166 break;
167 }
168 return -1;
169}
170
171static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4])
172{
173 u16 raw;
174 int i,state;
175 switch (rb[0]) {
176 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
177 raw = ((rb[1] & 0x0f) << 8) | rb[2];
178
179 state = !!(rb[1] & 0x40);
180
181 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state);
182 for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) {
183 if (haupp_rc_keys[i].raw == raw) {
184 if (dib->last_event == haupp_rc_keys[i].key &&
185 dib->last_state == state) {
186 deb_rc("key repeat\n");
187 return 0;
188 } else {
189 dib->last_event = haupp_rc_keys[i].key;
190 dib->last_state = state;
191 return 1;
192 }
193 }
194 }
195
196 break;
197 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
198 default:
199 break;
200 }
201 return -1;
202}
203
204/*
205 * Read the remote control and feed the appropriate event.
206 * NEC protocol is used for remote controls
207 */
208static int dibusb_read_remote_control(struct usb_dibusb *dib)
209{
210 u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
211 int ret,event = 0;
212
213 if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
214 return ret;
215
216 switch (dib->dibdev->dev_cl->remote_type) {
217 case DIBUSB_RC_NEC_PROTOCOL:
218 event = dibusb_key2event_nec(dib,rb);
219 break;
220 case DIBUSB_RC_HAUPPAUGE_PROTO:
221 event = dibusb_key2event_hauppauge(dib,rb);
222 default:
223 break;
224 }
225
226 /* key repeat */
227 if (event == 0)
228 if (++dib->repeat_key_count < dib->rc_key_repeat_count) {
229 deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count);
230 event = -1; /* skip this key repeat */
231 }
232
233 if (event == 1 || event == 0) {
234 deb_rc("Translated key 0x%04x\n",event);
235
236 /* Signal down and up events for this key. */
237 input_report_key(&dib->rc_input_dev, dib->last_event, 1);
238 input_report_key(&dib->rc_input_dev, dib->last_event, 0);
239 input_sync(&dib->rc_input_dev);
240
241 if (event == 1)
242 dib->repeat_key_count = 0;
243 }
244 return 0;
245}
246
247/* Remote-control poll function - called every dib->rc_query_interval ms to see
248 whether the remote control has received anything. */
249static void dibusb_remote_query(void *data)
250{
251 struct usb_dibusb *dib = (struct usb_dibusb *) data;
252 /* TODO: need a lock here. We can simply skip checking for the remote control
253 if we're busy. */
254 dibusb_read_remote_control(dib);
255 schedule_delayed_work(&dib->rc_query_work,
256 msecs_to_jiffies(dib->rc_query_interval));
257}
258
259int dibusb_remote_init(struct usb_dibusb *dib)
260{
261 int i;
262
263 if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
264 return 0;
265
266 /* Initialise the remote-control structures.*/
267 init_input_dev(&dib->rc_input_dev);
268
269 dib->rc_input_dev.evbit[0] = BIT(EV_KEY);
270 dib->rc_input_dev.keycodesize = sizeof(unsigned char);
271 dib->rc_input_dev.keycodemax = KEY_MAX;
272 dib->rc_input_dev.name = DRIVER_DESC " remote control";
273
274 switch (dib->dibdev->dev_cl->remote_type) {
275 case DIBUSB_RC_NEC_PROTOCOL:
276 for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++)
277 set_bit(nec_rc_keys[i].key, dib->rc_input_dev.keybit);
278 break;
279 case DIBUSB_RC_HAUPPAUGE_PROTO:
280 for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++)
281 set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit);
282 break;
283 default:
284 break;
285 }
286
287
288 input_register_device(&dib->rc_input_dev);
289
290 INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
291
292 /* Start the remote-control polling. */
293 if (dib->rc_query_interval < 40)
294 dib->rc_query_interval = 100; /* default */
295
296 info("schedule remote query interval to %d msecs.",dib->rc_query_interval);
297 schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval));
298
299 dib->init_state |= DIBUSB_STATE_REMOTE;
300
301 return 0;
302}
303
304int dibusb_remote_exit(struct usb_dibusb *dib)
305{
306 if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
307 return 0;
308
309 if (dib->init_state & DIBUSB_STATE_REMOTE) {
310 cancel_delayed_work(&dib->rc_query_work);
311 flush_scheduled_work();
312 input_unregister_device(&dib->rc_input_dev);
313 }
314 dib->init_state &= ~DIBUSB_STATE_REMOTE;
315 return 0;
316}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
deleted file mode 100644
index 642f0596a5ba..000000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
+++ /dev/null
@@ -1,303 +0,0 @@
1/*
2 * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * see dvb-dibusb-core.c for more copyright details.
8 *
9 * This file contains functions for initializing and handling the
10 * usb specific stuff.
11 */
12#include "dvb-dibusb.h"
13
14#include <linux/version.h>
15#include <linux/pci.h>
16
17int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
18 u16 rlen)
19{
20 int actlen,ret = -ENOMEM;
21
22 if (wbuf == NULL || wlen == 0)
23 return -EINVAL;
24
25 if ((ret = down_interruptible(&dib->usb_sem)))
26 return ret;
27
28 debug_dump(wbuf,wlen);
29
30 ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
31 dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen,
32 DIBUSB_I2C_TIMEOUT);
33
34 if (ret)
35 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
36 else
37 ret = actlen != wlen ? -1 : 0;
38
39 /* an answer is expected, and no error before */
40 if (!ret && rbuf && rlen) {
41 ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
42 dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen,
43 DIBUSB_I2C_TIMEOUT);
44
45 if (ret)
46 err("recv bulk message failed: %d",ret);
47 else {
48 deb_alot("rlen: %d\n",rlen);
49 debug_dump(rbuf,actlen);
50 }
51 }
52
53 up(&dib->usb_sem);
54 return ret;
55}
56
57/*
58 * Cypress controls
59 */
60int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
61{
62 return dibusb_readwrite_usb(dib,buf,len,NULL,0);
63}
64
65#if 0
66/*
67 * #if 0'ing the following functions as they are not in use _now_,
68 * but probably will be sometime.
69 */
70/*
71 * do not use this, just a workaround for a bug,
72 * which will hopefully never occur :).
73 */
74int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
75{
76 u8 b[1] = { DIBUSB_REQ_INTR_READ };
77 return dibusb_write_usb(dib,b,1);
78}
79#endif
80
81/*
82 * ioctl for the firmware
83 */
84static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen)
85{
86 u8 b[34];
87 int size = plen > 32 ? 32 : plen;
88 memset(b,0,34);
89 b[0] = DIBUSB_REQ_SET_IOCTL;
90 b[1] = cmd;
91
92 if (size > 0)
93 memcpy(&b[2],param,size);
94
95 return dibusb_write_usb(dib,b,34); //2+size);
96}
97
98/*
99 * ioctl for power control
100 */
101int dibusb_hw_wakeup(struct dvb_frontend *fe)
102{
103 struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
104 u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
105 deb_info("dibusb-device is getting up.\n");
106
107 switch (dib->dibdev->dev_cl->id) {
108 case DTT200U:
109 break;
110 default:
111 dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
112 break;
113 }
114
115 if (dib->fe_init)
116 return dib->fe_init(fe);
117
118 return 0;
119}
120
121int dibusb_hw_sleep(struct dvb_frontend *fe)
122{
123 struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
124 u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
125 deb_info("dibusb-device is going to bed.\n");
126 /* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */
127 switch (dib->dibdev->dev_cl->id) {
128 case DIBUSB1_1:
129 case NOVAT_USB2:
130 case DTT200U:
131 break;
132 default:
133 dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
134 break;
135 }
136 if (dib->fe_sleep)
137 return dib->fe_sleep(fe);
138
139 return 0;
140}
141
142int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode)
143{
144 u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode };
145 return dibusb_readwrite_usb(dib,b,2,NULL,0);
146}
147
148static int dibusb_urb_kill(struct usb_dibusb *dib)
149{
150 int i;
151deb_info("trying to kill urbs\n");
152 if (dib->init_state & DIBUSB_STATE_URB_SUBMIT) {
153 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
154 deb_info("killing URB no. %d.\n",i);
155
156 /* stop the URB */
157 usb_kill_urb(dib->urb_list[i]);
158 }
159 } else
160 deb_info(" URBs not killed.\n");
161 dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT;
162 return 0;
163}
164
165static int dibusb_urb_submit(struct usb_dibusb *dib)
166{
167 int i,ret;
168 if (dib->init_state & DIBUSB_STATE_URB_INIT) {
169 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
170 deb_info("submitting URB no. %d\n",i);
171 if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
172 err("could not submit buffer urb no. %d - get them all back\n",i);
173 dibusb_urb_kill(dib);
174 return ret;
175 }
176 dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
177 }
178 }
179 return 0;
180}
181
182int dibusb_streaming(struct usb_dibusb *dib,int onoff)
183{
184 if (onoff)
185 dibusb_urb_submit(dib);
186 else
187 dibusb_urb_kill(dib);
188
189 switch (dib->dibdev->dev_cl->id) {
190 case DIBUSB2_0:
191 case DIBUSB2_0B:
192 case NOVAT_USB2:
193 case UMT2_0:
194 if (onoff)
195 return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
196 else
197 return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0);
198 break;
199 default:
200 break;
201 }
202 return 0;
203}
204
205int dibusb_urb_init(struct usb_dibusb *dib)
206{
207 int i,bufsize,def_pid_parse = 1;
208
209 /*
210 * when reloading the driver w/o replugging the device
211 * a timeout occures, this helps
212 */
213 usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
214 usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
215 usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data));
216
217 /* allocate the array for the data transfer URBs */
218 dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL);
219 if (dib->urb_list == NULL)
220 return -ENOMEM;
221 memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *));
222
223 dib->init_state |= DIBUSB_STATE_URB_LIST;
224
225 bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size;
226 deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
227 /* allocate the actual buffer for the URBs */
228 if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
229 deb_info("not enough memory.\n");
230 return -ENOMEM;
231 }
232 deb_info("allocation complete\n");
233 memset(dib->buffer,0,bufsize);
234
235 dib->init_state |= DIBUSB_STATE_URB_BUF;
236
237 /* allocate and submit the URBs */
238 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
239 if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
240 return -ENOMEM;
241 }
242
243 usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
244 usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data),
245 &dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size],
246 dib->dibdev->dev_cl->urb_buffer_size,
247 dibusb_urb_complete, dib);
248
249 dib->urb_list[i]->transfer_flags = 0;
250
251 dib->init_state |= DIBUSB_STATE_URB_INIT;
252 }
253
254 /* dib->pid_parse here contains the value of the module parameter */
255 /* decide if pid parsing can be deactivated:
256 * is possible (by device type) and wanted (by user)
257 */
258 switch (dib->dibdev->dev_cl->id) {
259 case DIBUSB2_0:
260 case DIBUSB2_0B:
261 if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) {
262 def_pid_parse = 0;
263 info("running at HIGH speed, will deliver the complete TS.");
264 } else
265 info("will use pid_parsing.");
266 break;
267 default:
268 break;
269 }
270 /* from here on it contains the device and user decision */
271 dib->pid_parse = def_pid_parse;
272
273 return 0;
274}
275
276int dibusb_urb_exit(struct usb_dibusb *dib)
277{
278 int i;
279
280 dibusb_urb_kill(dib);
281
282 if (dib->init_state & DIBUSB_STATE_URB_LIST) {
283 for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
284 if (dib->urb_list[i] != NULL) {
285 deb_info("freeing URB no. %d.\n",i);
286 /* free the URBs */
287 usb_free_urb(dib->urb_list[i]);
288 }
289 }
290 /* free the urb array */
291 kfree(dib->urb_list);
292 dib->init_state &= ~DIBUSB_STATE_URB_LIST;
293 }
294
295 if (dib->init_state & DIBUSB_STATE_URB_BUF)
296 pci_free_consistent(NULL,
297 dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count,
298 dib->buffer,dib->dma_handle);
299
300 dib->init_state &= ~DIBUSB_STATE_URB_BUF;
301 dib->init_state &= ~DIBUSB_STATE_URB_INIT;
302 return 0;
303}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h
deleted file mode 100644
index c965b64fb1ab..000000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb.h
+++ /dev/null
@@ -1,327 +0,0 @@
1/*
2 * dvb-dibusb.h
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dvb-dibusb-core.c .
11 */
12#ifndef __DVB_DIBUSB_H__
13#define __DVB_DIBUSB_H__
14
15#include <linux/input.h>
16#include <linux/config.h>
17#include <linux/usb.h>
18
19#include "dvb_frontend.h"
20#include "dvb_demux.h"
21#include "dvb_net.h"
22#include "dmxdev.h"
23
24#include "dib3000.h"
25#include "mt352.h"
26
27/* debug */
28#ifdef CONFIG_DVB_DIBCOM_DEBUG
29#define dprintk(level,args...) \
30 do { if ((dvb_dibusb_debug & level)) { printk(args); } } while (0)
31
32#define debug_dump(b,l) {\
33 int i; \
34 for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
35 deb_xfer("\n");\
36}
37
38#else
39#define dprintk(args...)
40#define debug_dump(b,l)
41#endif
42
43extern int dvb_dibusb_debug;
44
45/* Version information */
46#define DRIVER_VERSION "0.3"
47#define DRIVER_DESC "DiBcom based USB Budget DVB-T device"
48#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
49
50#define deb_info(args...) dprintk(0x01,args)
51#define deb_xfer(args...) dprintk(0x02,args)
52#define deb_alot(args...) dprintk(0x04,args)
53#define deb_ts(args...) dprintk(0x08,args)
54#define deb_err(args...) dprintk(0x10,args)
55#define deb_rc(args...) dprintk(0x20,args)
56
57/* generic log methods - taken from usb.h */
58#undef err
59#define err(format, arg...) printk(KERN_ERR "dvb-dibusb: " format "\n" , ## arg)
60#undef info
61#define info(format, arg...) printk(KERN_INFO "dvb-dibusb: " format "\n" , ## arg)
62#undef warn
63#define warn(format, arg...) printk(KERN_WARNING "dvb-dibusb: " format "\n" , ## arg)
64
65struct dibusb_usb_controller {
66 const char *name; /* name of the usb controller */
67 u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
68};
69
70typedef enum {
71 DIBUSB1_1 = 0,
72 DIBUSB1_1_AN2235,
73 DIBUSB2_0,
74 UMT2_0,
75 DIBUSB2_0B,
76 NOVAT_USB2,
77 DTT200U,
78} dibusb_class_t;
79
80typedef enum {
81 DIBUSB_TUNER_CABLE_THOMSON = 0,
82 DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
83 DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
84 DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
85} dibusb_tuner_t;
86
87typedef enum {
88 DIBUSB_DIB3000MB = 0,
89 DIBUSB_DIB3000MC,
90 DIBUSB_MT352,
91 DTT200U_FE,
92} dibusb_demodulator_t;
93
94typedef enum {
95 DIBUSB_RC_NO = 0,
96 DIBUSB_RC_NEC_PROTOCOL,
97 DIBUSB_RC_HAUPPAUGE_PROTO,
98} dibusb_remote_t;
99
100struct dibusb_tuner {
101 dibusb_tuner_t id;
102
103 u8 pll_addr; /* tuner i2c address */
104};
105extern struct dibusb_tuner dibusb_tuner[];
106
107#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4
108struct dibusb_demod {
109 dibusb_demodulator_t id;
110
111 int pid_filter_count; /* counter of the internal pid_filter */
112 u8 i2c_addrs[DIBUSB_POSSIBLE_I2C_ADDR_NUM]; /* list of possible i2c addresses of the demod */
113};
114
115#define DIBUSB_MAX_TUNER_NUM 2
116struct dibusb_device_class {
117 dibusb_class_t id;
118
119 const struct dibusb_usb_controller *usb_ctrl; /* usb controller */
120 const char *firmware; /* valid firmware filenames */
121
122 int pipe_cmd; /* command pipe (read/write) */
123 int pipe_data; /* data pipe */
124
125 int urb_count; /* number of data URBs to be submitted */
126 int urb_buffer_size; /* the size of the buffer for each URB */
127
128 dibusb_remote_t remote_type; /* does this device have a ir-receiver */
129
130 struct dibusb_demod *demod; /* which demodulator is mount */
131 struct dibusb_tuner *tuner; /* which tuner can be found here */
132};
133
134#define DIBUSB_ID_MAX_NUM 15
135struct dibusb_usb_device {
136 const char *name; /* real name of the box */
137 struct dibusb_device_class *dev_cl; /* which dibusb_device_class is this device part of */
138
139 struct usb_device_id *cold_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at pre firmware state */
140 struct usb_device_id *warm_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at post firmware state */
141};
142
143/* a PID for the pid_filter list, when in use */
144struct dibusb_pid
145{
146 int index;
147 u16 pid;
148 int active;
149};
150
151struct usb_dibusb {
152 /* usb */
153 struct usb_device * udev;
154
155 struct dibusb_usb_device * dibdev;
156
157#define DIBUSB_STATE_INIT 0x000
158#define DIBUSB_STATE_URB_LIST 0x001
159#define DIBUSB_STATE_URB_BUF 0x002
160#define DIBUSB_STATE_URB_INIT 0x004
161#define DIBUSB_STATE_DVB 0x008
162#define DIBUSB_STATE_I2C 0x010
163#define DIBUSB_STATE_REMOTE 0x020
164#define DIBUSB_STATE_URB_SUBMIT 0x040
165 int init_state;
166
167 int feedcount;
168 struct dib_fe_xfer_ops xfer_ops;
169
170 struct dibusb_tuner *tuner;
171
172 struct urb **urb_list;
173 u8 *buffer;
174 dma_addr_t dma_handle;
175
176 /* I2C */
177 struct i2c_adapter i2c_adap;
178
179 /* locking */
180 struct semaphore usb_sem;
181 struct semaphore i2c_sem;
182
183 /* dvb */
184 struct dvb_adapter adapter;
185 struct dmxdev dmxdev;
186 struct dvb_demux demux;
187 struct dvb_net dvb_net;
188 struct dvb_frontend* fe;
189
190 int (*fe_sleep) (struct dvb_frontend *);
191 int (*fe_init) (struct dvb_frontend *);
192
193 /* remote control */
194 struct input_dev rc_input_dev;
195 struct work_struct rc_query_work;
196 int last_event;
197 int last_state; /* for Hauppauge RC protocol */
198 int repeat_key_count;
199 int rc_key_repeat_count; /* module parameter */
200
201 /* module parameters */
202 int pid_parse;
203 int rc_query_interval;
204};
205
206/* commonly used functions in the separated files */
207
208/* dvb-dibusb-firmware.c */
209int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev);
210
211/* dvb-dibusb-remote.c */
212int dibusb_remote_exit(struct usb_dibusb *dib);
213int dibusb_remote_init(struct usb_dibusb *dib);
214
215/* dvb-dibusb-fe-i2c.c */
216int dibusb_fe_init(struct usb_dibusb* dib);
217int dibusb_fe_exit(struct usb_dibusb *dib);
218int dibusb_i2c_init(struct usb_dibusb *dib);
219int dibusb_i2c_exit(struct usb_dibusb *dib);
220
221/* dvb-dibusb-dvb.c */
222void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs);
223int dibusb_dvb_init(struct usb_dibusb *dib);
224int dibusb_dvb_exit(struct usb_dibusb *dib);
225
226/* dvb-dibusb-usb.c */
227int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
228 u16 rlen);
229int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len);
230
231int dibusb_hw_wakeup(struct dvb_frontend *);
232int dibusb_hw_sleep(struct dvb_frontend *);
233int dibusb_set_streaming_mode(struct usb_dibusb *,u8);
234int dibusb_streaming(struct usb_dibusb *,int);
235
236int dibusb_urb_init(struct usb_dibusb *);
237int dibusb_urb_exit(struct usb_dibusb *);
238
239/* dvb-fe-dtt200u.c */
240struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *,struct dib_fe_xfer_ops *);
241
242/* i2c and transfer stuff */
243#define DIBUSB_I2C_TIMEOUT 5000
244
245/*
246 * protocol of all dibusb related devices
247 */
248
249/*
250 * bulk msg to/from endpoint 0x01
251 *
252 * general structure:
253 * request_byte parameter_bytes
254 */
255
256#define DIBUSB_REQ_START_READ 0x00
257#define DIBUSB_REQ_START_DEMOD 0x01
258
259/*
260 * i2c read
261 * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
262 * bulk read: byte_buffer (length_word bytes)
263 */
264#define DIBUSB_REQ_I2C_READ 0x02
265
266/*
267 * i2c write
268 * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
269 */
270#define DIBUSB_REQ_I2C_WRITE 0x03
271
272/*
273 * polling the value of the remote control
274 * bulk write: 0x04
275 * bulk read: byte_buffer (5 bytes)
276 *
277 * first byte of byte_buffer shows the status (0x00, 0x01, 0x02)
278 */
279#define DIBUSB_REQ_POLL_REMOTE 0x04
280
281#define DIBUSB_RC_NEC_EMPTY 0x00
282#define DIBUSB_RC_NEC_KEY_PRESSED 0x01
283#define DIBUSB_RC_NEC_KEY_REPEATED 0x02
284
285/* additional status values for Hauppauge Remote Control Protocol */
286#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
287#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
288
289/* streaming mode:
290 * bulk write: 0x05 mode_byte
291 *
292 * mode_byte is mostly 0x00
293 */
294#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
295
296/* interrupt the internal read loop, when blocking */
297#define DIBUSB_REQ_INTR_READ 0x06
298
299/* io control
300 * 0x07 cmd_byte param_bytes
301 *
302 * param_bytes can be up to 32 bytes
303 *
304 * cmd_byte function parameter name
305 * 0x00 power mode
306 * 0x00 sleep
307 * 0x01 wakeup
308 *
309 * 0x01 enable streaming
310 * 0x02 disable streaming
311 *
312 *
313 */
314#define DIBUSB_REQ_SET_IOCTL 0x07
315
316/* IOCTL commands */
317
318/* change the power mode in firmware */
319#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
320#define DIBUSB_IOCTL_POWER_SLEEP 0x00
321#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
322
323/* modify streaming of the FX2 */
324#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
325#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
326
327#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index d19301d90a09..d6b7a9de471e 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -35,6 +35,7 @@
35#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
36#include <linux/list.h> 36#include <linux/list.h>
37#include <linux/suspend.h> 37#include <linux/suspend.h>
38#include <linux/jiffies.h>
38#include <asm/processor.h> 39#include <asm/processor.h>
39#include <asm/semaphore.h> 40#include <asm/semaphore.h>
40 41
@@ -327,7 +328,8 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
327 return 1; 328 return 1;
328 329
329 if (fepriv->dvbdev->writers == 1) 330 if (fepriv->dvbdev->writers == 1)
330 if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ) 331 if (time_after(jiffies, fepriv->release_jiffies +
332 dvb_shutdown_timeout * HZ))
331 return 1; 333 return 1;
332 334
333 return 0; 335 return 0;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
new file mode 100644
index 000000000000..8aa32f6e447b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -0,0 +1,99 @@
1config DVB_USB
2 tristate "Support for various USB DVB devices"
3 depends on DVB_CORE && USB
4 select FW_LOADER
5 help
6 By enabling this you will be able to choose the various USB 1.1 and
7 USB2.0 DVB devices.
8
9 Almost every USB device needs a firmware, please look into
10 <file:Documentation/dvb/README.dvb-usb>
11
12 Say Y if you own an USB DVB device.
13
14config DVB_USB_DEBUG
15 bool "Enable extended debug support for all DVB-USB devices"
16 depends on DVB_USB
17 help
18 Say Y if you want to enable debuging. See modinfo dvb-usb (and the
19 appropriate drivers) for debug levels.
20
21config DVB_USB_A800
22 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
23 depends on DVB_USB
24 help
25 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
26
27config DVB_USB_DIBUSB_MB
28 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
29 depends on DVB_USB
30 help
31 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
32 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
33
34 Devices supported by this driver:
35 TwinhanDTV USB-Ter (VP7041)
36 TwinhanDTV Magic Box (VP7041e)
37 KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
38 Hama DVB-T USB1.1-Box
39 DiBcom USB1.1 reference devices (non-public)
40 Ultima Electronic/Artec T1 USB TVBOX
41 Compro Videomate DVB-U2000 - DVB-T USB
42 Grandtec DVB-T USB
43 Avermedia AverTV DVBT USB1.1
44 Artec T1 USB1.1 boxes
45
46 The VP7041 seems to be identical to "CTS Portable" (Chinese
47 Television System).
48
49 Say Y if you own such a device and want to use it. You should build it as
50 a module.
51
52config DVB_USB_DIBUSB_MC
53 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
54 depends on DVB_USB
55 help
56 Support for 2.0 DVB-T receivers based on reference designs made by
57 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
58
59 Devices supported by this driver:
60 DiBcom USB2.0 reference devices (non-public)
61 Artec T1 USB2.0 boxes
62
63 Say Y if you own such a device and want to use it. You should build it as
64 a module.
65
66config DVB_USB_UMT_010
67 tristate "HanfTek UMT-010 DVB-T USB2.0 support"
68 depends on DVB_USB
69 help
70 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
71
72config DVB_USB_DIGITV
73 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
74 depends on DVB_USB
75 help
76 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
77
78config DVB_USB_VP7045
79 tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support"
80 depends on DVB_USB
81 help
82 Say Y here to support the
83 TwinhanDTV Alpha (stick) (VP-7045),
84 TwinhanDTV MagicBox II (VP-7046) and
85 DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers.
86
87config DVB_USB_NOVA_T_USB2
88 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
89 depends on DVB_USB
90 help
91 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
92
93config DVB_USB_DTT200U
94 tristate "Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support"
95 depends on DVB_USB
96 help
97 Say Y here to support the Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
98
99 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
new file mode 100644
index 000000000000..d65b50f9abb0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -0,0 +1,30 @@
1dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
2obj-$(CONFIG_DVB_USB) += dvb-usb.o
3
4dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
5obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
6
7dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
8obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
9
10dvb-usb-dibusb-common-objs = dibusb-common.o
11
12dvb-usb-a800-objs = a800.o
13obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
14
15dvb-usb-dibusb-mb-objs = dibusb-mb.o
16obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
17
18dvb-usb-dibusb-mc-objs = dibusb-mc.o
19obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
20
21dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
22obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
23
24dvb-usb-umt-010-objs = umt-010.o
25obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
26
27dvb-usb-digitv-objs = digitv.o
28obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
29
30EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
new file mode 100644
index 000000000000..a3542935604f
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -0,0 +1,176 @@
1/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
2 * USB2.0 (A800) DVB-T receiver.
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to
7 * - AVerMedia who kindly provided information and
8 * - Glen Harris who suffered from my mistakes during development.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
16#include "dibusb.h"
17
18static int debug;
19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
21#define deb_rc(args...) dprintk(debug,0x01,args)
22
23static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
24{
25 /* do nothing for the AVerMedia */
26 return 0;
27}
28
29static struct dvb_usb_rc_key a800_rc_keys[] = {
30 { 0x02, 0x01, KEY_PROG1 }, /* SOURCE */
31 { 0x02, 0x00, KEY_POWER }, /* POWER */
32 { 0x02, 0x05, KEY_1 }, /* 1 */
33 { 0x02, 0x06, KEY_2 }, /* 2 */
34 { 0x02, 0x07, KEY_3 }, /* 3 */
35 { 0x02, 0x09, KEY_4 }, /* 4 */
36 { 0x02, 0x0a, KEY_5 }, /* 5 */
37 { 0x02, 0x0b, KEY_6 }, /* 6 */
38 { 0x02, 0x0d, KEY_7 }, /* 7 */
39 { 0x02, 0x0e, KEY_8 }, /* 8 */
40 { 0x02, 0x0f, KEY_9 }, /* 9 */
41 { 0x02, 0x12, KEY_LEFT }, /* L / DISPLAY */
42 { 0x02, 0x11, KEY_0 }, /* 0 */
43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
46 { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
47 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
48 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
49 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
50 { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
51 { 0x02, 0x14, KEY_MUTE }, /* MUTE */
52 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
53 { 0x02, 0x19, KEY_RECORD }, /* RECORD */
54 { 0x02, 0x18, KEY_PLAY }, /* PLAY */
55 { 0x02, 0x1b, KEY_STOP }, /* STOP */
56 { 0x02, 0x1a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
57 { 0x02, 0x1d, KEY_BACK }, /* << / RED */
58 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
59 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
60 { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
62 { 0x02, 0x04, KEY_EPG }, /* EPG */
63 { 0x02, 0x15, KEY_MENU }, /* MENU */
64};
65
66int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
67{
68 u8 key[5];
69 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
70 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
71 2*HZ) != 5)
72 return -ENODEV;
73
74 /* call the universal NEC remote processor, to find out the key's state and event */
75 dvb_usb_nec_rc_key_to_event(d,key,event,state);
76 if (key[0] != 0)
77 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
78 return 0;
79}
80
81/* USB Driver stuff */
82static struct dvb_usb_properties a800_properties;
83
84static int a800_probe(struct usb_interface *intf,
85 const struct usb_device_id *id)
86{
87 return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE);
88}
89
90/* do not change the order of the ID table */
91static struct usb_device_id a800_table [] = {
92/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
93/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
94 { } /* Terminating entry */
95};
96MODULE_DEVICE_TABLE (usb, a800_table);
97
98static struct dvb_usb_properties a800_properties = {
99 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
100 .pid_filter_count = 32,
101
102 .usb_ctrl = CYPRESS_FX2,
103
104 .firmware = "dvb-usb-avertv-a800-02.fw",
105
106 .size_of_priv = sizeof(struct dibusb_state),
107
108 .streaming_ctrl = dibusb2_0_streaming_ctrl,
109 .pid_filter = dibusb_pid_filter,
110 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
111 .power_ctrl = a800_power_ctrl,
112 .frontend_attach = dibusb_dib3000mc_frontend_attach,
113 .tuner_attach = dibusb_dib3000mc_tuner_attach,
114
115 .rc_interval = DEFAULT_RC_INTERVAL,
116 .rc_key_map = a800_rc_keys,
117 .rc_key_map_size = ARRAY_SIZE(a800_rc_keys),
118 .rc_query = a800_rc_query,
119
120 .i2c_algo = &dibusb_i2c_algo,
121
122 .generic_bulk_ctrl_endpoint = 0x01,
123 /* parameter for the MPEG2-data transfer */
124 .urb = {
125 .type = DVB_USB_BULK,
126 .count = 7,
127 .endpoint = 0x06,
128 .u = {
129 .bulk = {
130 .buffersize = 4096,
131 }
132 }
133 },
134
135 .num_device_descs = 1,
136 .devices = {
137 { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
138 { &a800_table[0], NULL },
139 { &a800_table[1], NULL },
140 },
141 }
142};
143
144static struct usb_driver a800_driver = {
145 .owner = THIS_MODULE,
146 .name = "AVerMedia AverTV DVB-T USB 2.0 (A800)",
147 .probe = a800_probe,
148 .disconnect = dvb_usb_device_exit,
149 .id_table = a800_table,
150};
151
152/* module stuff */
153static int __init a800_module_init(void)
154{
155 int result;
156 if ((result = usb_register(&a800_driver))) {
157 err("usb_register failed. Error number %d",result);
158 return result;
159 }
160
161 return 0;
162}
163
164static void __exit a800_module_exit(void)
165{
166 /* deregister this driver from the USB subsystem */
167 usb_deregister(&a800_driver);
168}
169
170module_init (a800_module_init);
171module_exit (a800_module_exit);
172
173MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
174MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
175MODULE_VERSION("1.0");
176MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
new file mode 100644
index 000000000000..63b626f70c81
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -0,0 +1,272 @@
1/* Common methods for dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#include "dibusb.h"
12
13static int debug;
14module_param(debug, int, 0644);
15MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
16MODULE_LICENSE("GPL");
17
18#define deb_info(args...) dprintk(debug,0x01,args)
19
20/* common stuff used by the different dibusb modules */
21int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
22{
23 if (d->priv != NULL) {
24 struct dib_fe_xfer_ops *ops = d->priv;
25 if (ops->fifo_ctrl != NULL)
26 if (ops->fifo_ctrl(d->fe,onoff)) {
27 err("error while controlling the fifo of the demod.");
28 return -ENODEV;
29 }
30 }
31 return 0;
32}
33EXPORT_SYMBOL(dibusb_streaming_ctrl);
34
35int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
36{
37 if (d->priv != NULL) {
38 struct dib_fe_xfer_ops *ops = d->priv;
39 if (d->pid_filtering && ops->pid_ctrl != NULL)
40 ops->pid_ctrl(d->fe,index,pid,onoff);
41 }
42 return 0;
43}
44EXPORT_SYMBOL(dibusb_pid_filter);
45
46int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
47{
48 if (d->priv != NULL) {
49 struct dib_fe_xfer_ops *ops = d->priv;
50 if (ops->pid_parse != NULL)
51 if (ops->pid_parse(d->fe,onoff) < 0)
52 err("could not handle pid_parser");
53 }
54 return 0;
55}
56EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
57
58int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
59{
60 u8 b[3];
61 int ret;
62 b[0] = DIBUSB_REQ_SET_IOCTL;
63 b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
64 b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
65 ret = dvb_usb_generic_write(d,b,3);
66 msleep(10);
67 return ret;
68}
69EXPORT_SYMBOL(dibusb_power_ctrl);
70
71int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
72{
73 u8 b[2];
74 b[0] = DIBUSB_REQ_SET_IOCTL;
75 b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
76
77 dvb_usb_generic_write(d,b,3);
78
79 return dibusb_streaming_ctrl(d,onoff);
80}
81EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
82
83int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
84{
85 if (onoff) {
86 u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
87 return dvb_usb_generic_write(d,b,3);
88 } else
89 return 0;
90}
91EXPORT_SYMBOL(dibusb2_0_power_ctrl);
92
93static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
94 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
95{
96 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
97 /* write only ? */
98 int wo = (rbuf == NULL || rlen == 0),
99 len = 2 + wlen + (wo ? 0 : 2);
100
101 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
102 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
103
104 memcpy(&sndbuf[2],wbuf,wlen);
105
106 if (!wo) {
107 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
108 sndbuf[wlen+3] = rlen & 0xff;
109 }
110
111 return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
112}
113
114/*
115 * I2C master xfer function
116 */
117static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
118{
119 struct dvb_usb_device *d = i2c_get_adapdata(adap);
120 int i;
121
122 if (down_interruptible(&d->i2c_sem) < 0)
123 return -EAGAIN;
124
125 if (num > 2)
126 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
127
128 for (i = 0; i < num; i++) {
129 /* write/read request */
130 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
131 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
132 msg[i+1].buf,msg[i+1].len) < 0)
133 break;
134 i++;
135 } else
136 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
137 break;
138 }
139
140 up(&d->i2c_sem);
141 return i;
142}
143
144static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
145{
146 return I2C_FUNC_I2C;
147}
148
149struct i2c_algorithm dibusb_i2c_algo = {
150 .name = "DiBcom USB I2C algorithm",
151 .id = I2C_ALGO_BIT,
152 .master_xfer = dibusb_i2c_xfer,
153 .functionality = dibusb_i2c_func,
154};
155EXPORT_SYMBOL(dibusb_i2c_algo);
156
157int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
158{
159 u8 wbuf[1] = { offs };
160 return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
161}
162EXPORT_SYMBOL(dibusb_read_eeprom_byte);
163
164int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
165{
166 struct dib3000_config demod_cfg;
167 struct dibusb_state *st = d->priv;
168
169 demod_cfg.pll_set = dvb_usb_pll_set_i2c;
170 demod_cfg.pll_init = dvb_usb_pll_init_i2c;
171
172 for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
173 if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) {
174 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
175 return 0;
176 }
177
178 return -ENODEV;
179}
180EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
181
182int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
183{
184 d->pll_addr = 0x60;
185 d->pll_desc = &dvb_pll_env57h1xd5;
186 return 0;
187}
188EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
189
190/*
191 * common remote control stuff
192 */
193struct dvb_usb_rc_key dibusb_rc_keys[] = {
194 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
195 { 0x00, 0x16, KEY_POWER },
196 { 0x00, 0x10, KEY_MUTE },
197 { 0x00, 0x03, KEY_1 },
198 { 0x00, 0x01, KEY_2 },
199 { 0x00, 0x06, KEY_3 },
200 { 0x00, 0x09, KEY_4 },
201 { 0x00, 0x1d, KEY_5 },
202 { 0x00, 0x1f, KEY_6 },
203 { 0x00, 0x0d, KEY_7 },
204 { 0x00, 0x19, KEY_8 },
205 { 0x00, 0x1b, KEY_9 },
206 { 0x00, 0x15, KEY_0 },
207 { 0x00, 0x05, KEY_CHANNELUP },
208 { 0x00, 0x02, KEY_CHANNELDOWN },
209 { 0x00, 0x1e, KEY_VOLUMEUP },
210 { 0x00, 0x0a, KEY_VOLUMEDOWN },
211 { 0x00, 0x11, KEY_RECORD },
212 { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
213 { 0x00, 0x14, KEY_PLAY },
214 { 0x00, 0x1a, KEY_STOP },
215 { 0x00, 0x40, KEY_REWIND },
216 { 0x00, 0x12, KEY_FASTFORWARD },
217 { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
218 { 0x00, 0x4c, KEY_PAUSE },
219 { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
220 { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
221 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
222 { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
223 { 0x00, 0x1c, KEY_EPG }, /* EPG */
224 { 0x00, 0x00, KEY_TAB }, /* Tab */
225 { 0x00, 0x48, KEY_INFO }, /* Preview */
226 { 0x00, 0x04, KEY_LIST }, /* RecordList */
227 { 0x00, 0x0f, KEY_TEXT }, /* Teletext */
228 /* Key codes for the KWorld/ADSTech/JetWay remote. */
229 { 0x86, 0x12, KEY_POWER },
230 { 0x86, 0x0f, KEY_SELECT }, /* source */
231 { 0x86, 0x0c, KEY_UNKNOWN }, /* scan */
232 { 0x86, 0x0b, KEY_EPG },
233 { 0x86, 0x10, KEY_MUTE },
234 { 0x86, 0x01, KEY_1 },
235 { 0x86, 0x02, KEY_2 },
236 { 0x86, 0x03, KEY_3 },
237 { 0x86, 0x04, KEY_4 },
238 { 0x86, 0x05, KEY_5 },
239 { 0x86, 0x06, KEY_6 },
240 { 0x86, 0x07, KEY_7 },
241 { 0x86, 0x08, KEY_8 },
242 { 0x86, 0x09, KEY_9 },
243 { 0x86, 0x0a, KEY_0 },
244 { 0x86, 0x18, KEY_ZOOM },
245 { 0x86, 0x1c, KEY_UNKNOWN }, /* preview */
246 { 0x86, 0x13, KEY_UNKNOWN }, /* snap */
247 { 0x86, 0x00, KEY_UNDO },
248 { 0x86, 0x1d, KEY_RECORD },
249 { 0x86, 0x0d, KEY_STOP },
250 { 0x86, 0x0e, KEY_PAUSE },
251 { 0x86, 0x16, KEY_PLAY },
252 { 0x86, 0x11, KEY_BACK },
253 { 0x86, 0x19, KEY_FORWARD },
254 { 0x86, 0x14, KEY_UNKNOWN }, /* pip */
255 { 0x86, 0x15, KEY_ESC },
256 { 0x86, 0x1a, KEY_UP },
257 { 0x86, 0x1e, KEY_DOWN },
258 { 0x86, 0x1f, KEY_LEFT },
259 { 0x86, 0x1b, KEY_RIGHT },
260};
261EXPORT_SYMBOL(dibusb_rc_keys);
262
263int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
264{
265 u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
266 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
267 dvb_usb_nec_rc_key_to_event(d,key,event,state);
268 if (key[0] != 0)
269 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
270 return 0;
271}
272EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
new file mode 100644
index 000000000000..a0ffbb59fa14
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -0,0 +1,316 @@
1/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
2 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * based on GPL code from DiBcom, which has
7 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "dibusb.h"
16
17static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
18{
19 struct dib3000_config demod_cfg;
20 struct dibusb_state *st = d->priv;
21
22 demod_cfg.demod_address = 0x8;
23 demod_cfg.pll_set = dvb_usb_pll_set_i2c;
24 demod_cfg.pll_init = dvb_usb_pll_init_i2c;
25
26 if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
27 return -ENODEV;
28
29 d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
30
31 return 0;
32}
33
34/* some of the dibusb 1.1 device aren't equipped with the default tuner
35 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
36 * this out. */
37static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d)
38{
39 u8 b[2] = { 0,0 }, b2[1];
40 int ret = 0;
41 struct i2c_msg msg[2] = {
42 { .flags = 0, .buf = b, .len = 2 },
43 { .flags = I2C_M_RD, .buf = b2, .len = 1 },
44 };
45
46 /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
47 msg[0].addr = msg[1].addr = 0x60;
48
49 if (d->tuner_pass_ctrl)
50 d->tuner_pass_ctrl(d->fe,1,msg[0].addr);
51
52 if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) {
53 err("tuner i2c write failed.");
54 ret = -EREMOTEIO;
55 }
56
57 if (d->tuner_pass_ctrl)
58 d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
59
60 if (b2[0] == 0xfe) {
61 info("this device has the Thomson Cable onboard. Which is default.");
62 d->pll_addr = 0x61;
63 d->pll_desc = &dvb_pll_tua6010xs;
64 } else {
65 u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
66 info("this device has the Panasonic ENV77H11D5 onboard.");
67 d->pll_addr = 0x60;
68 memcpy(d->pll_init,bpll,4);
69 d->pll_desc = &dvb_pll_tda665x;
70 }
71
72 return ret;
73}
74
75/* USB Driver stuff */
76static struct dvb_usb_properties dibusb1_1_properties;
77static struct dvb_usb_properties dibusb1_1_an2235_properties;
78static struct dvb_usb_properties dibusb2_0b_properties;
79
80static int dibusb_probe(struct usb_interface *intf,
81 const struct usb_device_id *id)
82{
83 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 ||
84 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 ||
85 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0)
86 return 0;
87
88 return -EINVAL;
89}
90
91/* do not change the order of the ID table */
92static struct usb_device_id dibusb_dib3000mb_table [] = {
93/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
94/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
95/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
96/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
97/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
98/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
99/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
100/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
101/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
102/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
103/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
104/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
105/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
106/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
107/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
108/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) },
109/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) },
110/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
111/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
112/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
113/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
114/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
115/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
116/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
117/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
118 { } /* Terminating entry */
119};
120MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
121
122static struct dvb_usb_properties dibusb1_1_properties = {
123 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
124 .pid_filter_count = 16,
125
126 .usb_ctrl = CYPRESS_AN2135,
127
128 .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
129
130 .size_of_priv = sizeof(struct dibusb_state),
131
132 .streaming_ctrl = dibusb_streaming_ctrl,
133 .pid_filter = dibusb_pid_filter,
134 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
135 .power_ctrl = dibusb_power_ctrl,
136 .frontend_attach = dibusb_dib3000mb_frontend_attach,
137 .tuner_attach = dibusb_dib3000mb_tuner_attach,
138
139 .rc_interval = DEFAULT_RC_INTERVAL,
140 .rc_key_map = dibusb_rc_keys,
141 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
142 .rc_query = dibusb_rc_query,
143
144 .i2c_algo = &dibusb_i2c_algo,
145
146 .generic_bulk_ctrl_endpoint = 0x01,
147 /* parameter for the MPEG2-data transfer */
148 .urb = {
149 .type = DVB_USB_BULK,
150 .count = 7,
151 .endpoint = 0x02,
152 .u = {
153 .bulk = {
154 .buffersize = 4096,
155 }
156 }
157 },
158
159 .num_device_descs = 8,
160 .devices = {
161 { "AVerMedia AverTV DVBT USB1.1",
162 { &dibusb_dib3000mb_table[0], NULL },
163 { &dibusb_dib3000mb_table[1], NULL },
164 },
165 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
166 { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
167 { &dibusb_dib3000mb_table[3], NULL },
168 },
169 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
170 { &dibusb_dib3000mb_table[5], NULL },
171 { &dibusb_dib3000mb_table[6], NULL },
172 },
173 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
174 { &dibusb_dib3000mb_table[7], NULL },
175 { &dibusb_dib3000mb_table[8], NULL },
176 },
177 { "Grandtec USB1.1 DVB-T",
178 { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL },
179 { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
180 },
181 { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
182 { &dibusb_dib3000mb_table[13], NULL },
183 { &dibusb_dib3000mb_table[14], NULL },
184 },
185 { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
186 { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
187 { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
188 },
189 { "Artec T1 USB1.1 TVBOX with AN2135",
190 { &dibusb_dib3000mb_table[19], NULL },
191 { &dibusb_dib3000mb_table[20], NULL },
192 },
193 }
194};
195
196static struct dvb_usb_properties dibusb1_1_an2235_properties = {
197 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
198 .usb_ctrl = CYPRESS_AN2235,
199
200 .firmware = "dvb-usb-dibusb-an2235-01.fw",
201
202 .size_of_priv = sizeof(struct dibusb_state),
203
204 .streaming_ctrl = dibusb_streaming_ctrl,
205 .pid_filter = dibusb_pid_filter,
206 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
207 .power_ctrl = dibusb_power_ctrl,
208 .frontend_attach = dibusb_dib3000mb_frontend_attach,
209 .tuner_attach = dibusb_dib3000mb_tuner_attach,
210
211 .rc_interval = DEFAULT_RC_INTERVAL,
212 .rc_key_map = dibusb_rc_keys,
213 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
214 .rc_query = dibusb_rc_query,
215
216 .i2c_algo = &dibusb_i2c_algo,
217
218 .generic_bulk_ctrl_endpoint = 0x01,
219 /* parameter for the MPEG2-data transfer */
220 .urb = {
221 .type = DVB_USB_BULK,
222 .count = 7,
223 .endpoint = 0x02,
224 .u = {
225 .bulk = {
226 .buffersize = 4096,
227 }
228 }
229 },
230
231 .num_device_descs = 1,
232 .devices = {
233 { "Artec T1 USB1.1 TVBOX with AN2235",
234 { &dibusb_dib3000mb_table[20], NULL },
235 { &dibusb_dib3000mb_table[21], NULL },
236 },
237 }
238};
239
240static struct dvb_usb_properties dibusb2_0b_properties = {
241 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
242 .usb_ctrl = CYPRESS_FX2,
243
244 .firmware = "dvb-usb-adstech-usb2-01.fw",
245
246 .size_of_priv = sizeof(struct dibusb_state),
247
248 .streaming_ctrl = dibusb2_0_streaming_ctrl,
249 .pid_filter = dibusb_pid_filter,
250 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
251 .power_ctrl = dibusb2_0_power_ctrl,
252 .frontend_attach = dibusb_dib3000mb_frontend_attach,
253 .tuner_attach = dibusb_dib3000mb_tuner_attach,
254
255 .rc_interval = DEFAULT_RC_INTERVAL,
256 .rc_key_map = dibusb_rc_keys,
257 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
258 .rc_query = dibusb_rc_query,
259
260 .i2c_algo = &dibusb_i2c_algo,
261
262 .generic_bulk_ctrl_endpoint = 0x01,
263 /* parameter for the MPEG2-data transfer */
264 .urb = {
265 .type = DVB_USB_BULK,
266 .count = 7,
267 .endpoint = 0x06,
268 .u = {
269 .bulk = {
270 .buffersize = 4096,
271 }
272 }
273 },
274
275 .num_device_descs = 2,
276 .devices = {
277 { "KWorld/ADSTech Instant DVB-T USB 2.0",
278 { &dibusb_dib3000mb_table[23], NULL },
279 { &dibusb_dib3000mb_table[24], NULL }, /* device ID with default DIBUSB2_0-firmware */
280 },
281 }
282};
283
284static struct usb_driver dibusb_driver = {
285 .owner = THIS_MODULE,
286 .name = "DiBcom based USB DVB-T devices (DiB3000M-B based)",
287 .probe = dibusb_probe,
288 .disconnect = dvb_usb_device_exit,
289 .id_table = dibusb_dib3000mb_table,
290};
291
292/* module stuff */
293static int __init dibusb_module_init(void)
294{
295 int result;
296 if ((result = usb_register(&dibusb_driver))) {
297 err("usb_register failed. Error number %d",result);
298 return result;
299 }
300
301 return 0;
302}
303
304static void __exit dibusb_module_exit(void)
305{
306 /* deregister this driver from the USB subsystem */
307 usb_deregister(&dibusb_driver);
308}
309
310module_init (dibusb_module_init);
311module_exit (dibusb_module_exit);
312
313MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
314MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
315MODULE_VERSION("1.0");
316MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
new file mode 100644
index 000000000000..aad8ed3fe005
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -0,0 +1,116 @@
1/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
2 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * based on GPL code from DiBcom, which has
7 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "dibusb.h"
16
17/* USB Driver stuff */
18static struct dvb_usb_properties dibusb_mc_properties;
19
20static int dibusb_mc_probe(struct usb_interface *intf,
21 const struct usb_device_id *id)
22{
23 return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE);
24}
25
26/* do not change the order of the ID table */
27static struct usb_device_id dibusb_dib3000mc_table [] = {
28/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
29/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
30/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
31 { } /* Terminating entry */
32};
33MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
34
35static struct dvb_usb_properties dibusb_mc_properties = {
36 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
37 .pid_filter_count = 32,
38
39 .usb_ctrl = CYPRESS_FX2,
40 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
41
42 .size_of_priv = sizeof(struct dibusb_state),
43
44 .streaming_ctrl = dibusb2_0_streaming_ctrl,
45 .pid_filter = dibusb_pid_filter,
46 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
47 .power_ctrl = dibusb2_0_power_ctrl,
48 .frontend_attach = dibusb_dib3000mc_frontend_attach,
49 .tuner_attach = dibusb_dib3000mc_tuner_attach,
50
51 .rc_interval = DEFAULT_RC_INTERVAL,
52 .rc_key_map = dibusb_rc_keys,
53 .rc_key_map_size = 63, /* FIXME */
54 .rc_query = dibusb_rc_query,
55
56 .i2c_algo = &dibusb_i2c_algo,
57
58 .generic_bulk_ctrl_endpoint = 0x01,
59 /* parameter for the MPEG2-data transfer */
60 .urb = {
61 .type = DVB_USB_BULK,
62 .count = 7,
63 .endpoint = 0x06,
64 .u = {
65 .bulk = {
66 .buffersize = 4096,
67 }
68 }
69 },
70
71 .num_device_descs = 2,
72 .devices = {
73 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
74 { &dibusb_dib3000mc_table[0], NULL },
75 { &dibusb_dib3000mc_table[1], NULL },
76 },
77 { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
78 { &dibusb_dib3000mc_table[2], NULL },
79 { NULL },
80 },
81 }
82};
83
84static struct usb_driver dibusb_mc_driver = {
85 .owner = THIS_MODULE,
86 .name = "DiBcom based USB2.0 DVB-T (DiB3000M-C/P based) devices",
87 .probe = dibusb_mc_probe,
88 .disconnect = dvb_usb_device_exit,
89 .id_table = dibusb_dib3000mc_table,
90};
91
92/* module stuff */
93static int __init dibusb_mc_module_init(void)
94{
95 int result;
96 if ((result = usb_register(&dibusb_mc_driver))) {
97 err("usb_register failed. Error number %d",result);
98 return result;
99 }
100
101 return 0;
102}
103
104static void __exit dibusb_mc_module_exit(void)
105{
106 /* deregister this driver from the USB subsystem */
107 usb_deregister(&dibusb_mc_driver);
108}
109
110module_init (dibusb_mc_module_init);
111module_exit (dibusb_mc_module_exit);
112
113MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
114MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
115MODULE_VERSION("1.0");
116MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
new file mode 100644
index 000000000000..6611f62977c0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -0,0 +1,122 @@
1/* Header file for all dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_
13
14#define DVB_USB_LOG_PREFIX "dibusb"
15#include "dvb-usb.h"
16
17#include "dib3000.h"
18
19/*
20 * protocol of all dibusb related devices
21 */
22
23/*
24 * bulk msg to/from endpoint 0x01
25 *
26 * general structure:
27 * request_byte parameter_bytes
28 */
29
30#define DIBUSB_REQ_START_READ 0x00
31#define DIBUSB_REQ_START_DEMOD 0x01
32
33/*
34 * i2c read
35 * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
36 * bulk read: byte_buffer (length_word bytes)
37 */
38#define DIBUSB_REQ_I2C_READ 0x02
39
40/*
41 * i2c write
42 * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
43 */
44#define DIBUSB_REQ_I2C_WRITE 0x03
45
46/*
47 * polling the value of the remote control
48 * bulk write: 0x04
49 * bulk read: byte_buffer (5 bytes)
50 */
51#define DIBUSB_REQ_POLL_REMOTE 0x04
52
53/* additional status values for Hauppauge Remote Control Protocol */
54#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
55#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
56
57/* streaming mode:
58 * bulk write: 0x05 mode_byte
59 *
60 * mode_byte is mostly 0x00
61 */
62#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
63
64/* interrupt the internal read loop, when blocking */
65#define DIBUSB_REQ_INTR_READ 0x06
66
67/* io control
68 * 0x07 cmd_byte param_bytes
69 *
70 * param_bytes can be up to 32 bytes
71 *
72 * cmd_byte function parameter name
73 * 0x00 power mode
74 * 0x00 sleep
75 * 0x01 wakeup
76 *
77 * 0x01 enable streaming
78 * 0x02 disable streaming
79 *
80 *
81 */
82#define DIBUSB_REQ_SET_IOCTL 0x07
83
84/* IOCTL commands */
85
86/* change the power mode in firmware */
87#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
88#define DIBUSB_IOCTL_POWER_SLEEP 0x00
89#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
90
91/* modify streaming of the FX2 */
92#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
93#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
94
95struct dibusb_state {
96 struct dib_fe_xfer_ops ops;
97
98 /* for RC5 remote control */
99 int old_toggle;
100 int last_repeat_count;
101};
102
103extern struct i2c_algorithm dibusb_i2c_algo;
104
105extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *);
106extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *);
107
108extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int);
109extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int);
110extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int);
111extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
112extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int);
113extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
114
115#define DEFAULT_RC_INTERVAL 150
116//#define DEFAULT_RC_INTERVAL 100000
117
118extern struct dvb_usb_rc_key dibusb_rc_keys[];
119extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
120extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
121
122#endif
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
new file mode 100644
index 000000000000..5acf3fde9522
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -0,0 +1,282 @@
1/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
2 * receiver
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) and
5 * Allan Third (allan.third@cs.man.ac.uk)
6 *
7 * partly based on the SDK published by Nebula Electronics (TODO do we want this line ?)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "digitv.h"
16
17#include "mt352.h"
18#include "nxt6000.h"
19
20/* debug */
21int dvb_usb_digitv_debug;
22module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
23MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
24
25static int digitv_ctrl_msg(struct dvb_usb_device *d,
26 u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
27{
28 int wo = (rbuf == NULL || rlen == 0); /* write-only */
29 u8 sndbuf[7],rcvbuf[7];
30 memset(sndbuf,0,7); memset(rcvbuf,0,7);
31
32 sndbuf[0] = cmd;
33 sndbuf[1] = vv;
34 sndbuf[2] = wo ? wlen : rlen;
35
36 if (!wo) {
37 memcpy(&sndbuf[3],wbuf,wlen);
38 dvb_usb_generic_write(d,sndbuf,7);
39 } else {
40 dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
41 memcpy(&rbuf,&rcvbuf[3],rlen);
42 }
43 return 0;
44}
45
46/* I2C */
47static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
48{
49 struct dvb_usb_device *d = i2c_get_adapdata(adap);
50 int i;
51
52 if (down_interruptible(&d->i2c_sem) < 0)
53 return -EAGAIN;
54
55 if (num > 2)
56 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
57
58 for (i = 0; i < num; i++) {
59 /* write/read request */
60 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
61 if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
62 msg[i+1].buf,msg[i+1].len) < 0)
63 break;
64 i++;
65 } else
66 if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
67 &msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
68 break;
69 }
70
71 up(&d->i2c_sem);
72 return i;
73}
74
75static u32 digitv_i2c_func(struct i2c_adapter *adapter)
76{
77 return I2C_FUNC_I2C;
78}
79
80static struct i2c_algorithm digitv_i2c_algo = {
81 .name = "Nebula DigiTV USB I2C algorithm",
82 .id = I2C_ALGO_BIT,
83 .master_xfer = digitv_i2c_xfer,
84 .functionality = digitv_i2c_func,
85};
86
87/* Callbacks for DVB USB */
88static int digitv_identify_state (struct usb_device *udev, struct
89 dvb_usb_properties *props, struct dvb_usb_device_description **desc,
90 int *cold)
91{
92 *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
93 return 0;
94}
95
96static int digitv_mt352_demod_init(struct dvb_frontend *fe)
97{
98 static u8 mt352_clock_config[] = { 0x89, 0x38, 0x2d };
99 static u8 mt352_reset[] = { 0x50, 0x80 };
100 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
101
102 static u8 mt352_agc_cfg[] = { 0x68, 0xa0 };
103 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0xa0 };
104 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
105 static u8 mt352_agc_target[] = { 0x67, 0x20 };
106
107 static u8 mt352_rs_err_per[] = { 0x7c, 0x00, 0x01 };
108 static u8 mt352_snr_select[] = { 0x79, 0x00, 0x20 };
109
110 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x05 };
111
112 static u8 mt352_scan_ctl[] = { 0x88, 0x0f };
113 static u8 mt352_capt_range[] = { 0x75, 0x32 };
114
115 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
116 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
117 msleep(1);
118 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
119
120 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
121 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
122 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
123 mt352_write(fe, mt352_agc_target, sizeof(mt352_agc_target));
124
125
126 mt352_write(fe, mt352_rs_err_per, sizeof(mt352_rs_err_per));
127 mt352_write(fe, mt352_snr_select, sizeof(mt352_snr_select));
128
129 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
130
131 mt352_write(fe, mt352_scan_ctl, sizeof(mt352_scan_ctl));
132 mt352_write(fe, mt352_capt_range, sizeof(mt352_capt_range));
133
134 return 0;
135}
136
137static struct mt352_config digitv_mt352_config = {
138 .demod_address = 0x0, /* ignored by the digitv anyway */
139 .demod_init = digitv_mt352_demod_init,
140 .pll_set = NULL, /* TODO */
141};
142
143static struct nxt6000_config digitv_nxt6000_config = {
144 .demod_address = 0x0, /* ignored by the digitv anyway */
145 .clock_inversion = 0x0,
146
147 .pll_init = NULL,
148 .pll_set = NULL,
149};
150
151static int digitv_frontend_attach(struct dvb_usb_device *d)
152{
153 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) == NULL)
154 return 0;
155 if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) == NULL) {
156
157 warn("nxt6000 support is not done yet, in fact you are one of the first "
158 "person who wants to use this device in Linux. Please report to "
159 "linux-dvb@linuxtv.org");
160
161 return 0;
162 }
163 return -EIO;
164}
165
166static struct dvb_usb_rc_key digitv_rc_keys[] = {
167 { 0x00, 0x16, KEY_POWER }, /* dummy key */
168};
169
170/* TODO is it really the NEC protocol ? */
171int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
172{
173 u8 key[5];
174
175 digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
176 /* TODO state, maybe it is VV ? */
177 if (key[1] != 0)
178 key[0] = 0x01; /* if something is inside the buffer, simulate key press */
179
180 /* call the universal NEC remote processor, to find out the key's state and event */
181 dvb_usb_nec_rc_key_to_event(d,key,event,state);
182 if (key[0] != 0)
183 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
184 return 0;
185}
186
187
188/* DVB USB Driver stuff */
189static struct dvb_usb_properties digitv_properties;
190
191static int digitv_probe(struct usb_interface *intf,
192 const struct usb_device_id *id)
193{
194 return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE);
195}
196
197static struct usb_device_id digitv_table [] = {
198 { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
199 { } /* Terminating entry */
200};
201MODULE_DEVICE_TABLE (usb, digitv_table);
202
203static struct dvb_usb_properties digitv_properties = {
204 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
205
206 .usb_ctrl = CYPRESS_FX2,
207 .firmware = "dvb-usb-digitv-01.fw",
208
209 .size_of_priv = 0,
210
211 .streaming_ctrl = NULL,
212 .pid_filter = NULL,
213 .pid_filter_ctrl = NULL,
214 .power_ctrl = NULL,
215 .frontend_attach = digitv_frontend_attach,
216 .tuner_attach = NULL, // digitv_tuner_attach,
217 .read_mac_address = NULL,
218
219 .rc_interval = 1000,
220 .rc_key_map = digitv_rc_keys,
221 .rc_key_map_size = ARRAY_SIZE(digitv_rc_keys),
222 .rc_query = digitv_rc_query,
223
224 .identify_state = digitv_identify_state,
225
226 .i2c_algo = &digitv_i2c_algo,
227
228 .generic_bulk_ctrl_endpoint = 0x01,
229 /* parameter for the MPEG2-data transfer */
230 .urb = {
231 .type = DVB_USB_BULK,
232 .count = 7,
233 .endpoint = 0x02,
234 .u = {
235 .bulk = {
236 .buffersize = 4096,
237 }
238 }
239 },
240
241 .num_device_descs = 2,
242 .devices = {
243 { "Nebula Electronics uDigiTV DVB-T USB2.0)",
244 { &digitv_table[0], NULL },
245 { NULL },
246 },
247 }
248};
249
250static struct usb_driver digitv_driver = {
251 .owner = THIS_MODULE,
252 .name = "Nebula Electronics uDigiTV DVB-T USB2.0 device",
253 .probe = digitv_probe,
254 .disconnect = dvb_usb_device_exit,
255 .id_table = digitv_table,
256};
257
258/* module stuff */
259static int __init digitv_module_init(void)
260{
261 int result;
262 if ((result = usb_register(&digitv_driver))) {
263 err("usb_register failed. Error number %d",result);
264 return result;
265 }
266
267 return 0;
268}
269
270static void __exit digitv_module_exit(void)
271{
272 /* deregister this driver from the USB subsystem */
273 usb_deregister(&digitv_driver);
274}
275
276module_init (digitv_module_init);
277module_exit (digitv_module_exit);
278
279MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
280MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
281MODULE_VERSION("1.0-alpha");
282MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h
new file mode 100644
index 000000000000..477ee428a70e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.h
@@ -0,0 +1,65 @@
1#ifndef _DVB_USB_DIGITV_H_
2#define _DVB_USB_DIGITV_H_
3
4#define DVB_USB_LOG_PREFIX "digitv"
5#include "dvb-usb.h"
6
7extern int dvb_usb_digitv_debug;
8#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
9
10/* protocol (from usblogging and the SDK:
11 *
12 * Always 7 bytes bulk message(s) for controlling
13 *
14 * First byte describes the command. Reads are 2 consecutive transfer (as always).
15 *
16 * General structure:
17 *
18 * write or first message of a read:
19 * <cmdbyte> VV <len> B0 B1 B2 B3
20 *
21 * second message of a read
22 * <cmdbyte> VV <len> R0 R1 R2 R3
23 *
24 * whereas 0 < len <= 4
25 *
26 * I2C address is stored somewhere inside the device.
27 *
28 * 0x01 read from EEPROM
29 * VV = offset; B* = 0; R* = value(s)
30 *
31 * 0x02 read register of the COFDM
32 * VV = register; B* = 0; R* = value(s)
33 *
34 * 0x05 write register of the COFDM
35 * VV = register; B* = value(s);
36 *
37 * 0x06 write to the tuner (only for NXT6000)
38 * VV = 0; B* = PLL data; len = 4;
39 *
40 * 0x03 read remote control
41 * VV = 0; B* = 0; len = 4; R* = key
42 *
43 * 0x07 write to the remote (don't know why one should this, resetting ?)
44 * VV = 0; B* = key; len = 4;
45 *
46 * 0x08 write remote type
47 * VV = 0; B[0] = 0x01, len = 4
48 *
49 * 0x09 write device init
50 * TODO
51 */
52#define USB_READ_EEPROM 1
53
54#define USB_READ_COFDM 2
55#define USB_WRITE_COFDM 5
56
57#define USB_WRITE_TUNER 6
58
59#define USB_READ_REMOTE 3
60#define USB_WRITE_REMOTE 7
61#define USB_WRITE_REMOTE_TYPE 8
62
63#define USB_DEV_INIT 9
64
65#endif
diff --git a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index 1872aa6d200a..d17d768038c6 100644
--- a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -1,42 +1,18 @@
1/* 1/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T
2 * dvb-dtt200u-fe.c is a driver which implements the frontend-part of the 2 * USB2.0 receiver.
3 * Yakumo/Typhoon/Hama USB2.0 boxes. It is hard-wired to the dibusb-driver as
4 * it uses the usb-transfer functions directly (maybe creating a
5 * generic-dvb-usb-lib for all usb-drivers will be reduce some more code.)
6 * 3 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de> 4 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 * 5 *
9 * see dvb-dibusb-core.c for copyright details. 6 * This program is free software; you can redistribute it and/or modify it
10 */ 7 * under the terms of the GNU General Public License as published by the Free
11 8 * Software Foundation, version 2.
12/* guessed protocol description (reverse engineered):
13 * read
14 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
15 * 81 - <TS_LOCK> <current frequency divided by 250000>
16 * 82 - crash - do not touch
17 * 83 - crash - do not touch
18 * 84 - remote control
19 * 85 - crash - do not touch (OK, stop testing here)
20 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
21 * 89 - noise-to-signal
22 * 8a - unkown 1 byte - signal_strength
23 * 8c - ber ???
24 * 8d - ber
25 * 8e - unc
26 * 9 *
27 * write 10 * see Documentation/dvb/README.dvb-usb for more information
28 * 02 - bandwidth
29 * 03 - frequency (divided by 250000)
30 * 04 - pid table (index pid(7:0) pid(12:8))
31 * 05 - reset the pid table
32 * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
33 */ 11 */
34 12#include "dtt200u.h"
35#include "dvb-dibusb.h"
36#include "dvb_frontend.h"
37 13
38struct dtt200u_fe_state { 14struct dtt200u_fe_state {
39 struct usb_dibusb *dib; 15 struct dvb_usb_device *d;
40 16
41 struct dvb_frontend_parameters fep; 17 struct dvb_frontend_parameters fep;
42 struct dvb_frontend frontend; 18 struct dvb_frontend frontend;
@@ -47,11 +23,11 @@ struct dtt200u_fe_state {
47static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) 23static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
48{ 24{
49 struct dtt200u_fe_state *state = fe->demodulator_priv; 25 struct dtt200u_fe_state *state = fe->demodulator_priv;
50 u8 bw[1] = { 0x81 }; 26 u8 bw = GET_TUNE_STAT;
51 u8 br[3] = { 0 }; 27 u8 br[3] = { 0 };
52// u8 bdeb[5] = { 0 }; 28// u8 bdeb[5] = { 0 };
53 29
54 dibusb_readwrite_usb(state->dib,bw,1,br,3); 30 dvb_usb_generic_rw(state->d,&bw,1,br,3,0);
55 switch (br[0]) { 31 switch (br[0]) {
56 case 0x01: 32 case 0x01:
57 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 33 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
@@ -60,12 +36,12 @@ static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
60 *stat = 0; 36 *stat = 0;
61 break; 37 break;
62 default: 38 default:
63 moan("br[0]",0x81); 39 moan("br[0]",GET_TUNE_STAT);
64 break; 40 break;
65 } 41 }
66 42
67// bw[0] = 0x88; 43// bw[0] = 0x88;
68// dibusb_readwrite_usb(state->dib,bw,1,bdeb,5); 44// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0);
69 45
70// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]); 46// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
71 47
@@ -74,27 +50,26 @@ static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
74static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber) 50static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
75{ 51{
76 struct dtt200u_fe_state *state = fe->demodulator_priv; 52 struct dtt200u_fe_state *state = fe->demodulator_priv;
77 u8 bw[1] = { 0x8d }; 53 u8 bw = GET_BER;
78 *ber = 0; 54 *ber = 0;
79 dibusb_readwrite_usb(state->dib,bw,1,(u8*) ber, 3); 55 dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0);
80 return 0; 56 return 0;
81} 57}
82 58
83static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) 59static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
84{ 60{
85 struct dtt200u_fe_state *state = fe->demodulator_priv; 61 struct dtt200u_fe_state *state = fe->demodulator_priv;
86 u8 bw[1] = { 0x8c }; 62 u8 bw = GET_UNK;
87 *unc = 0; 63 *unc = 0;
88 dibusb_readwrite_usb(state->dib,bw,1,(u8*) unc, 3); 64 dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0);
89 return 0; 65 return 0;
90} 66}
91 67
92static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) 68static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
93{ 69{
94 struct dtt200u_fe_state *state = fe->demodulator_priv; 70 struct dtt200u_fe_state *state = fe->demodulator_priv;
95 u8 bw[1] = { 0x8a }; 71 u8 bw = GET_SIG_STRENGTH, b;
96 u8 b; 72 dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
97 dibusb_readwrite_usb(state->dib,bw,1,&b, 1);
98 *strength = (b << 8) | b; 73 *strength = (b << 8) | b;
99 return 0; 74 return 0;
100} 75}
@@ -102,18 +77,17 @@ static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strengt
102static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr) 77static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
103{ 78{
104 struct dtt200u_fe_state *state = fe->demodulator_priv; 79 struct dtt200u_fe_state *state = fe->demodulator_priv;
105 u8 bw[1] = { 0x89 }; 80 u8 bw = GET_SNR,br;
106 u8 br[1] = { 0 }; 81 dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
107 dibusb_readwrite_usb(state->dib,bw,1,br,1); 82 *snr = ~((br << 8) | br);
108 *snr = ((0xff - br[0]) << 8) | (0xff - br[0]);
109 return 0; 83 return 0;
110} 84}
111 85
112static int dtt200u_fe_init(struct dvb_frontend* fe) 86static int dtt200u_fe_init(struct dvb_frontend* fe)
113{ 87{
114 struct dtt200u_fe_state *state = fe->demodulator_priv; 88 struct dtt200u_fe_state *state = fe->demodulator_priv;
115 u8 b[] = { 0x01 }; 89 u8 b = RESET_DEMOD;
116 return dibusb_write_usb(state->dib,b,1); 90 return dvb_usb_generic_write(state->d,&b,1);
117} 91}
118 92
119static int dtt200u_fe_sleep(struct dvb_frontend* fe) 93static int dtt200u_fe_sleep(struct dvb_frontend* fe)
@@ -134,7 +108,7 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
134{ 108{
135 struct dtt200u_fe_state *state = fe->demodulator_priv; 109 struct dtt200u_fe_state *state = fe->demodulator_priv;
136 u16 freq = fep->frequency / 250000; 110 u16 freq = fep->frequency / 250000;
137 u8 bw,bwbuf[2] = { 0x03, 0 }, freqbuf[3] = { 0x02, 0, 0 }; 111 u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 };
138 112
139 switch (fep->u.ofdm.bandwidth) { 113 switch (fep->u.ofdm.bandwidth) {
140 case BANDWIDTH_8_MHZ: bw = 8; break; 114 case BANDWIDTH_8_MHZ: bw = 8; break;
@@ -147,11 +121,11 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
147 deb_info("set_frontend\n"); 121 deb_info("set_frontend\n");
148 122
149 bwbuf[1] = bw; 123 bwbuf[1] = bw;
150 dibusb_write_usb(state->dib,bwbuf,2); 124 dvb_usb_generic_write(state->d,bwbuf,2);
151 125
152 freqbuf[1] = freq & 0xff; 126 freqbuf[1] = freq & 0xff;
153 freqbuf[2] = (freq >> 8) & 0xff; 127 freqbuf[2] = (freq >> 8) & 0xff;
154 dibusb_write_usb(state->dib,freqbuf,3); 128 dvb_usb_generic_write(state->d,freqbuf,3);
155 129
156 memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters)); 130 memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
157 131
@@ -172,37 +146,9 @@ static void dtt200u_fe_release(struct dvb_frontend* fe)
172 kfree(state); 146 kfree(state);
173} 147}
174 148
175static int dtt200u_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
176{
177 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
178 u8 b_pid[4];
179 pid = onoff ? pid : 0;
180
181 b_pid[0] = 0x04;
182 b_pid[1] = index;
183 b_pid[2] = pid & 0xff;
184 b_pid[3] = (pid >> 8) & 0xff;
185
186 dibusb_write_usb(state->dib,b_pid,4);
187 return 0;
188}
189
190static int dtt200u_fifo_control(struct dvb_frontend *fe, int onoff)
191{
192 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
193 u8 b_streaming[2] = { 0x08, onoff };
194 u8 b_rst_pid[1] = { 0x05 };
195
196 dibusb_write_usb(state->dib,b_streaming,2);
197
198 if (!onoff)
199 dibusb_write_usb(state->dib,b_rst_pid,1);
200 return 0;
201}
202
203static struct dvb_frontend_ops dtt200u_fe_ops; 149static struct dvb_frontend_ops dtt200u_fe_ops;
204 150
205struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfer_ops *xfer_ops) 151struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
206{ 152{
207 struct dtt200u_fe_state* state = NULL; 153 struct dtt200u_fe_state* state = NULL;
208 154
@@ -214,14 +160,11 @@ struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfe
214 160
215 deb_info("attaching frontend dtt200u\n"); 161 deb_info("attaching frontend dtt200u\n");
216 162
217 state->dib = dib; 163 state->d = d;
218 164
219 state->frontend.ops = &dtt200u_fe_ops; 165 state->frontend.ops = &dtt200u_fe_ops;
220 state->frontend.demodulator_priv = state; 166 state->frontend.demodulator_priv = state;
221 167
222 xfer_ops->fifo_ctrl = dtt200u_fifo_control;
223 xfer_ops->pid_ctrl = dtt200u_pid_control;
224
225 goto success; 168 goto success;
226error: 169error:
227 return NULL; 170 return NULL;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
new file mode 100644
index 000000000000..fb2b5a2da137
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -0,0 +1,171 @@
1/* DVB USB library compliant Linux driver for the Yakumo/Hama/Typhoon DVB-T
2 * USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dtt200u.h"
13
14/* debug */
15int dvb_usb_dtt200u_debug;
16module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
17MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
18
19static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
20{
21 u8 b_streaming[2] = { SET_TS_CTRL, onoff };
22 u8 b_rst_pid = RESET_PID_FILTER;
23
24 dvb_usb_generic_write(d,b_streaming,2);
25
26 if (!onoff)
27 dvb_usb_generic_write(d,&b_rst_pid,1);
28 return 0;
29}
30
31static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
32{
33 u8 b_pid[4];
34 pid = onoff ? pid : 0;
35
36 b_pid[0] = SET_PID_FILTER;
37 b_pid[1] = index;
38 b_pid[2] = pid & 0xff;
39 b_pid[3] = (pid >> 8) & 0xff;
40
41 return dvb_usb_generic_write(d,b_pid,4);
42}
43
44/* remote control */
45/* key list for the tiny remote control (Yakumo, don't know about the others) */
46static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
47 { 0x80, 0x01, KEY_MUTE },
48 { 0x80, 0x02, KEY_CHANNELDOWN },
49 { 0x80, 0x03, KEY_VOLUMEDOWN },
50 { 0x80, 0x04, KEY_1 },
51 { 0x80, 0x05, KEY_2 },
52 { 0x80, 0x06, KEY_3 },
53 { 0x80, 0x07, KEY_4 },
54 { 0x80, 0x08, KEY_5 },
55 { 0x80, 0x09, KEY_6 },
56 { 0x80, 0x0a, KEY_7 },
57 { 0x00, 0x0c, KEY_ZOOM },
58 { 0x80, 0x0d, KEY_0 },
59 { 0x00, 0x0e, KEY_SELECT },
60 { 0x80, 0x12, KEY_POWER },
61 { 0x80, 0x1a, KEY_CHANNELUP },
62 { 0x80, 0x1b, KEY_8 },
63 { 0x80, 0x1e, KEY_VOLUMEUP },
64 { 0x80, 0x1f, KEY_9 },
65};
66
67static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
68{
69 u8 key[5],cmd = GET_RC_KEY;
70 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
71 dvb_usb_nec_rc_key_to_event(d,key,event,state);
72 if (key[0] != 0)
73 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
74 return 0;
75}
76
77static int dtt200u_frontend_attach(struct dvb_usb_device *d)
78{
79 d->fe = dtt200u_fe_attach(d);
80 return 0;
81}
82
83static struct dvb_usb_properties dtt200u_properties;
84
85static int dtt200u_usb_probe(struct usb_interface *intf,
86 const struct usb_device_id *id)
87{
88 return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE);
89}
90
91static struct usb_device_id dtt200u_usb_table [] = {
92 { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_COLD) },
93 { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_WARM) },
94 { 0 },
95};
96MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
97
98static struct dvb_usb_properties dtt200u_properties = {
99 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
100 .pid_filter_count = 255, /* It is a guess, but there are at least 10 */
101
102 .usb_ctrl = CYPRESS_FX2,
103 .firmware = "dvb-usb-dtt200u-01.fw",
104
105 .streaming_ctrl = dtt200u_streaming_ctrl,
106 .pid_filter = dtt200u_pid_filter,
107 .frontend_attach = dtt200u_frontend_attach,
108
109 .rc_interval = 200,
110 .rc_key_map = dtt200u_rc_keys,
111 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
112 .rc_query = dtt200u_rc_query,
113
114 .generic_bulk_ctrl_endpoint = 0x01,
115
116 /* parameter for the MPEG2-data transfer */
117 .urb = {
118 .type = DVB_USB_BULK,
119 .count = 7,
120 .endpoint = 0x02,
121 .u = {
122 .bulk = {
123 .buffersize = 4096,
124 }
125 }
126 },
127
128 .num_device_descs = 1,
129 .devices = {
130 { .name = "Yakumo/Hama/Typhoon DVB-T USB2.0)",
131 .cold_ids = { &dtt200u_usb_table[0], &dtt200u_usb_table[2] },
132 .warm_ids = { &dtt200u_usb_table[1], NULL },
133 },
134 { 0 },
135 }
136};
137
138/* usb specific object needed to register this driver with the usb subsystem */
139static struct usb_driver dtt200u_usb_driver = {
140 .owner = THIS_MODULE,
141 .name = "Yakumo/Hama/Typhoon DVB-T USB2.0",
142 .probe = dtt200u_usb_probe,
143 .disconnect = dvb_usb_device_exit,
144 .id_table = dtt200u_usb_table,
145};
146
147/* module stuff */
148static int __init dtt200u_usb_module_init(void)
149{
150 int result;
151 if ((result = usb_register(&dtt200u_usb_driver))) {
152 err("usb_register failed. (%d)",result);
153 return result;
154 }
155
156 return 0;
157}
158
159static void __exit dtt200u_usb_module_exit(void)
160{
161 /* deregister this driver from the USB subsystem */
162 usb_deregister(&dtt200u_usb_driver);
163}
164
165module_init(dtt200u_usb_module_init);
166module_exit(dtt200u_usb_module_exit);
167
168MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
169MODULE_DESCRIPTION("Driver for the Yakumo/Hama/Typhoon DVB-T USB2.0 device");
170MODULE_VERSION("1.0");
171MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
new file mode 100644
index 000000000000..ed4142071518
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -0,0 +1,66 @@
1/* Common header file of Linux driver for the Yakumo/Hama/Typhoon DVB-T
2 * USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#ifndef _DVB_USB_DTT200U_H_
13#define _DVB_USB_DTT200U_H_
14
15#define DVB_USB_LOG_PREFIX "dtt200u"
16#include "dvb-usb.h"
17
18extern int dvb_usb_dtt200u_debug;
19#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
20#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
21
22/* guessed protocol description (reverse engineered):
23 * read
24 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
25 * 81 - <TS_LOCK> <current frequency divided by 250000>
26 * 82 - crash - do not touch
27 * 83 - crash - do not touch
28 * 84 - remote control
29 * 85 - crash - do not touch (OK, stop testing here)
30 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
31 * 89 - noise-to-signal
32 * 8a - unkown 1 byte - signal_strength
33 * 8c - ber ???
34 * 8d - ber
35 * 8e - unc
36 */
37
38#define GET_SPEED 0x00
39#define GET_TUNE_STAT 0x81
40#define GET_RC_KEY 0x84
41#define GET_STATUS 0x88
42#define GET_SNR 0x89
43#define GET_SIG_STRENGTH 0x8a
44#define GET_UNK 0x8c
45#define GET_BER 0x8d
46#define GET_UNC 0x8e
47
48/* write
49 * 01 - reset the demod
50 * 02 - frequency (divided by 250000)
51 * 03 - bandwidth
52 * 04 - pid table (index pid(7:0) pid(12:8))
53 * 05 - reset the pid table
54 * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
55 */
56
57#define RESET_DEMOD 0x01
58#define SET_FREQUENCY 0x02
59#define SET_BANDWIDTH 0x03
60#define SET_PID_FILTER 0x04
61#define RESET_PID_FILTER 0x05
62#define SET_TS_CTRL 0x08
63
64extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
65
66#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
new file mode 100644
index 000000000000..67e0d73fbceb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -0,0 +1,44 @@
1/* dvb-usb-common.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * a header file containing prototypes and types for internal use of the dvb-usb-lib
7 */
8#ifndef _DVB_USB_COMMON_H_
9#define _DVB_USB_COMMON_H_
10
11#define DVB_USB_LOG_PREFIX "dvb-usb"
12#include "dvb-usb.h"
13
14extern int dvb_usb_debug;
15
16#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
17#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
18#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
19#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args)
20#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args)
21#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args)
22#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args)
23
24/* commonly used methods */
25extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
26
27extern int dvb_usb_urb_submit(struct dvb_usb_device *);
28extern int dvb_usb_urb_kill(struct dvb_usb_device *);
29extern int dvb_usb_urb_init(struct dvb_usb_device *);
30extern int dvb_usb_urb_exit(struct dvb_usb_device *);
31
32extern int dvb_usb_i2c_init(struct dvb_usb_device *);
33extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
34
35extern int dvb_usb_dvb_init(struct dvb_usb_device *);
36extern int dvb_usb_dvb_exit(struct dvb_usb_device *);
37
38extern int dvb_usb_fe_init(struct dvb_usb_device *);
39extern int dvb_usb_fe_exit(struct dvb_usb_device *);
40
41extern int dvb_usb_remote_init(struct dvb_usb_device *);
42extern int dvb_usb_remote_exit(struct dvb_usb_device *);
43
44#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
new file mode 100644
index 000000000000..bdd72f779707
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -0,0 +1,210 @@
1/* dvb-usb-dvb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing and handling the
7 * linux-dvb API.
8 */
9#include "dvb-usb-common.h"
10
11static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
12{
13 struct dvb_usb_device *d = dvbdmxfeed->demux->priv;
14 int newfeedcount,ret;
15
16 if (d == NULL)
17 return -ENODEV;
18
19 newfeedcount = d->feedcount + (onoff ? 1 : -1);
20
21 /*
22 * stop feed before setting a new pid if there will be no pid anymore
23 */
24 if (newfeedcount == 0) {
25 deb_ts("stop feeding\n");
26
27 if (d->props.streaming_ctrl != NULL)
28 if ((ret = d->props.streaming_ctrl(d,0)))
29 err("error while stopping stream.");
30
31 dvb_usb_urb_kill(d);
32 }
33
34 d->feedcount = newfeedcount;
35
36 /* activate the pid on the device specific pid_filter */
37 deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
38 if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
39 d->pid_filtering &&
40 d->props.pid_filter != NULL)
41 d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
42
43 /* start the feed if this was the first feed and there is still a feed
44 * for reception.
45 */
46 if (d->feedcount == onoff && d->feedcount > 0) {
47
48 deb_ts("controlling pid parser\n");
49 if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
50 d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF &&
51 d->props.pid_filter_ctrl != NULL)
52 if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0)
53 err("could not handle pid_parser");
54
55 deb_ts("start feeding\n");
56 if (d->props.streaming_ctrl != NULL)
57 if (d->props.streaming_ctrl(d,1)) {
58 err("error while enabling fifo.");
59 return -ENODEV;
60 }
61
62 dvb_usb_urb_submit(d);
63 }
64 return 0;
65}
66
67static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
68{
69 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
70 return dvb_usb_ctrl_feed(dvbdmxfeed,1);
71}
72
73static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
74{
75 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
76 return dvb_usb_ctrl_feed(dvbdmxfeed,0);
77}
78
79int dvb_usb_dvb_init(struct dvb_usb_device *d)
80{
81 int ret;
82
83 if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
84 d->owner)) < 0) {
85 deb_info("dvb_register_adapter failed: error %d", ret);
86 goto err;
87 }
88 d->dvb_adap.priv = d;
89
90 if (d->props.read_mac_address) {
91 if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0)
92 info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0],
93 d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2],
94 d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4],
95 d->dvb_adap.proposed_mac[5]);
96 else
97 err("MAC address reading failed.");
98 }
99
100
101 d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
102 d->demux.priv = d;
103
104 d->demux.feednum = d->demux.filternum = d->max_feed_count;
105 d->demux.start_feed = dvb_usb_start_feed;
106 d->demux.stop_feed = dvb_usb_stop_feed;
107 d->demux.write_to_decoder = NULL;
108 if ((ret = dvb_dmx_init(&d->demux)) < 0) {
109 err("dvb_dmx_init failed: error %d",ret);
110 goto err_dmx;
111 }
112
113 d->dmxdev.filternum = d->demux.filternum;
114 d->dmxdev.demux = &d->demux.dmx;
115 d->dmxdev.capabilities = 0;
116 if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) {
117 err("dvb_dmxdev_init failed: error %d",ret);
118 goto err_dmx_dev;
119 }
120
121 dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
122
123 goto success;
124err_dmx_dev:
125 dvb_dmx_release(&d->demux);
126err_dmx:
127 dvb_unregister_adapter(&d->dvb_adap);
128err:
129 return ret;
130success:
131 d->state |= DVB_USB_STATE_DVB;
132 return 0;
133}
134
135int dvb_usb_dvb_exit(struct dvb_usb_device *d)
136{
137 if (d->state & DVB_USB_STATE_DVB) {
138 deb_info("unregistering DVB part\n");
139 dvb_net_release(&d->dvb_net);
140 d->demux.dmx.close(&d->demux.dmx);
141 dvb_dmxdev_release(&d->dmxdev);
142 dvb_dmx_release(&d->demux);
143 dvb_unregister_adapter(&d->dvb_adap);
144 d->state &= ~DVB_USB_STATE_DVB;
145 }
146 return 0;
147}
148
149static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
150{
151 struct dvb_usb_device *d = fe->dvb->priv;
152
153 if (d->props.power_ctrl)
154 d->props.power_ctrl(d,1);
155
156 if (d->fe_init)
157 d->fe_init(fe);
158
159 return 0;
160}
161
162static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
163{
164 struct dvb_usb_device *d = fe->dvb->priv;
165
166 if (d->fe_sleep)
167 d->fe_sleep(fe);
168
169 if (d->props.power_ctrl)
170 d->props.power_ctrl(d,0);
171
172 return 0;
173}
174
175int dvb_usb_fe_init(struct dvb_usb_device* d)
176{
177 if (d->props.frontend_attach == NULL) {
178 err("strange '%s' don't want to attach a frontend.",d->desc->name);
179 return 0;
180 }
181
182 d->props.frontend_attach(d);
183
184 /* re-assign sleep and wakeup functions */
185 if (d->fe != NULL) {
186 d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup;
187 d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep;
188
189 if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
190 err("Frontend registration failed.");
191 if (d->fe->ops->release)
192 d->fe->ops->release(d->fe);
193 d->fe = NULL;
194 return -ENODEV;
195 }
196 } else
197 err("no frontend was attached by '%s'",d->desc->name);
198
199 if (d->props.tuner_attach != NULL)
200 d->props.tuner_attach(d);
201
202 return 0;
203}
204
205int dvb_usb_fe_exit(struct dvb_usb_device *d)
206{
207 if (d->fe != NULL)
208 dvb_unregister_frontend(d->fe);
209 return 0;
210}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
new file mode 100644
index 000000000000..5244e39770a0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -0,0 +1,100 @@
1/* dvb-usb-firmware.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
7 *
8 * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
9 */
10#include "dvb-usb-common.h"
11
12#include <linux/firmware.h>
13#include <linux/usb.h>
14
15struct usb_cypress_controller {
16 int id;
17 const char *name; /* name of the usb controller */
18 u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
19};
20
21static struct usb_cypress_controller cypress[] = {
22 { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
23 { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
24 { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
25};
26
27/*
28 * load a firmware packet to the device
29 */
30static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
31{
32 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
33 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ);
34}
35
36int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type)
37{
38 const struct firmware *fw = NULL;
39 u16 addr;
40 u8 *b,*p;
41 int ret = 0,i;
42
43 if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) {
44 err("did not find the firmware file. (%s) "
45 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
46 filename);
47 return ret;
48 }
49
50 info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name);
51
52 p = kmalloc(fw->size,GFP_KERNEL);
53 if (p != NULL) {
54 u8 reset;
55 /*
56 * you cannot use the fw->data as buffer for
57 * usb_control_msg, a new buffer has to be
58 * created
59 */
60 memcpy(p,fw->data,fw->size);
61
62 /* stop the CPU */
63 reset = 1;
64 if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
65 err("could not stop the USB controller CPU.");
66 for(i = 0; p[i+3] == 0 && i < fw->size; ) {
67 b = (u8 *) &p[i];
68 addr = cpu_to_le16( *((u16 *) &b[1]) );
69
70 deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]);
71
72 ret = usb_cypress_writemem(udev,addr,&b[4],b[0]);
73
74 if (ret != b[0]) {
75 err("error while transferring firmware "
76 "(transferred size: %d, block size: %d)",
77 ret,b[0]);
78 ret = -EINVAL;
79 break;
80 }
81 i += 5 + b[0];
82 }
83 /* length in ret */
84 if (ret > 0)
85 ret = 0;
86 /* restart the CPU */
87 reset = 0;
88 if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
89 err("could not restart the USB controller CPU.");
90 ret = -EINVAL;
91 }
92
93 kfree(p);
94 } else {
95 ret = -ENOMEM;
96 }
97 release_firmware(fw);
98
99 return ret;
100}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
new file mode 100644
index 000000000000..9f0a8d90d146
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -0,0 +1,118 @@
1/* dvb-usb-i2c.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for (de-)initializing an I2C adapter.
7 */
8#include "dvb-usb-common.h"
9
10int dvb_usb_i2c_init(struct dvb_usb_device *d)
11{
12 int ret = 0;
13
14 if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
15 return 0;
16
17 if (d->props.i2c_algo == NULL) {
18 err("no i2c algorithm specified");
19 return -EINVAL;
20 }
21
22 strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE);
23#ifdef I2C_ADAP_CLASS_TV_DIGITAL
24 d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
25#else
26 d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
27#endif
28 d->i2c_adap.algo = d->props.i2c_algo;
29 d->i2c_adap.algo_data = NULL;
30 d->i2c_adap.id = I2C_ALGO_BIT;
31
32 i2c_set_adapdata(&d->i2c_adap, d);
33
34 if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
35 err("could not add i2c adapter");
36
37 d->state |= DVB_USB_STATE_I2C;
38
39 return ret;
40}
41
42int dvb_usb_i2c_exit(struct dvb_usb_device *d)
43{
44 if (d->state & DVB_USB_STATE_I2C)
45 i2c_del_adapter(&d->i2c_adap);
46 d->state &= ~DVB_USB_STATE_I2C;
47 return 0;
48}
49
50int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
51{
52 struct dvb_usb_device *d = fe->dvb->priv;
53 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
54 int ret = 0;
55
56 /* if there is nothing to initialize */
57 if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 &&
58 d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00)
59 return 0;
60
61 if (d->tuner_pass_ctrl)
62 d->tuner_pass_ctrl(fe,1,d->pll_addr);
63
64 deb_pll("pll init: %x\n",d->pll_addr);
65 deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
66 d->pll_init[2],d->pll_init[3]);
67
68 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
69 err("tuner i2c write failed for pll_init.");
70 ret = -EREMOTEIO;
71 }
72 msleep(1);
73
74 if (d->tuner_pass_ctrl)
75 d->tuner_pass_ctrl(fe,0,d->pll_addr);
76 return ret;
77}
78EXPORT_SYMBOL(dvb_usb_pll_init_i2c);
79
80int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5])
81{
82 struct dvb_usb_device *d = fe->dvb->priv;
83
84 deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
85
86 b[0] = d->pll_addr << 1;
87 dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
88
89 deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
90
91 return 0;
92}
93EXPORT_SYMBOL(dvb_usb_pll_set);
94
95int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
96{
97 struct dvb_usb_device *d = fe->dvb->priv;
98 int ret = 0;
99 u8 b[5];
100 struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
101
102 dvb_usb_pll_set(fe,fep,b);
103
104 if (d->tuner_pass_ctrl)
105 d->tuner_pass_ctrl(fe,1,d->pll_addr);
106
107 if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
108 err("tuner i2c write failed for pll_set.");
109 ret = -EREMOTEIO;
110 }
111 msleep(1);
112
113 if (d->tuner_pass_ctrl)
114 d->tuner_pass_ctrl(fe,0,d->pll_addr);
115
116 return ret;
117}
118EXPORT_SYMBOL(dvb_usb_pll_set_i2c);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
new file mode 100644
index 000000000000..bcb34191868b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -0,0 +1,83 @@
1/* dvb-usb-ids.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see
4 * dvb-usb-init.c for copyright information.
5 *
6 * a header file containing define's for the USB device supported by the
7 * various drivers.
8 */
9#ifndef _DVB_USB_IDS_H_
10#define _DVB_USB_IDS_H_
11
12/* Vendor IDs */
13#define USB_VID_ADSTECH 0x06e1
14#define USB_VID_ANCHOR 0x0547
15#define USB_VID_AVERMEDIA_UNK 0x14aa
16#define USB_VID_AVERMEDIA 0x07ca
17#define USB_VID_COMPRO 0x185b
18#define USB_VID_COMPRO_UNK 0x145f
19#define USB_VID_CYPRESS 0x04b4
20#define USB_VID_DIBCOM 0x10b8
21#define USB_VID_DVICO 0x0fe9
22#define USB_VID_EMPIA 0xeb1a
23#define USB_VID_GRANDTEC 0x5032
24#define USB_VID_HANFTEK 0x15f4
25#define USB_VID_HAUPPAUGE 0x2040
26#define USB_VID_HYPER_PALTEK 0x1025
27#define USB_VID_VISIONPLUS 0x13d3
28#define USB_VID_TWINHAN 0x1822
29#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
30
31/* Product IDs */
32#define USB_PID_ADSTECH_USB2_COLD 0xa333
33#define USB_PID_ADSTECH_USB2_WARM 0xa334
34#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
35#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
36#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
37#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801
38#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
39#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
40#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
41#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
42#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
43#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
44#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
45#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
46#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
47#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
48#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
49#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
50#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
51#define USB_PID_TWINHAN_VP7041_COLD 0x3201
52#define USB_PID_TWINHAN_VP7041_WARM 0x3202
53#define USB_PID_TWINHAN_VP7045_COLD 0x3205
54#define USB_PID_TWINHAN_VP7045_WARM 0x3206
55#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
56#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
57#define USB_PID_TWINHAN_VP7021_COLD 0x3207
58#define USB_PID_TWINHAN_VP7021_WARM 0x3208
59#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
60#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
61#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
62#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
63#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
64#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
65#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
66#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
67#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
68#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
69#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
70#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
71#define USB_PID_DTT200U_COLD 0x0201
72#define USB_PID_DTT200U_WARM 0x0301
73#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
74#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
75#define USB_PID_NEBULA_DIGITV 0x0201
76#define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00
77#define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10
78#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
79#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01
80#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11
81
82
83#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
new file mode 100644
index 000000000000..3aadec974cf1
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -0,0 +1,211 @@
1/*
2 * DVB USB library - provides a generic interface for a DVB USB device driver.
3 *
4 * dvb-usb-init.c
5 *
6 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dvb-usb-common.h"
15
16/* debug */
17int dvb_usb_debug;
18module_param_named(debug,dvb_usb_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS);
20
21/* general initialization functions */
22int dvb_usb_exit(struct dvb_usb_device *d)
23{
24 deb_info("state before exiting everything: %x\n",d->state);
25 dvb_usb_remote_exit(d);
26 dvb_usb_fe_exit(d);
27 dvb_usb_i2c_exit(d);
28 dvb_usb_dvb_exit(d);
29 dvb_usb_urb_exit(d);
30 deb_info("state should be zero now: %x\n",d->state);
31 d->state = DVB_USB_STATE_INIT;
32 kfree(d->priv);
33 kfree(d);
34 return 0;
35}
36
37static int dvb_usb_init(struct dvb_usb_device *d)
38{
39 int ret = 0;
40
41 sema_init(&d->usb_sem, 1);
42 sema_init(&d->i2c_sem, 1);
43
44 d->state = DVB_USB_STATE_INIT;
45
46/* check the capabilites and set appropriate variables */
47
48/* speed - when running at FULL speed we need a HW PID filter */
49 if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
50 err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a HW PID filter)");
51 return -ENODEV;
52 }
53
54 if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) ||
55 (d->props.caps & DVB_USB_NEED_PID_FILTERING)) {
56 info("will use the device's hw PID filter.");
57 d->pid_filtering = 1;
58 d->max_feed_count = d->props.pid_filter_count;
59 } else {
60 info("will pass the complete MPEG2 transport stream to the demuxer.");
61 d->pid_filtering = 0;
62 d->max_feed_count = 255;
63 }
64
65 if (d->props.power_ctrl)
66 d->props.power_ctrl(d,1);
67
68 if ((ret = dvb_usb_urb_init(d)) ||
69 (ret = dvb_usb_dvb_init(d)) ||
70 (ret = dvb_usb_i2c_init(d)) ||
71 (ret = dvb_usb_fe_init(d))) {
72 dvb_usb_exit(d);
73 return ret;
74 }
75
76 if ((ret = dvb_usb_remote_init(d)))
77 err("could not initialize remote control.");
78
79 if (d->props.power_ctrl)
80 d->props.power_ctrl(d,0);
81
82 return 0;
83}
84
85/* determine the name and the state of the just found USB device */
86static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold)
87{
88 int i,j;
89 struct dvb_usb_device_description *desc = NULL;
90 *cold = -1;
91
92 for (i = 0; i < props->num_device_descs; i++) {
93
94 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
95 deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
96 if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
97 props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
98 *cold = 1;
99 desc = &props->devices[i];
100 break;
101 }
102 }
103
104 if (desc != NULL)
105 break;
106
107 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
108 deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
109 if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
110 props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
111 *cold = 0;
112 desc = &props->devices[i];
113 break;
114 }
115 }
116 }
117
118 if (desc != NULL && props->identify_state != NULL)
119 props->identify_state(udev,props,&desc,cold);
120
121 return desc;
122}
123
124/*
125 * USB
126 */
127int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner)
128{
129 struct usb_device *udev = interface_to_usbdev(intf);
130 struct dvb_usb_device *d = NULL;
131 struct dvb_usb_device_description *desc = NULL;
132
133 int ret = -ENOMEM,cold=0;
134
135 if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) {
136 deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
137 return -ENODEV;
138 }
139
140 if (cold) {
141 info("found a '%s' in cold state, will try to load a firmware",desc->name);
142 ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl);
143 } else {
144 info("found a '%s' in warm state.",desc->name);
145 d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
146 if (d == NULL) {
147 err("no memory for 'struct dvb_usb_device'");
148 return ret;
149 }
150 memset(d,0,sizeof(struct dvb_usb_device));
151
152 d->udev = udev;
153 memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
154 d->desc = desc;
155 d->owner = owner;
156
157 if (d->props.size_of_priv > 0) {
158 d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
159 if (d->priv == NULL) {
160 err("no memory for priv in 'struct dvb_usb_device'");
161 kfree(d);
162 return -ENOMEM;
163 }
164 memset(d->priv,0,d->props.size_of_priv);
165 }
166
167 usb_set_intfdata(intf, d);
168
169 ret = dvb_usb_init(d);
170 }
171
172 if (ret == 0)
173 info("%s successfully initialized and connected.",desc->name);
174 else
175 info("%s error while loading driver (%d)",desc->name,ret);
176 return ret;
177}
178EXPORT_SYMBOL(dvb_usb_device_init);
179
180void dvb_usb_device_exit(struct usb_interface *intf)
181{
182 struct dvb_usb_device *d = usb_get_intfdata(intf);
183 const char *name = "generic DVB-USB module";
184
185 usb_set_intfdata(intf,NULL);
186 if (d != NULL && d->desc != NULL) {
187 name = d->desc->name;
188 dvb_usb_exit(d);
189 }
190 info("%s successfully deinitialized and disconnected.",name);
191
192}
193EXPORT_SYMBOL(dvb_usb_device_exit);
194
195/* module stuff */
196static int __init dvb_usb_module_init(void)
197{
198 return 0;
199}
200
201static void __exit dvb_usb_module_exit(void)
202{
203}
204
205module_init (dvb_usb_module_init);
206module_exit (dvb_usb_module_exit);
207
208MODULE_VERSION("0.3");
209MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
210MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
211MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
new file mode 100644
index 000000000000..9f1e23f82bae
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -0,0 +1,175 @@
1/* dvb-usb-remote.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing the the input-device and for handling remote-control-queries.
7 */
8#include "dvb-usb-common.h"
9
10/* Remote-control poll function - called every dib->rc_query_interval ms to see
11 * whether the remote control has received anything.
12 *
13 * TODO: Fix the repeat rate of the input device.
14 */
15static void dvb_usb_read_remote_control(void *data)
16{
17 struct dvb_usb_device *d = data;
18 u32 event;
19 int state;
20
21 /* TODO: need a lock here. We can simply skip checking for the remote control
22 if we're busy. */
23
24 if (d->props.rc_query(d,&event,&state)) {
25 err("error while querying for an remote control event.");
26 goto schedule;
27 }
28
29
30 switch (state) {
31 case REMOTE_NO_KEY_PRESSED:
32 break;
33 case REMOTE_KEY_PRESSED:
34 deb_rc("key pressed\n");
35 d->last_event = event;
36 case REMOTE_KEY_REPEAT:
37 deb_rc("key repeated\n");
38 input_event(&d->rc_input_dev, EV_KEY, event, 1);
39 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
40 input_sync(&d->rc_input_dev);
41 break;
42 default:
43 break;
44 }
45
46/* improved repeat handling ???
47 switch (state) {
48 case REMOTE_NO_KEY_PRESSED:
49 deb_rc("NO KEY PRESSED\n");
50 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
51 deb_rc("releasing event %d\n",d->last_event);
52 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
53 input_sync(&d->rc_input_dev);
54 }
55 d->last_state = REMOTE_NO_KEY_PRESSED;
56 d->last_event = 0;
57 break;
58 case REMOTE_KEY_PRESSED:
59 deb_rc("KEY PRESSED\n");
60 deb_rc("pressing event %d\n",event);
61
62 input_event(&d->rc_input_dev, EV_KEY, event, 1);
63 input_sync(&d->rc_input_dev);
64
65 d->last_event = event;
66 d->last_state = REMOTE_KEY_PRESSED;
67 break;
68 case REMOTE_KEY_REPEAT:
69 deb_rc("KEY_REPEAT\n");
70 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
71 deb_rc("repeating event %d\n",d->last_event);
72 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
73 input_sync(&d->rc_input_dev);
74 d->last_state = REMOTE_KEY_REPEAT;
75 }
76 default:
77 break;
78 }
79*/
80
81schedule:
82 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
83}
84
85int dvb_usb_remote_init(struct dvb_usb_device *d)
86{
87 int i;
88 if (d->props.rc_key_map == NULL)
89 return 0;
90
91 /* Initialise the remote-control structures.*/
92 init_input_dev(&d->rc_input_dev);
93
94 d->rc_input_dev.evbit[0] = BIT(EV_KEY);
95 d->rc_input_dev.keycodesize = sizeof(unsigned char);
96 d->rc_input_dev.keycodemax = KEY_MAX;
97 d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
98
99 /* set the bits for the keys */
100 deb_rc("key map size: %d\n",d->props.rc_key_map_size);
101 for (i = 0; i < d->props.rc_key_map_size; i++) {
102 deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
103 set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
104 }
105
106 /* Start the remote-control polling. */
107 if (d->props.rc_interval < 40)
108 d->props.rc_interval = 100; /* default */
109
110 /* setting these two values to non-zero, we have to manage key repeats */
111 d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
112 d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150;
113
114 input_register_device(&d->rc_input_dev);
115
116 INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
117
118 info("schedule remote query interval to %d msecs.",d->props.rc_interval);
119 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
120
121 d->state |= DVB_USB_STATE_REMOTE;
122
123 return 0;
124}
125
126int dvb_usb_remote_exit(struct dvb_usb_device *d)
127{
128 if (d->state & DVB_USB_STATE_REMOTE) {
129 cancel_delayed_work(&d->rc_query_work);
130 flush_scheduled_work();
131 input_unregister_device(&d->rc_input_dev);
132 }
133 d->state &= ~DVB_USB_STATE_REMOTE;
134 return 0;
135}
136
137#define DVB_USB_RC_NEC_EMPTY 0x00
138#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
139#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
140int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
141 u8 keybuf[5], u32 *event, int *state)
142{
143 int i;
144 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
145 *event = 0;
146 *state = REMOTE_NO_KEY_PRESSED;
147 switch (keybuf[0]) {
148 case DVB_USB_RC_NEC_EMPTY:
149 break;
150 case DVB_USB_RC_NEC_KEY_PRESSED:
151 if ((u8) ~keybuf[1] != keybuf[2] ||
152 (u8) ~keybuf[3] != keybuf[4]) {
153 deb_err("remote control checksum failed.\n");
154 break;
155 }
156 /* See if we can match the raw key code. */
157 for (i = 0; i < sizeof(keymap)/sizeof(struct dvb_usb_rc_key); i++)
158 if (keymap[i].custom == keybuf[1] &&
159 keymap[i].data == keybuf[3]) {
160 *event = keymap[i].event;
161 *state = REMOTE_KEY_PRESSED;
162 break;
163 }
164 deb_err("key mapping failed - no appropriate key found in keymapping\n");
165 break;
166 case DVB_USB_RC_NEC_KEY_REPEATED:
167 *state = REMOTE_KEY_REPEAT;
168 break;
169 default:
170 deb_err("unkown type of remote status: %d\n",keybuf[0]);
171 break;
172 }
173 return 0;
174}
175EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
new file mode 100644
index 000000000000..83d476fb410a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -0,0 +1,211 @@
1/* dvb-usb-urb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing and handling the
7 * USB and URB stuff.
8 */
9#include "dvb-usb-common.h"
10
11int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
12 u16 rlen, int delay_ms)
13{
14 int actlen,ret = -ENOMEM;
15
16 if (d->props.generic_bulk_ctrl_endpoint == 0) {
17 err("endpoint for generic control not specified.");
18 return -EINVAL;
19 }
20
21 if (wbuf == NULL || wlen == 0)
22 return -EINVAL;
23
24 if ((ret = down_interruptible(&d->usb_sem)))
25 return ret;
26
27 debug_dump(wbuf,wlen,deb_xfer);
28
29 ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
30 d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
31 2*HZ);
32
33 if (ret)
34 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
35 else
36 ret = actlen != wlen ? -1 : 0;
37
38 /* an answer is expected, and no error before */
39 if (!ret && rbuf && rlen) {
40 if (delay_ms)
41 msleep(delay_ms);
42
43 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
44 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
45 2*HZ);
46
47 if (ret)
48 err("recv bulk message failed: %d",ret);
49 else
50 debug_dump(rbuf,actlen,deb_xfer);
51 }
52
53 up(&d->usb_sem);
54 return ret;
55}
56EXPORT_SYMBOL(dvb_usb_generic_rw);
57
58int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
59{
60 return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
61}
62EXPORT_SYMBOL(dvb_usb_generic_write);
63
64static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs)
65{
66 struct dvb_usb_device *d = urb->context;
67
68 deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status,
69 urb->actual_length);
70
71 switch (urb->status) {
72 case 0: /* success */
73 case -ETIMEDOUT: /* NAK */
74 break;
75 case -ECONNRESET: /* kill */
76 case -ENOENT:
77 case -ESHUTDOWN:
78 return;
79 default: /* error */
80 deb_ts("urb completition error %d.", urb->status);
81 break;
82 }
83
84 if (d->feedcount > 0 && urb->actual_length > 0) {
85 if (d->state & DVB_USB_STATE_DVB)
86 dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length);
87 } else
88 deb_ts("URB dropped because of feedcount.\n");
89
90 usb_submit_urb(urb,GFP_ATOMIC);
91}
92
93int dvb_usb_urb_kill(struct dvb_usb_device *d)
94{
95 int i;
96 for (i = 0; i < d->urbs_submitted; i++) {
97 deb_info("killing URB no. %d.\n",i);
98
99 /* stop the URB */
100 usb_kill_urb(d->urb_list[i]);
101 }
102 d->urbs_submitted = 0;
103 return 0;
104}
105
106int dvb_usb_urb_submit(struct dvb_usb_device *d)
107{
108 int i,ret;
109 for (i = 0; i < d->urbs_initialized; i++) {
110 deb_info("submitting URB no. %d\n",i);
111 if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
112 err("could not submit URB no. %d - get them all back\n",i);
113 dvb_usb_urb_kill(d);
114 return ret;
115 }
116 d->urbs_submitted++;
117 }
118 return 0;
119}
120
121static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
122{
123 int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize;
124
125 deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
126 /* allocate the actual buffer for the URBs */
127 if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) {
128 deb_info("not enough memory for urb-buffer allocation.\n");
129 return -ENOMEM;
130 }
131 deb_info("allocation successful\n");
132 memset(d->buffer,0,bufsize);
133
134 d->state |= DVB_USB_STATE_URB_BUF;
135
136 /* allocate the URBs */
137 for (i = 0; i < d->props.urb.count; i++) {
138 if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
139 return -ENOMEM;
140 }
141
142 usb_fill_bulk_urb( d->urb_list[i], d->udev,
143 usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
144 &d->buffer[i*d->props.urb.u.bulk.buffersize],
145 d->props.urb.u.bulk.buffersize,
146 dvb_usb_bulk_urb_complete, d);
147
148 d->urb_list[i]->transfer_flags = 0;
149 d->urbs_initialized++;
150 }
151 return 0;
152}
153
154int dvb_usb_urb_init(struct dvb_usb_device *d)
155{
156 /*
157 * when reloading the driver w/o replugging the device
158 * sometimes a timeout occures, this helps
159 */
160 if (d->props.generic_bulk_ctrl_endpoint != 0) {
161 usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
162 usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
163 }
164 usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
165
166 /* allocate the array for the data transfer URBs */
167 d->urb_list = kmalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
168 if (d->urb_list == NULL)
169 return -ENOMEM;
170 memset(d->urb_list,0,d->props.urb.count * sizeof(struct urb *));
171 d->state |= DVB_USB_STATE_URB_LIST;
172
173 switch (d->props.urb.type) {
174 case DVB_USB_BULK:
175 return dvb_usb_bulk_urb_init(d);
176 case DVB_USB_ISOC:
177 err("isochronous transfer not yet implemented in dvb-usb.");
178 return -EINVAL;
179 default:
180 err("unkown URB-type for data transfer.");
181 return -EINVAL;
182 }
183}
184
185int dvb_usb_urb_exit(struct dvb_usb_device *d)
186{
187 int i;
188
189 dvb_usb_urb_kill(d);
190
191 if (d->state & DVB_USB_STATE_URB_LIST) {
192 for (i = 0; i < d->urbs_initialized; i++) {
193 if (d->urb_list[i] != NULL) {
194 deb_info("freeing URB no. %d.\n",i);
195 /* free the URBs */
196 usb_free_urb(d->urb_list[i]);
197 }
198 }
199 d->urbs_initialized = 0;
200 /* free the urb array */
201 kfree(d->urb_list);
202 d->state &= ~DVB_USB_STATE_URB_LIST;
203 }
204
205 if (d->state & DVB_USB_STATE_URB_BUF)
206 usb_buffer_free(d->udev, d->props.urb.u.bulk.buffersize * d->props.urb.count,
207 d->buffer, d->dma_handle);
208
209 d->state &= ~DVB_USB_STATE_URB_BUF;
210 return 0;
211}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
new file mode 100644
index 000000000000..abcee1943f64
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -0,0 +1,315 @@
1/* dvb-usb.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * the headerfile, all dvb-usb-drivers have to include.
7 */
8#ifndef __DVB_USB_H__
9#define __DVB_USB_H__
10
11#include <linux/config.h>
12#include <linux/input.h>
13#include <linux/module.h>
14#include <linux/usb.h>
15
16#include "dvb_frontend.h"
17#include "dvb_demux.h"
18#include "dvb_net.h"
19#include "dmxdev.h"
20
21#include "dvb-pll.h"
22
23#include "dvb-usb-ids.h"
24
25/* debug */
26#ifdef CONFIG_DVB_USB_DEBUG
27#define dprintk(var,level,args...) \
28 do { if ((var & level)) { printk(args); } } while (0)
29
30#define debug_dump(b,l,func) {\
31 int loop_; \
32 for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
33 func("\n");\
34}
35#define DVB_USB_DEBUG_STATUS
36#else
37#define dprintk(args...)
38#define debug_dump(b,l,func)
39
40#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
41
42#endif
43
44/* generic log methods - taken from usb.h */
45#ifndef DVB_USB_LOG_PREFIX
46 #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
47#endif
48
49#undef err
50#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
51#undef info
52#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
53#undef warn
54#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
55
56/**
57 * struct dvb_usb_device_description - name and its according USB IDs
58 * @name: real name of the box, regardless which DVB USB device class is in use
59 * @cold_ids: array of struct usb_device_id which describe the device in
60 * pre-firmware state
61 * @warm_ids: array of struct usb_device_id which describe the device in
62 * post-firmware state
63 *
64 * Each DVB USB device class can have one or more actual devices, this struct
65 * assigns a name to it.
66 */
67struct dvb_usb_device_description {
68 const char *name;
69
70#define DVB_USB_ID_MAX_NUM 15
71 struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
72 struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
73};
74
75/**
76 * struct dvb_usb_rc_key - a remote control key and its input-event
77 * @custom: the vendor/custom part of the key
78 * @data: the actual key part
79 * @event: the input event assigned to key identified by custom and data
80 */
81struct dvb_usb_rc_key {
82 u8 custom,data;
83 u32 event;
84};
85
86struct dvb_usb_device;
87
88/**
89 * struct dvb_usb_properties - properties of a dvb-usb-device
90 * @caps: capabilites of the DVB USB device.
91 * @pid_filter_count: number of PID filter position in the optional hardware
92 * PID-filter.
93 *
94 * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
95 * download.
96 * @firmware: name of the firmware file.
97 *
98 * @size_of_priv: how many bytes shall be allocated for the private field
99 * of struct dvb_usb_device.
100 *
101 * @power_ctrl: called to enable/disable power of the device.
102 * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
103 * device (not URB submitting/killing).
104 * @pid_filter_ctrl: called to en/disable the PID filter, if any.
105 * @pid_filter: called to set/unset a PID for filtering.
106 *
107 * @read_mac_address: called to read the MAC address of the device.
108 *
109 * @frontend_attach: called to attach the possible frontends (fill fe-field
110 * of struct dvb_usb_device).
111 * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
112 * pll_desc and pll_init_buf of struct dvb_usb_device).
113 * @identify_state: called to determine the state (cold or warm), when it
114 * is not distinguishable by the USB IDs.
115 *
116 * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable
117 * remote control handling).
118 * @rc_key_map_size: number of items in @rc_key_map.
119 * @rc_query: called to query an event event.
120 * @rc_interval: time in ms between two queries.
121 *
122 * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
123 *
124 * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
125 * endpoint which received control messages with bulk transfers. When this
126 * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
127 * helper functions.
128 *
129 * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
130 * Currently only BULK is implemented
131 *
132 * @num_device_descs: number of struct dvb_usb_device_description in @devices
133 * @devices: array of struct dvb_usb_device_description compatibles with these
134 * properties.
135 */
136struct dvb_usb_properties {
137
138#define DVB_USB_HAS_PID_FILTER 0x01
139#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02
140#define DVB_USB_NEED_PID_FILTERING 0x04
141#define DVB_USB_IS_AN_I2C_ADAPTER 0x08
142 int caps;
143 int pid_filter_count;
144
145#define CYPRESS_AN2135 0
146#define CYPRESS_AN2235 1
147#define CYPRESS_FX2 2
148 int usb_ctrl;
149 const char *firmware;
150
151 int size_of_priv;
152
153 int (*power_ctrl) (struct dvb_usb_device *, int);
154 int (*streaming_ctrl) (struct dvb_usb_device *, int);
155 int (*pid_filter_ctrl) (struct dvb_usb_device *, int);
156 int (*pid_filter) (struct dvb_usb_device *, int, u16, int);
157
158 int (*read_mac_address) (struct dvb_usb_device *, u8 []);
159 int (*frontend_attach) (struct dvb_usb_device *);
160 int (*tuner_attach) (struct dvb_usb_device *);
161
162 int (*identify_state) (struct usb_device *, struct dvb_usb_properties *,
163 struct dvb_usb_device_description **, int *);
164
165/* remote control properties */
166#define REMOTE_NO_KEY_PRESSED 0x00
167#define REMOTE_KEY_PRESSED 0x01
168#define REMOTE_KEY_REPEAT 0x02
169 struct dvb_usb_rc_key *rc_key_map;
170 int rc_key_map_size;
171 int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
172 int rc_interval;
173
174 struct i2c_algorithm *i2c_algo;
175
176 int generic_bulk_ctrl_endpoint;
177
178 struct {
179#define DVB_USB_BULK 1
180#define DVB_USB_ISOC 2
181 int type;
182 int count;
183 int endpoint;
184
185 union {
186 struct {
187 int buffersize; /* per URB */
188 } bulk;
189 struct {
190 int framesperurb;
191 int framesize;
192 } isoc;
193 } u;
194 } urb;
195
196 int num_device_descs;
197 struct dvb_usb_device_description devices[8];
198};
199
200
201/**
202 * struct dvb_usb_device - object of a DVB USB device
203 * @props: copy of the struct dvb_usb_properties this device belongs to.
204 * @desc: pointer to the device's struct dvb_usb_device_description.
205 * @state: initialization and runtime state of the device.
206 *
207 * @udev: pointer to the device's struct usb_device.
208 * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
209 * streaming.
210 * @buffer: buffer used to streaming.
211 * @dma_handle: dma_addr_t for buffer.
212 * @urbs_initialized: number of URBs initialized.
213 * @urbs_submitted: number of URBs submitted.
214 * @feedcount: number of reqested feeds (used for streaming-activation)
215 * @pid_filtering: is hardware pid_filtering used or not.
216 * @usb_sem: semaphore of USB control messages (reading needs two messages)
217 * @i2c_sem: semaphore for i2c-transfers
218 * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
219 * @pll_addr: I2C address of the tuner for programming
220 * @pll_init: array containing the initialization buffer
221 * @pll_desc: pointer to the appropriate struct dvb_pll_desc
222 * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod
223 * @dvb_adap: device's dvb_adapter.
224 * @dmxdev: device's dmxdev.
225 * @demux: device's software demuxer.
226 * @dvb_net: device's dvb_net interfaces.
227 * @dvb_frontend: device's frontend.
228 * @max_feed_count: how many feeds can be handled simultaneously by this
229 * device
230 * @fe_sleep: rerouted frontend-sleep function.
231 * @fe_init: rerouted frontend-init (wakeup) function.
232 * @rc_input_dev: input device for the remote control.
233 * @rc_query_work: struct work_struct frequent rc queries
234 * @last_event: last triggered event
235 * @last_state: last state (no, pressed, repeat)
236 * @owner: owner of the dvb_adapter
237 * @priv: private data of the actual driver (allocate by dvb-usb, size defined
238 * in size_of_priv of dvb_usb_properties).
239 */
240struct dvb_usb_device {
241 struct dvb_usb_properties props;
242 struct dvb_usb_device_description *desc;
243
244#define DVB_USB_STATE_INIT 0x000
245#define DVB_USB_STATE_URB_LIST 0x001
246#define DVB_USB_STATE_URB_BUF 0x002
247#define DVB_USB_STATE_DVB 0x004
248#define DVB_USB_STATE_I2C 0x008
249#define DVB_USB_STATE_REMOTE 0x010
250#define DVB_USB_STATE_URB_SUBMIT 0x020
251 int state;
252
253 /* usb */
254 struct usb_device *udev;
255 struct urb **urb_list;
256 u8 *buffer;
257 dma_addr_t dma_handle;
258 int urbs_initialized;
259 int urbs_submitted;
260
261 int feedcount;
262 int pid_filtering;
263
264 /* locking */
265 struct semaphore usb_sem;
266
267 /* i2c */
268 struct semaphore i2c_sem;
269 struct i2c_adapter i2c_adap;
270
271 /* tuner programming information */
272 u8 pll_addr;
273 u8 pll_init[4];
274 struct dvb_pll_desc *pll_desc;
275 int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8);
276
277 /* dvb */
278 struct dvb_adapter dvb_adap;
279 struct dmxdev dmxdev;
280 struct dvb_demux demux;
281 struct dvb_net dvb_net;
282 struct dvb_frontend* fe;
283 int max_feed_count;
284
285 int (*fe_sleep) (struct dvb_frontend *);
286 int (*fe_init) (struct dvb_frontend *);
287
288 /* remote control */
289 struct input_dev rc_input_dev;
290 struct work_struct rc_query_work;
291 u32 last_event;
292 int last_state;
293
294 struct module *owner;
295
296 void *priv;
297};
298
299extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *);
300extern void dvb_usb_device_exit(struct usb_interface *);
301
302/* the generic read/write method for device control */
303extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
304extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
305
306/* commonly used remote control parsing */
307extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
308
309/* commonly used pll init and set functions */
310extern int dvb_usb_pll_init_i2c(struct dvb_frontend *);
311extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]);
312extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
313
314
315#endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
new file mode 100644
index 000000000000..9d83781aef95
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -0,0 +1,236 @@
1/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14static int debug;
15module_param(debug, int, 0644);
16MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
17
18#define deb_rc(args...) dprintk(debug,0x01,args)
19#define deb_ee(args...) dprintk(debug,0x02,args)
20
21/* Hauppauge NOVA-T USB2 keys */
22static struct dvb_usb_rc_key haupp_rc_keys [] = {
23 { 0x1e, 0x00, KEY_0 },
24 { 0x1e, 0x01, KEY_1 },
25 { 0x1e, 0x02, KEY_2 },
26 { 0x1e, 0x03, KEY_3 },
27 { 0x1e, 0x04, KEY_4 },
28 { 0x1e, 0x05, KEY_5 },
29 { 0x1e, 0x06, KEY_6 },
30 { 0x1e, 0x07, KEY_7 },
31 { 0x1e, 0x08, KEY_8 },
32 { 0x1e, 0x09, KEY_9 },
33 { 0x1e, 0x0a, KEY_KPASTERISK },
34 { 0x1e, 0x0b, KEY_RED },
35 { 0x1e, 0x0c, KEY_RADIO },
36 { 0x1e, 0x0d, KEY_MENU },
37 { 0x1e, 0x0e, KEY_GRAVE }, /* # */
38 { 0x1e, 0x0f, KEY_MUTE },
39 { 0x1e, 0x10, KEY_VOLUMEUP },
40 { 0x1e, 0x11, KEY_VOLUMEDOWN },
41 { 0x1e, 0x12, KEY_CHANNEL },
42 { 0x1e, 0x14, KEY_UP },
43 { 0x1e, 0x15, KEY_DOWN },
44 { 0x1e, 0x16, KEY_LEFT },
45 { 0x1e, 0x17, KEY_RIGHT },
46 { 0x1e, 0x18, KEY_VIDEO },
47 { 0x1e, 0x19, KEY_AUDIO },
48 { 0x1e, 0x1a, KEY_MEDIA },
49 { 0x1e, 0x1b, KEY_EPG },
50 { 0x1e, 0x1c, KEY_TV },
51 { 0x1e, 0x1e, KEY_NEXT },
52 { 0x1e, 0x1f, KEY_BACK },
53 { 0x1e, 0x20, KEY_CHANNELUP },
54 { 0x1e, 0x21, KEY_CHANNELDOWN },
55 { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
56 { 0x1e, 0x25, KEY_OK },
57 { 0x1e, 0x29, KEY_BLUE},
58 { 0x1e, 0x2e, KEY_GREEN },
59 { 0x1e, 0x30, KEY_PAUSE },
60 { 0x1e, 0x32, KEY_REWIND },
61 { 0x1e, 0x34, KEY_FASTFORWARD },
62 { 0x1e, 0x35, KEY_PLAY },
63 { 0x1e, 0x36, KEY_STOP },
64 { 0x1e, 0x37, KEY_RECORD },
65 { 0x1e, 0x38, KEY_YELLOW },
66 { 0x1e, 0x3b, KEY_GOTO },
67 { 0x1e, 0x3d, KEY_POWER },
68};
69
70/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
71 * is delivered. No workaround yet, maybe a new firmware.
72 */
73static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
74{
75 u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
76 u16 raw;
77 int i;
78 struct dibusb_state *st = d->priv;
79
80 dvb_usb_generic_rw(d,cmd,2,key,5,0);
81
82 *state = REMOTE_NO_KEY_PRESSED;
83 switch (key[0]) {
84 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
85 raw = ((key[1] << 8) | key[2]) >> 3;
86 toggle = !!(raw & 0x800);
87 data = raw & 0x3f;
88 custom = (raw >> 6) & 0x1f;
89
90 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
91
92 for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
93 deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
94 if (haupp_rc_keys[i].data == data &&
95 haupp_rc_keys[i].custom == custom) {
96 *event = haupp_rc_keys[i].event;
97 *state = REMOTE_KEY_PRESSED;
98 if (st->old_toggle == toggle) {
99 if (st->last_repeat_count++ < 2)
100 *state = REMOTE_NO_KEY_PRESSED;
101 } else {
102 st->last_repeat_count = 0;
103 st->old_toggle = toggle;
104 }
105 break;
106 }
107 }
108
109 break;
110 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
111 default:
112 break;
113 }
114
115 return 0;
116}
117
118static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
119{
120 int i;
121 u8 b;
122
123 mac[0] = 0x00;
124 mac[1] = 0x0d;
125 mac[2] = 0xfe;
126
127 /* this is a complete guess, but works for my box */
128 for (i = 136; i < 139; i++) {
129 dibusb_read_eeprom_byte(d,i, &b);
130
131 mac[5 - (i - 136)] = b;
132
133/* deb_ee("%02x ",b);
134 if ((i+1) % 16 == 0)
135 deb_ee("\n");*/
136 }
137
138 return 0;
139}
140
141/* USB Driver stuff */
142static struct dvb_usb_properties nova_t_properties;
143
144static int nova_t_probe(struct usb_interface *intf,
145 const struct usb_device_id *id)
146{
147 return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE);
148}
149
150/* do not change the order of the ID table */
151static struct usb_device_id nova_t_table [] = {
152/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
153/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
154 { } /* Terminating entry */
155};
156MODULE_DEVICE_TABLE (usb, nova_t_table);
157
158static struct dvb_usb_properties nova_t_properties = {
159 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
160 .pid_filter_count = 32,
161
162 .usb_ctrl = CYPRESS_FX2,
163 .firmware = "dvb-usb-nova-t-usb2-01.fw",
164
165 .size_of_priv = sizeof(struct dibusb_state),
166
167 .streaming_ctrl = dibusb2_0_streaming_ctrl,
168 .pid_filter = dibusb_pid_filter,
169 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
170 .power_ctrl = dibusb2_0_power_ctrl,
171 .frontend_attach = dibusb_dib3000mc_frontend_attach,
172 .tuner_attach = dibusb_dib3000mc_tuner_attach,
173 .read_mac_address = nova_t_read_mac_address,
174
175 .rc_interval = 100,
176 .rc_key_map = haupp_rc_keys,
177 .rc_key_map_size = ARRAY_SIZE(haupp_rc_keys),
178 .rc_query = nova_t_rc_query,
179
180 .i2c_algo = &dibusb_i2c_algo,
181
182 .generic_bulk_ctrl_endpoint = 0x01,
183 /* parameter for the MPEG2-data transfer */
184 .urb = {
185 .type = DVB_USB_BULK,
186 .count = 7,
187 .endpoint = 0x06,
188 .u = {
189 .bulk = {
190 .buffersize = 4096,
191 }
192 }
193 },
194
195 .num_device_descs = 1,
196 .devices = {
197 { "Hauppauge WinTV-NOVA-T usb2",
198 { &nova_t_table[0], NULL },
199 { &nova_t_table[1], NULL },
200 },
201 }
202};
203
204static struct usb_driver nova_t_driver = {
205 .owner = THIS_MODULE,
206 .name = "Hauppauge WinTV-NOVA-T usb2",
207 .probe = nova_t_probe,
208 .disconnect = dvb_usb_device_exit,
209 .id_table = nova_t_table,
210};
211
212/* module stuff */
213static int __init nova_t_module_init(void)
214{
215 int result;
216 if ((result = usb_register(&nova_t_driver))) {
217 err("usb_register failed. Error number %d",result);
218 return result;
219 }
220
221 return 0;
222}
223
224static void __exit nova_t_module_exit(void)
225{
226 /* deregister this driver from the USB subsystem */
227 usb_deregister(&nova_t_driver);
228}
229
230module_init (nova_t_module_init);
231module_exit (nova_t_module_exit);
232
233MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
234MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
235MODULE_VERSION("1.0");
236MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
new file mode 100644
index 000000000000..aa560422ce7c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -0,0 +1,162 @@
1/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14#include "mt352.h"
15
16static int umt_mt352_demod_init(struct dvb_frontend *fe)
17{
18 static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
19 static u8 mt352_reset[] = { 0x50, 0x80 };
20 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
21 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
22 static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
23
24 static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
25 static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
26 static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
27 static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
28 static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
29
30 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
31 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
32
33 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
34 udelay(2000);
35 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
36 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
37
38 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
39 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
40
41 mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
42 mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
43 mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
44 mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
45 mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
46
47 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
48 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
49
50 return 0;
51}
52
53static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
54{
55 struct mt352_config umt_config;
56
57 memset(&umt_config,0,sizeof(struct mt352_config));
58 umt_config.demod_init = umt_mt352_demod_init;
59 umt_config.demod_address = 0xf;
60 umt_config.pll_set = dvb_usb_pll_set;
61
62 d->fe = mt352_attach(&umt_config, &d->i2c_adap);
63
64 return 0;
65}
66
67static int umt_tuner_attach (struct dvb_usb_device *d)
68{
69 d->pll_addr = 0x61;
70 d->pll_desc = &dvb_pll_tua6034;
71 return 0;
72}
73
74/* USB Driver stuff */
75static struct dvb_usb_properties umt_properties;
76
77static int umt_probe(struct usb_interface *intf,
78 const struct usb_device_id *id)
79{
80 if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0)
81 return 0;
82 return -EINVAL;
83}
84
85/* do not change the order of the ID table */
86static struct usb_device_id umt_table [] = {
87/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
88/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
89 { } /* Terminating entry */
90};
91MODULE_DEVICE_TABLE (usb, umt_table);
92
93static struct dvb_usb_properties umt_properties = {
94 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
95
96 .usb_ctrl = CYPRESS_FX2,
97 .firmware = "dvb-usb-umt-010-02.fw",
98
99 .size_of_priv = sizeof(struct dibusb_state),
100
101 .streaming_ctrl = dibusb2_0_streaming_ctrl,
102 .power_ctrl = dibusb_power_ctrl,
103 .frontend_attach = umt_mt352_frontend_attach,
104 .tuner_attach = umt_tuner_attach,
105
106 .i2c_algo = &dibusb_i2c_algo,
107
108 .generic_bulk_ctrl_endpoint = 0x01,
109 /* parameter for the MPEG2-data transfer */
110 .urb = {
111 .type = DVB_USB_BULK,
112 .count = 20,
113 .endpoint = 0x06,
114 .u = {
115 .bulk = {
116 .buffersize = 512,
117 }
118 }
119 },
120
121 .num_device_descs = 1,
122 .devices = {
123 { "Hanftek UMT-010 DVB-T USB2.0",
124 { &umt_table[0], NULL },
125 { &umt_table[1], NULL },
126 },
127 }
128};
129
130static struct usb_driver umt_driver = {
131 .owner = THIS_MODULE,
132 .name = "HanfTek UMT-010 USB2.0 DVB-T devices",
133 .probe = umt_probe,
134 .disconnect = dvb_usb_device_exit,
135 .id_table = umt_table,
136};
137
138/* module stuff */
139static int __init umt_module_init(void)
140{
141 int result;
142 if ((result = usb_register(&umt_driver))) {
143 err("usb_register failed. Error number %d",result);
144 return result;
145 }
146
147 return 0;
148}
149
150static void __exit umt_module_exit(void)
151{
152 /* deregister this driver from the USB subsystem */
153 usb_deregister(&umt_driver);
154}
155
156module_init (umt_module_init);
157module_exit (umt_module_exit);
158
159MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
160MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
161MODULE_VERSION("1.0");
162MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
new file mode 100644
index 000000000000..2746edfeccba
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -0,0 +1,196 @@
1/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 *
14 */
15#include "vp7045.h"
16
17/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
18 *
19 * Programming is hidden inside the firmware, so set_frontend is very easy.
20 * Even though there is a Firmware command that one can use to access the demod
21 * via its registers. This is used for status information.
22 */
23
24struct vp7045_fe_state {
25 struct dvb_frontend fe;
26 struct dvb_usb_device *d;
27};
28
29
30static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
31{
32 struct vp7045_fe_state *state = fe->demodulator_priv;
33 u8 s0 = vp7045_read_reg(state->d,0x00),
34 s1 = vp7045_read_reg(state->d,0x01),
35 s3 = vp7045_read_reg(state->d,0x03);
36
37 *status = 0;
38 if (s0 & (1 << 4))
39 *status |= FE_HAS_CARRIER;
40 if (s0 & (1 << 1))
41 *status |= FE_HAS_VITERBI;
42 if (s0 & (1 << 5))
43 *status |= FE_HAS_LOCK;
44 if (s1 & (1 << 1))
45 *status |= FE_HAS_SYNC;
46 if (s3 & (1 << 6))
47 *status |= FE_HAS_SIGNAL;
48
49 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
50 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
51 *status &= ~FE_HAS_LOCK;
52
53 return 0;
54}
55
56static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
57{
58 struct vp7045_fe_state *state = fe->demodulator_priv;
59 *ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
60 (vp7045_read_reg(state->d, 0x0E) << 8) |
61 vp7045_read_reg(state->d, 0x0F);
62 return 0;
63}
64
65static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
66{
67 struct vp7045_fe_state *state = fe->demodulator_priv;
68 *unc = (vp7045_read_reg(state->d, 0x10) << 8) |
69 vp7045_read_reg(state->d, 0x11);
70 return 0;
71}
72
73static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
74{
75 struct vp7045_fe_state *state = fe->demodulator_priv;
76 u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
77 vp7045_read_reg(state->d, 0x15);
78
79 *strength = ~signal;
80 return 0;
81}
82
83static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
84{
85 struct vp7045_fe_state *state = fe->demodulator_priv;
86 u8 _snr = vp7045_read_reg(state->d, 0x09);
87 *snr = (_snr << 8) | _snr;
88 return 0;
89}
90
91static int vp7045_fe_init(struct dvb_frontend* fe)
92{
93 return 0;
94}
95
96static int vp7045_fe_sleep(struct dvb_frontend* fe)
97{
98 return 0;
99}
100
101static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
102{
103 tune->min_delay_ms = 800;
104 return 0;
105}
106
107static int vp7045_fe_set_frontend(struct dvb_frontend* fe,
108 struct dvb_frontend_parameters *fep)
109{
110 struct vp7045_fe_state *state = fe->demodulator_priv;
111 u8 buf[5];
112 u32 freq = fep->frequency / 1000;
113
114 buf[0] = (freq >> 16) & 0xff;
115 buf[1] = (freq >> 8) & 0xff;
116 buf[2] = freq & 0xff;
117 buf[3] = 0;
118
119 switch (fep->u.ofdm.bandwidth) {
120 case BANDWIDTH_8_MHZ: buf[4] = 8; break;
121 case BANDWIDTH_7_MHZ: buf[4] = 7; break;
122 case BANDWIDTH_6_MHZ: buf[4] = 6; break;
123 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
124 default:
125 return -EINVAL;
126 }
127
128 vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
129 return 0;
130}
131
132static int vp7045_fe_get_frontend(struct dvb_frontend* fe,
133 struct dvb_frontend_parameters *fep)
134{
135 return 0;
136}
137
138static void vp7045_fe_release(struct dvb_frontend* fe)
139{
140 struct vp7045_fe_state *state = fe->demodulator_priv;
141 kfree(state);
142}
143
144static struct dvb_frontend_ops vp7045_fe_ops;
145
146struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
147{
148 struct vp7045_fe_state *s = kmalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
149 if (s == NULL)
150 goto error;
151 memset(s,0,sizeof(struct vp7045_fe_state));
152
153 s->d = d;
154 s->fe.ops = &vp7045_fe_ops;
155 s->fe.demodulator_priv = s;
156
157 goto success;
158error:
159 return NULL;
160success:
161 return &s->fe;
162}
163
164
165static struct dvb_frontend_ops vp7045_fe_ops = {
166 .info = {
167 .name = "Twinhan VP7045/46 USB DVB-T",
168 .type = FE_OFDM,
169 .frequency_min = 44250000,
170 .frequency_max = 867250000,
171 .frequency_stepsize = 1000,
172 .caps = FE_CAN_INVERSION_AUTO |
173 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
174 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
175 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
176 FE_CAN_TRANSMISSION_MODE_AUTO |
177 FE_CAN_GUARD_INTERVAL_AUTO |
178 FE_CAN_RECOVER |
179 FE_CAN_HIERARCHY_AUTO,
180 },
181
182 .release = vp7045_fe_release,
183
184 .init = vp7045_fe_init,
185 .sleep = vp7045_fe_sleep,
186
187 .set_frontend = vp7045_fe_set_frontend,
188 .get_frontend = vp7045_fe_get_frontend,
189 .get_tune_settings = vp7045_fe_get_tune_settings,
190
191 .read_status = vp7045_fe_read_status,
192 .read_ber = vp7045_fe_read_ber,
193 .read_signal_strength = vp7045_fe_read_signal_strength,
194 .read_snr = vp7045_fe_read_snr,
195 .read_ucblocks = vp7045_fe_read_unc_blocks,
196};
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
new file mode 100644
index 000000000000..02ecc9a8e3b6
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -0,0 +1,263 @@
1/* DVB USB compliant Linux driver for the
2 * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
3 * - DigitalNow TinyUSB2 DVB-t receiver
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * Thanks to Twinhan who kindly provided hardware and information.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "vp7045.h"
16
17/* debug */
18int dvb_usb_vp7045_debug;
19module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
21
22int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
23{
24 int ret = 0;
25 u8 inbuf[12] = { 0 }, outbuf[20] = { 0 };
26
27 outbuf[0] = cmd;
28
29 if (outlen > 19)
30 outlen = 19;
31
32 if (inlen > 11)
33 inlen = 11;
34
35 if (out != NULL && outlen > 0)
36 memcpy(&outbuf[1], out, outlen);
37
38 deb_xfer("out buffer: ");
39 debug_dump(outbuf,outlen+1,deb_xfer);
40
41 if ((ret = down_interruptible(&d->usb_sem)))
42 return ret;
43
44 if (usb_control_msg(d->udev,
45 usb_sndctrlpipe(d->udev,0),
46 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
47 outbuf, 20, 2*HZ) != 20) {
48 err("USB control message 'out' went wrong.");
49 ret = -EIO;
50 goto unlock;
51 }
52
53 msleep(msec);
54
55 if (usb_control_msg(d->udev,
56 usb_rcvctrlpipe(d->udev,0),
57 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
58 inbuf, 12, 2*HZ) != 12) {
59 err("USB control message 'in' went wrong.");
60 ret = -EIO;
61 goto unlock;
62 }
63
64 deb_xfer("in buffer: ");
65 debug_dump(inbuf,12,deb_xfer);
66
67 if (in != NULL && inlen > 0)
68 memcpy(in,&inbuf[1],inlen);
69
70unlock:
71 up(&d->usb_sem);
72
73 return ret;
74}
75
76u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
77{
78 u8 obuf[2] = { 0 },v;
79 obuf[1] = reg;
80
81 vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
82
83 return v;
84}
85
86static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
87{
88 u8 v = onoff;
89 return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
90}
91
92/* remote control stuff */
93
94/* The keymapping struct. Somehow this should be loaded to the driver, but
95 * currently it is hardcoded. */
96static struct dvb_usb_rc_key vp7045_rc_keys[] = {
97 /* insert the keys like this. to make the raw keys visible, enable
98 * debug=0x04 when loading dvb-usb-vp7045. */
99
100 /* these keys are probably wrong. I don't have a working IR-receiver on my
101 * vp7045, so I can't test it. Patches are welcome. */
102 { 0x00, 0x01, KEY_1 },
103 { 0x00, 0x02, KEY_2 },
104};
105
106static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state)
107{
108 u8 key;
109 int i;
110 vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
111
112 deb_rc("remote query key: %x %d\n",key,key);
113
114 if (key == 0x44) {
115 *state = REMOTE_NO_KEY_PRESSED;
116 return 0;
117 }
118
119 for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++)
120 if (vp7045_rc_keys[i].data == key) {
121 *state = REMOTE_KEY_PRESSED;
122 *key_buf = vp7045_rc_keys[i].event;
123 break;
124 }
125 return 0;
126}
127
128static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
129{
130 int i = 0;
131 u8 v,br[2];
132 for (i=0; i < len; i++) {
133 v = offset + i;
134 vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
135 buf[i] = br[1];
136 }
137 deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
138 debug_dump(buf,i,deb_info);
139 return 0;
140}
141
142
143static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
144{
145 return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
146}
147
148static int vp7045_frontend_attach(struct dvb_usb_device *d)
149{
150 u8 buf[255] = { 0 };
151
152 vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0);
153 buf[10] = '\0';
154 deb_info("firmware says: %s ",buf);
155
156 vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0);
157 buf[10] = '\0';
158 deb_info("%s ",buf);
159
160 vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0);
161 buf[10] = '\0';
162 deb_info("v%s\n",buf);
163
164/* Dump the EEPROM */
165/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
166
167 d->fe = vp7045_fe_attach(d);
168
169 return 0;
170}
171
172static struct dvb_usb_properties vp7045_properties;
173
174static int vp7045_usb_probe(struct usb_interface *intf,
175 const struct usb_device_id *id)
176{
177 return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE);
178}
179
180static struct usb_device_id vp7045_usb_table [] = {
181 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
182 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
183 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
184 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
185 { 0 },
186};
187MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
188
189static struct dvb_usb_properties vp7045_properties = {
190 .caps = 0,
191
192 .usb_ctrl = CYPRESS_FX2,
193 .firmware = "dvb-usb-vp7045-01.fw",
194
195 .power_ctrl = vp7045_power_ctrl,
196 .frontend_attach = vp7045_frontend_attach,
197 .read_mac_address = vp7045_read_mac_addr,
198
199 .rc_interval = 400,
200 .rc_key_map = vp7045_rc_keys,
201 .rc_key_map_size = ARRAY_SIZE(vp7045_rc_keys),
202 .rc_query = vp7045_rc_query,
203
204 /* parameter for the MPEG2-data transfer */
205 .urb = {
206 .type = DVB_USB_BULK,
207 .count = 7,
208 .endpoint = 0x02,
209 .u = {
210 .bulk = {
211 .buffersize = 4096,
212 }
213 }
214 },
215
216 .num_device_descs = 2,
217 .devices = {
218 { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
219 .cold_ids = { &vp7045_usb_table[0], NULL },
220 .warm_ids = { &vp7045_usb_table[1], NULL },
221 },
222 { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
223 .cold_ids = { &vp7045_usb_table[2], NULL },
224 .warm_ids = { &vp7045_usb_table[3], NULL },
225 },
226 { 0 },
227 }
228};
229
230/* usb specific object needed to register this driver with the usb subsystem */
231static struct usb_driver vp7045_usb_driver = {
232 .owner = THIS_MODULE,
233 .name = "dvb-usb-vp7045",
234 .probe = vp7045_usb_probe,
235 .disconnect = dvb_usb_device_exit,
236 .id_table = vp7045_usb_table,
237};
238
239/* module stuff */
240static int __init vp7045_usb_module_init(void)
241{
242 int result;
243 if ((result = usb_register(&vp7045_usb_driver))) {
244 err("usb_register failed. (%d)",result);
245 return result;
246 }
247
248 return 0;
249}
250
251static void __exit vp7045_usb_module_exit(void)
252{
253 /* deregister this driver from the USB subsystem */
254 usb_deregister(&vp7045_usb_driver);
255}
256
257module_init(vp7045_usb_module_init);
258module_exit(vp7045_usb_module_exit);
259
260MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
261MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
262MODULE_VERSION("1.0");
263MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h
new file mode 100644
index 000000000000..9ce21a20fa86
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.h
@@ -0,0 +1,78 @@
1/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
2 * USB2.0 DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#ifndef _DVB_USB_VP7045_H_
15#define _DVB_USB_VP7045_H_
16
17#define DVB_USB_LOG_PREFIX "vp7045"
18#include "dvb-usb.h"
19
20extern int dvb_usb_vp7045_debug;
21#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
22#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
23#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
24
25/* vp7045 commands */
26
27/* Twinhan Vendor requests */
28#define TH_COMMAND_IN 0xC0
29#define TH_COMMAND_OUT 0xC1
30
31/* command bytes */
32#define TUNER_REG_READ 0x03
33#define TUNER_REG_WRITE 0x04
34
35#define RC_VAL_READ 0x05
36 #define RC_NO_KEY 0x44
37
38#define SET_TUNER_POWER 0x06
39#define CHECK_TUNER_POWER 0x12
40 #define Tuner_Power_ON 1
41 #define Tuner_Power_OFF 0
42
43#define GET_USB_SPEED 0x07
44 #define USB_SPEED_LOW 0
45 #define USB_SPEED_FULL 1
46 #define USB_SPEED_HIGH 2
47
48#define LOCK_TUNER_COMMAND 0x09
49
50#define TUNER_SIGNAL_READ 0x0A
51
52/* FX2 eeprom */
53#define SET_EE_VALUE 0x10
54#define GET_EE_VALUE 0x11
55 #define FX2_ID_ADDR 0x00
56 #define VID_MSB_ADDR 0x02
57 #define VID_LSB_ADDR 0x01
58 #define PID_MSB_ADDR 0x04
59 #define PID_LSB_ADDR 0x03
60 #define MAC_0_ADDR 0x07
61 #define MAC_1_ADDR 0x08
62 #define MAC_2_ADDR 0x09
63 #define MAC_3_ADDR 0x0a
64 #define MAC_4_ADDR 0x0b
65 #define MAC_5_ADDR 0x0c
66
67#define RESET_FX2 0x13
68
69#define FW_VERSION_READ 0x0B
70#define VENDOR_STRING_READ 0x0C
71#define PRODUCT_STRING_READ 0x0D
72#define FW_BCD_VERSION_READ 0x14
73
74extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
75extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
76extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
77
78#endif
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 75fb556ec01f..b4fddf513ebe 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -173,4 +173,12 @@ config DVB_OR51132
173 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 173 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
174 to support this frontend. 174 to support this frontend.
175 175
176config DVB_BCM3510
177 tristate "Broadcom BCM3510"
178 depends on DVB_CORE
179 select FW_LOADER
180 help
181 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
182 support this frontend.
183
176endmenu 184endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 7f8784870eab..91d6d3576d3d 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o 28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o 29obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o 30obj-$(CONFIG_DVB_OR51132) += or51132.o
31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
new file mode 100644
index 000000000000..f5fdc5c3e605
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -0,0 +1,853 @@
1/*
2 * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
3 *
4 * Copyright (C) 2001-5, B2C2 inc.
5 *
6 * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
7 *
8 * This driver is "hard-coded" to be used with the 1st generation of
9 * Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
10 * (Panasonic CT10S) is located here, which is actually wrong. Unless there is
11 * another device with a BCM3510, this is no problem.
12 *
13 * The driver works also with QAM64 DVB-C, but had an unreasonable high
14 * UNC. (Tested with the Air2PC ATSC 1st generation)
15 *
16 * You'll need a firmware for this driver in order to get it running. It is
17 * called "dvb-fe-bcm3510-01.fw".
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the Free
21 * Software Foundation; either version 2 of the License, or (at your option)
22 * any later version.
23 *
24 * This program is distributed in the hope that it will be useful, but WITHOUT
25 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
27 * more details.
28 *
29 * You should have received a copy of the GNU General Public License along with
30 * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
31 * Ave, Cambridge, MA 02139, USA.
32 */
33
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/device.h>
38#include <linux/firmware.h>
39
40#include "dvb_frontend.h"
41#include "bcm3510.h"
42#include "bcm3510_priv.h"
43
44struct bcm3510_state {
45
46 struct i2c_adapter* i2c;
47 struct dvb_frontend_ops ops;
48 const struct bcm3510_config* config;
49 struct dvb_frontend frontend;
50
51 /* demodulator private data */
52 struct semaphore hab_sem;
53 u8 firmware_loaded:1;
54
55 unsigned long next_status_check;
56 unsigned long status_check_interval;
57 struct bcm3510_hab_cmd_status1 status1;
58 struct bcm3510_hab_cmd_status2 status2;
59};
60
61static int debug;
62module_param(debug, int, 0644);
63MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
64
65#define dprintk(level,x...) if (level & debug) printk(x)
66#define dbufout(b,l,m) {\
67 int i; \
68 for (i = 0; i < l; i++) \
69 m("%02x ",b[i]); \
70}
71#define deb_info(args...) dprintk(0x01,args)
72#define deb_i2c(args...) dprintk(0x02,args)
73#define deb_hab(args...) dprintk(0x04,args)
74
75/* transfer functions */
76static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
77{
78 u8 b[256];
79 int err;
80 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
81
82 b[0] = reg;
83 memcpy(&b[1],buf,len);
84
85 deb_i2c("i2c wr %02x: ",reg);
86 dbufout(buf,len,deb_i2c);
87 deb_i2c("\n");
88
89 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
90
91 deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
92 __FUNCTION__, state->config->demod_address, reg, err);
93 return -EREMOTEIO;
94 }
95
96 return 0;
97}
98
99static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
100{
101 struct i2c_msg msg[] = {
102 { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
103 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len }
104 };
105 int err;
106
107 memset(buf,0,len);
108
109 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
110 deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
111 __FUNCTION__, state->config->demod_address, reg, err);
112 return -EREMOTEIO;
113 }
114 deb_i2c("i2c rd %02x: ",reg);
115 dbufout(buf,len,deb_i2c);
116 deb_i2c("\n");
117
118 return 0;
119}
120
121static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
122{
123 return bcm3510_writebytes(state,reg,&v.raw,1);
124}
125
126static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
127{
128 return bcm3510_readbytes(state,reg,&v->raw,1);
129}
130
131/* Host Access Buffer transfers */
132static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
133{
134 bcm3510_register_value v;
135 int ret,i;
136
137 v.HABADR_a6.HABADR = 0;
138 if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
139 return ret;
140
141 for (i = 0; i < len; i++) {
142 if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
143 return ret;
144 buf[i] = v.HABDATA_a7;
145 }
146 return 0;
147}
148
149static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
150{
151 bcm3510_register_value v,hab;
152 int ret,i;
153 unsigned long t;
154
155/* Check if any previous HAB request still needs to be serviced by the
156 * Aquisition Processor before sending new request */
157 if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
158 return ret;
159 if (v.HABSTAT_a8.HABR) {
160 deb_info("HAB is running already - clearing it.\n");
161 v.HABSTAT_a8.HABR = 0;
162 bcm3510_writeB(st,0xa8,v);
163// return -EBUSY;
164 }
165
166/* Send the start HAB Address (automatically incremented after write of
167 * HABDATA) and write the HAB Data */
168 hab.HABADR_a6.HABADR = 0;
169 if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
170 return ret;
171
172 for (i = 0; i < len; i++) {
173 hab.HABDATA_a7 = buf[i];
174 if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
175 return ret;
176 }
177
178/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
179 * be written) */
180 v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
181 if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
182 return ret;
183
184/* Polling method: Wait until the AP finishes processing the HAB request */
185 t = jiffies + 1*HZ;
186 while (time_before(jiffies, t)) {
187 deb_info("waiting for HAB to complete\n");
188 msleep(10);
189 if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
190 return ret;
191
192 if (!v.HABSTAT_a8.HABR)
193 return 0;
194 }
195
196 deb_info("send_request execution timed out.\n");
197 return -ETIMEDOUT;
198}
199
200static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
201{
202 u8 ob[olen+2],ib[ilen+2];
203 int ret = 0;
204
205 ob[0] = cmd;
206 ob[1] = msgid;
207 memcpy(&ob[2],obuf,olen);
208
209 deb_hab("hab snd: ");
210 dbufout(ob,olen+2,deb_hab);
211 deb_hab("\n");
212
213 if (down_interruptible(&st->hab_sem) < 0)
214 return -EAGAIN;
215
216 if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
217 (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
218 goto error;
219
220 deb_hab("hab get: ");
221 dbufout(ib,ilen+2,deb_hab);
222 deb_hab("\n");
223
224 memcpy(ibuf,&ib[2],ilen);
225error:
226 up(&st->hab_sem);
227 return ret;
228}
229
230#if 0
231/* not needed, we use a semaphore to prevent HAB races */
232static int bcm3510_is_ap_ready(struct bcm3510_state *st)
233{
234 bcm3510_register_value ap,hab;
235 int ret;
236
237 if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
238 (ret = bcm3510_readB(st,0xa2,&ap) < 0))
239 return ret;
240
241 if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
242 deb_info("AP is busy\n");
243 return -EBUSY;
244 }
245
246 return 0;
247}
248#endif
249
250static int bcm3510_bert_reset(struct bcm3510_state *st)
251{
252 bcm3510_register_value b;
253 int ret;
254
255 if ((ret < bcm3510_readB(st,0xfa,&b)) < 0)
256 return ret;
257
258 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
259 b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
260 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
261 b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
262
263 /* clear residual bit counter TODO */
264 return 0;
265}
266
267static int bcm3510_refresh_state(struct bcm3510_state *st)
268{
269 if (time_after(jiffies,st->next_status_check)) {
270 bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
271 bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
272 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
273 }
274 return 0;
275}
276
277static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status)
278{
279 struct bcm3510_state* st = fe->demodulator_priv;
280 bcm3510_refresh_state(st);
281
282 *status = 0;
283 if (st->status1.STATUS1.RECEIVER_LOCK)
284 *status |= FE_HAS_LOCK | FE_HAS_SYNC;
285
286 if (st->status1.STATUS1.FEC_LOCK)
287 *status |= FE_HAS_VITERBI;
288
289 if (st->status1.STATUS1.OUT_PLL_LOCK)
290 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
291
292 if (*status & FE_HAS_LOCK)
293 st->status_check_interval = 1500;
294 else /* more frequently checks if no lock has been achieved yet */
295 st->status_check_interval = 500;
296
297 deb_info("real_status: %02x\n",*status);
298 return 0;
299}
300
301static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
302{
303 struct bcm3510_state* st = fe->demodulator_priv;
304 bcm3510_refresh_state(st);
305
306 *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
307 return 0;
308}
309
310static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
311{
312 struct bcm3510_state* st = fe->demodulator_priv;
313 bcm3510_refresh_state(st);
314 *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
315 return 0;
316}
317
318static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
319{
320 struct bcm3510_state* st = fe->demodulator_priv;
321 s32 t;
322
323 bcm3510_refresh_state(st);
324 t = st->status2.SIGNAL;
325
326 if (t > 190)
327 t = 190;
328 if (t < 90)
329 t = 90;
330
331 t -= 90;
332 t = t * 0xff / 100;
333 /* normalize if necessary */
334 *strength = (t << 8) | t;
335 return 0;
336}
337
338static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
339{
340 struct bcm3510_state* st = fe->demodulator_priv;
341 bcm3510_refresh_state(st);
342
343 *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
344 return 0;
345}
346
347/* tuner frontend programming */
348static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
349{
350 struct bcm3510_hab_cmd_tune c;
351 memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
352
353/* I2C Mode disabled, set 16 control / Data pairs */
354 c.length = 0x10;
355 c.clock_width = 0;
356/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
357 * logic high (as Configuration) */
358 c.misc = 0x10;
359/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
360 c.TUNCTL_state = 0x40;
361
362/* PRESCALER DEVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
363 c.ctl_dat[0].ctrl.size = BITS_8;
364 c.ctl_dat[0].data = 0x80 | bc;
365
366/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
367 c.ctl_dat[1].ctrl.size = BITS_8;
368 c.ctl_dat[1].data = 4;
369
370/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
371 c.ctl_dat[2].ctrl.size = BITS_3;
372 c.ctl_dat[2].data = 0x20;
373
374/* control CS0 pin, pulse byte ? */
375 c.ctl_dat[3].ctrl.size = BITS_3;
376 c.ctl_dat[3].ctrl.clk_off = 1;
377 c.ctl_dat[3].ctrl.cs0 = 1;
378 c.ctl_dat[3].data = 0x40;
379
380/* PGM_S18 to PGM_S11 */
381 c.ctl_dat[4].ctrl.size = BITS_8;
382 c.ctl_dat[4].data = n >> 3;
383
384/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
385 c.ctl_dat[5].ctrl.size = BITS_8;
386 c.ctl_dat[5].data = ((n & 0x7) << 5) | (a >> 2);
387
388/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
389 c.ctl_dat[6].ctrl.size = BITS_3;
390 c.ctl_dat[6].data = (a << 6) & 0xdf;
391
392/* control CS0 pin, pulse byte ? */
393 c.ctl_dat[7].ctrl.size = BITS_3;
394 c.ctl_dat[7].ctrl.clk_off = 1;
395 c.ctl_dat[7].ctrl.cs0 = 1;
396 c.ctl_dat[7].data = 0x40;
397
398/* PRESCALER DEVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
399 c.ctl_dat[8].ctrl.size = BITS_8;
400 c.ctl_dat[8].data = 0x80;
401
402/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
403 c.ctl_dat[9].ctrl.size = BITS_8;
404 c.ctl_dat[9].data = 0x10;
405
406/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
407 c.ctl_dat[10].ctrl.size = BITS_3;
408 c.ctl_dat[10].data = 0x20;
409
410/* pulse byte */
411 c.ctl_dat[11].ctrl.size = BITS_3;
412 c.ctl_dat[11].ctrl.clk_off = 1;
413 c.ctl_dat[11].ctrl.cs1 = 1;
414 c.ctl_dat[11].data = 0x40;
415
416/* PGM_S18 to PGM_S11 */
417 c.ctl_dat[12].ctrl.size = BITS_8;
418 c.ctl_dat[12].data = 0x2a;
419
420/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
421 c.ctl_dat[13].ctrl.size = BITS_8;
422 c.ctl_dat[13].data = 0x8e;
423
424/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
425 c.ctl_dat[14].ctrl.size = BITS_3;
426 c.ctl_dat[14].data = 0;
427
428/* Pulse Byte */
429 c.ctl_dat[15].ctrl.size = BITS_3;
430 c.ctl_dat[15].ctrl.clk_off = 1;
431 c.ctl_dat[15].ctrl.cs1 = 1;
432 c.ctl_dat[15].data = 0x40;
433
434 return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
435}
436
437static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
438{
439 u8 bc,a;
440 u16 n;
441 s32 YIntercept,Tfvco1;
442
443 freq /= 1000;
444
445 deb_info("%dkHz:",freq);
446 /* set Band Switch */
447 if (freq <= 168000)
448 bc = 0x1c;
449 else if (freq <= 378000)
450 bc = 0x2c;
451 else
452 bc = 0x30;
453
454 if (freq >= 470000) {
455 freq -= 470001;
456 YIntercept = 18805;
457 } else if (freq >= 90000) {
458 freq -= 90001;
459 YIntercept = 15005;
460 } else if (freq >= 76000){
461 freq -= 76001;
462 YIntercept = 14865;
463 } else {
464 freq -= 54001;
465 YIntercept = 14645;
466 }
467
468 Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
469
470 n = Tfvco1 >> 6;
471 a = Tfvco1 & 0x3f;
472
473 deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
474 if (n >= 16 && n <= 2047)
475 return bcm3510_tuner_cmd(st,bc,n,a);
476
477 return -EINVAL;
478}
479
480static int bcm3510_set_frontend(struct dvb_frontend* fe,
481 struct dvb_frontend_parameters *p)
482{
483 struct bcm3510_state* st = fe->demodulator_priv;
484 struct bcm3510_hab_cmd_ext_acquire cmd;
485 struct bcm3510_hab_cmd_bert_control bert;
486 int ret;
487
488 memset(&cmd,0,sizeof(cmd));
489 switch (p->u.vsb.modulation) {
490 case QAM_256:
491 cmd.ACQUIRE0.MODE = 0x1;
492 cmd.ACQUIRE1.SYM_RATE = 0x1;
493 cmd.ACQUIRE1.IF_FREQ = 0x1;
494 break;
495 case QAM_64:
496 cmd.ACQUIRE0.MODE = 0x2;
497 cmd.ACQUIRE1.SYM_RATE = 0x2;
498 cmd.ACQUIRE1.IF_FREQ = 0x1;
499 break;
500/* case QAM_256:
501 cmd.ACQUIRE0.MODE = 0x3;
502 break;
503 case QAM_128:
504 cmd.ACQUIRE0.MODE = 0x4;
505 break;
506 case QAM_64:
507 cmd.ACQUIRE0.MODE = 0x5;
508 break;
509 case QAM_32:
510 cmd.ACQUIRE0.MODE = 0x6;
511 break;
512 case QAM_16:
513 cmd.ACQUIRE0.MODE = 0x7;
514 break;*/
515 case VSB_8:
516 cmd.ACQUIRE0.MODE = 0x8;
517 cmd.ACQUIRE1.SYM_RATE = 0x0;
518 cmd.ACQUIRE1.IF_FREQ = 0x0;
519 break;
520 case VSB_16:
521 cmd.ACQUIRE0.MODE = 0x9;
522 cmd.ACQUIRE1.SYM_RATE = 0x0;
523 cmd.ACQUIRE1.IF_FREQ = 0x0;
524 default:
525 return -EINVAL;
526 };
527 cmd.ACQUIRE0.OFFSET = 0;
528 cmd.ACQUIRE0.NTSCSWEEP = 1;
529 cmd.ACQUIRE0.FA = 1;
530 cmd.ACQUIRE0.BW = 0;
531
532/* if (enableOffset) {
533 cmd.IF_OFFSET0 = xx;
534 cmd.IF_OFFSET1 = xx;
535
536 cmd.SYM_OFFSET0 = xx;
537 cmd.SYM_OFFSET1 = xx;
538 if (enableNtscSweep) {
539 cmd.NTSC_OFFSET0;
540 cmd.NTSC_OFFSET1;
541 }
542 } */
543 bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
544
545/* doing it with different MSGIDs, data book and source differs */
546 bert.BE = 0;
547 bert.unused = 0;
548 bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
549 bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
550
551 bcm3510_bert_reset(st);
552
553 if ((ret = bcm3510_set_freq(st,p->frequency)) < 0)
554 return ret;
555
556 memset(&st->status1,0,sizeof(st->status1));
557 memset(&st->status2,0,sizeof(st->status2));
558 st->status_check_interval = 500;
559
560/* Give the AP some time */
561 msleep(200);
562
563 return 0;
564}
565
566static int bcm3510_sleep(struct dvb_frontend* fe)
567{
568 return 0;
569}
570
571static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
572{
573 s->min_delay_ms = 1000;
574 s->step_size = 0;
575 s->max_drift = 0;
576 return 0;
577}
578
579static void bcm3510_release(struct dvb_frontend* fe)
580{
581 struct bcm3510_state* state = fe->demodulator_priv;
582 kfree(state);
583}
584
585/* firmware download:
586 * firmware file is build up like this:
587 * 16bit addr, 16bit length, 8byte of length
588 */
589#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
590
591static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, u8 *b, u16 len)
592{
593 int ret = 0,i;
594 bcm3510_register_value vH, vL,vD;
595
596 vH.MADRH_a9 = addr >> 8;
597 vL.MADRL_aa = addr;
598 if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
599 if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
600
601 for (i = 0; i < len; i++) {
602 vD.MDATA_ab = b[i];
603 if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
604 return ret;
605 }
606
607 return 0;
608}
609
610static int bcm3510_download_firmware(struct dvb_frontend* fe)
611{
612 struct bcm3510_state* st = fe->demodulator_priv;
613 const struct firmware *fw;
614 u16 addr,len;
615 u8 *b;
616 int ret,i;
617
618 deb_info("requesting firmware\n");
619 if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
620 err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
621 return ret;
622 }
623 deb_info("got firmware: %d\n",fw->size);
624
625 b = fw->data;
626 for (i = 0; i < fw->size;) {
627 addr = le16_to_cpu( *( (u16 *)&b[i] ) );
628 len = le16_to_cpu( *( (u16 *)&b[i+2] ) );
629 deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size);
630 if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
631 err("firmware download failed: %d\n",ret);
632 return ret;
633 }
634 i += 4 + len;
635 }
636 release_firmware(fw);
637 deb_info("firmware download successfully completed\n");
638 return 0;
639}
640
641static int bcm3510_check_firmware_version(struct bcm3510_state *st)
642{
643 struct bcm3510_hab_cmd_get_version_info ver;
644 bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
645
646 deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
647 ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
648
649 if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
650 ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
651 ver.demod_version == BCM3510_DEF_DEMOD_VERSION)
652 return 0;
653
654 deb_info("version check failed\n");
655 return -ENODEV;
656}
657
658/* (un)resetting the AP */
659static int bcm3510_reset(struct bcm3510_state *st)
660{
661 int ret;
662 unsigned long t;
663 bcm3510_register_value v;
664
665 bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
666 if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
667 return ret;
668
669 t = jiffies + 3*HZ;
670 while (time_before(jiffies, t)) {
671 msleep(10);
672 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
673 return ret;
674
675 if (v.APSTAT1_a2.RESET)
676 return 0;
677 }
678 deb_info("reset timed out\n");
679 return -ETIMEDOUT;
680}
681
682static int bcm3510_clear_reset(struct bcm3510_state *st)
683{
684 bcm3510_register_value v;
685 int ret;
686 unsigned long t;
687
688 v.raw = 0;
689 if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
690 return ret;
691
692 t = jiffies + 3*HZ;
693 while (time_before(jiffies, t)) {
694 msleep(10);
695 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
696 return ret;
697
698 /* verify that reset is cleared */
699 if (!v.APSTAT1_a2.RESET)
700 return 0;
701 }
702 deb_info("reset clear timed out\n");
703 return -ETIMEDOUT;
704}
705
706static int bcm3510_init_cold(struct bcm3510_state *st)
707{
708 int ret;
709 bcm3510_register_value v;
710
711 /* read Acquisation Processor status register and check it is not in RUN mode */
712 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
713 return ret;
714 if (v.APSTAT1_a2.RUN) {
715 deb_info("AP is already running - firmware already loaded.\n");
716 return 0;
717 }
718
719 deb_info("reset?\n");
720 if ((ret = bcm3510_reset(st)) < 0)
721 return ret;
722
723 deb_info("tristate?\n");
724 /* tri-state */
725 v.TSTCTL_2e.CTL = 0;
726 if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
727 return ret;
728
729 deb_info("firmware?\n");
730 if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
731 (ret = bcm3510_clear_reset(st)) < 0)
732 return ret;
733
734 /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
735
736 return 0;
737}
738
739static int bcm3510_init(struct dvb_frontend* fe)
740{
741 struct bcm3510_state* st = fe->demodulator_priv;
742 bcm3510_register_value j;
743 struct bcm3510_hab_cmd_set_agc c;
744 int ret;
745
746 if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
747 return ret;
748
749 deb_info("JDEC: %02x\n",j.raw);
750
751 switch (j.JDEC_ca.JDEC) {
752 case JDEC_WAIT_AT_RAM:
753 deb_info("attempting to download firmware\n");
754 if ((ret = bcm3510_init_cold(st)) < 0)
755 return ret;
756 case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
757 deb_info("firmware is loaded\n");
758 bcm3510_check_firmware_version(st);
759 break;
760 default:
761 return -ENODEV;
762 }
763
764 memset(&c,0,1);
765 c.SEL = 1;
766 bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
767
768 return 0;
769}
770
771
772static struct dvb_frontend_ops bcm3510_ops;
773
774struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
775 struct i2c_adapter *i2c)
776{
777 struct bcm3510_state* state = NULL;
778 int ret;
779 bcm3510_register_value v;
780
781 /* allocate memory for the internal state */
782 state = kmalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
783 if (state == NULL)
784 goto error;
785 memset(state,0,sizeof(struct bcm3510_state));
786
787 /* setup the state */
788
789 state->config = config;
790 state->i2c = i2c;
791 memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
792
793 /* create dvb_frontend */
794 state->frontend.ops = &state->ops;
795 state->frontend.demodulator_priv = state;
796
797 sema_init(&state->hab_sem, 1);
798
799 if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
800 goto error;
801
802 deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
803
804 if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
805 (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0)) /* warm */
806 goto error;
807
808 info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
809
810 bcm3510_reset(state);
811
812 return &state->frontend;
813
814error:
815 kfree(state);
816 return NULL;
817}
818EXPORT_SYMBOL(bcm3510_attach);
819
820static struct dvb_frontend_ops bcm3510_ops = {
821
822 .info = {
823 .name = "Broadcom BCM3510 VSB/QAM frontend",
824 .type = FE_ATSC,
825 .frequency_min = 54000000,
826 .frequency_max = 803000000,
827 /* stepsize is just a guess */
828 .frequency_stepsize = 0,
829 .caps =
830 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
831 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
832 FE_CAN_8VSB | FE_CAN_16VSB |
833 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
834 },
835
836 .release = bcm3510_release,
837
838 .init = bcm3510_init,
839 .sleep = bcm3510_sleep,
840
841 .set_frontend = bcm3510_set_frontend,
842 .get_tune_settings = bcm3510_get_tune_settings,
843
844 .read_status = bcm3510_read_status,
845 .read_ber = bcm3510_read_ber,
846 .read_signal_strength = bcm3510_read_signal_strength,
847 .read_snr = bcm3510_read_snr,
848 .read_ucblocks = bcm3510_read_unc,
849};
850
851MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
852MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
853MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
new file mode 100644
index 000000000000..80f5d0953d02
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.h
@@ -0,0 +1,40 @@
1/*
2 * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
3 *
4 * Copyright (C) 2001-5, B2C2 inc.
5 *
6 * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22#ifndef BCM3510_H
23#define BCM3510_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/firmware.h>
27
28struct bcm3510_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* request firmware for device */
34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
35};
36
37extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
38 struct i2c_adapter* i2c);
39
40#endif
diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h
new file mode 100644
index 000000000000..3bb1bc2a04f0
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510_priv.h
@@ -0,0 +1,460 @@
1/*
2 * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
3 *
4 * Copyright (C) 2001-5, B2C2 inc.
5 *
6 * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22#ifndef __BCM3510_PRIV_H__
23#define __BCM3510_PRIV_H__
24
25#define PACKED __attribute__((packed))
26
27#undef err
28#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg)
29#undef info
30#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg)
31#undef warn
32#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
33
34
35#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500
36#define BCM3510_SYMBOL_RATE 5381000
37
38typedef union {
39 u8 raw;
40
41 struct {
42 u8 CTL :8;
43 } TSTCTL_2e;
44
45 u8 LDCERC_4e;
46 u8 LDUERC_4f;
47 u8 LD_BER0_65;
48 u8 LD_BER1_66;
49 u8 LD_BER2_67;
50 u8 LD_BER3_68;
51
52 struct {
53 u8 RESET :1;
54 u8 IDLE :1;
55 u8 STOP :1;
56 u8 HIRQ0 :1;
57 u8 HIRQ1 :1;
58 u8 na0 :1;
59 u8 HABAV :1;
60 u8 na1 :1;
61 } HCTL1_a0;
62
63 struct {
64 u8 na0 :1;
65 u8 IDLMSK :1;
66 u8 STMSK :1;
67 u8 I0MSK :1;
68 u8 I1MSK :1;
69 u8 na1 :1;
70 u8 HABMSK :1;
71 u8 na2 :1;
72 } HCTLMSK_a1;
73
74 struct {
75 u8 RESET :1;
76 u8 IDLE :1;
77 u8 STOP :1;
78 u8 RUN :1;
79 u8 HABAV :1;
80 u8 MEMAV :1;
81 u8 ALDONE :1;
82 u8 REIRQ :1;
83 } APSTAT1_a2;
84
85 struct {
86 u8 RSTMSK :1;
87 u8 IMSK :1;
88 u8 SMSK :1;
89 u8 RMSK :1;
90 u8 HABMSK :1;
91 u8 MAVMSK :1;
92 u8 ALDMSK :1;
93 u8 REMSK :1;
94 } APMSK1_a3;
95
96 u8 APSTAT2_a4;
97 u8 APMSK2_a5;
98
99 struct {
100 u8 HABADR :7;
101 u8 na :1;
102 } HABADR_a6;
103
104 u8 HABDATA_a7;
105
106 struct {
107 u8 HABR :1;
108 u8 LDHABR :1;
109 u8 APMSK :1;
110 u8 HMSK :1;
111 u8 LDMSK :1;
112 u8 na :3;
113 } HABSTAT_a8;
114
115 u8 MADRH_a9;
116 u8 MADRL_aa;
117 u8 MDATA_ab;
118
119 struct {
120#define JDEC_WAIT_AT_RAM 0x7
121#define JDEC_EEPROM_LOAD_WAIT 0x4
122 u8 JDEC :3;
123 u8 na :5;
124 } JDEC_ca;
125
126 struct {
127 u8 REV :4;
128 u8 LAYER :4;
129 } REVID_e0;
130
131 struct {
132 u8 unk0 :1;
133 u8 CNTCTL :1;
134 u8 BITCNT :1;
135 u8 unk1 :1;
136 u8 RESYNC :1;
137 u8 unk2 :3;
138 } BERCTL_fa;
139
140 struct {
141 u8 CSEL0 :1;
142 u8 CLKED0 :1;
143 u8 CSEL1 :1;
144 u8 CLKED1 :1;
145 u8 CLKLEV :1;
146 u8 SPIVAR :1;
147 u8 na :2;
148 } TUNSET_fc;
149
150 struct {
151 u8 CLK :1;
152 u8 DATA :1;
153 u8 CS0 :1;
154 u8 CS1 :1;
155 u8 AGCSEL :1;
156 u8 na0 :1;
157 u8 TUNSEL :1;
158 u8 na1 :1;
159 } TUNCTL_fd;
160
161 u8 TUNSEL0_fe;
162 u8 TUNSEL1_ff;
163
164} bcm3510_register_value;
165
166/* HAB commands */
167
168/* version */
169#define CMD_GET_VERSION_INFO 0x3D
170#define MSGID_GET_VERSION_INFO 0x15
171struct bcm3510_hab_cmd_get_version_info {
172 u8 microcode_version;
173 u8 script_version;
174 u8 config_version;
175 u8 demod_version;
176} PACKED;
177
178#define BCM3510_DEF_MICROCODE_VERSION 0x0E
179#define BCM3510_DEF_SCRIPT_VERSION 0x06
180#define BCM3510_DEF_CONFIG_VERSION 0x01
181#define BCM3510_DEF_DEMOD_VERSION 0xB1
182
183/* acquire */
184#define CMD_ACQUIRE 0x38
185
186#define MSGID_EXT_TUNER_ACQUIRE 0x0A
187struct bcm3510_hab_cmd_ext_acquire {
188 struct {
189 u8 MODE :4;
190 u8 BW :1;
191 u8 FA :1;
192 u8 NTSCSWEEP :1;
193 u8 OFFSET :1;
194 } PACKED ACQUIRE0; /* control_byte */
195
196 struct {
197 u8 IF_FREQ :3;
198 u8 zero0 :1;
199 u8 SYM_RATE :3;
200 u8 zero1 :1;
201 } PACKED ACQUIRE1; /* sym_if */
202
203 u8 IF_OFFSET0; /* IF_Offset_10hz */
204 u8 IF_OFFSET1;
205 u8 SYM_OFFSET0; /* SymbolRateOffset */
206 u8 SYM_OFFSET1;
207 u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
208 u8 NTSC_OFFSET1;
209} PACKED;
210
211#define MSGID_INT_TUNER_ACQUIRE 0x0B
212struct bcm3510_hab_cmd_int_acquire {
213 struct {
214 u8 MODE :4;
215 u8 BW :1;
216 u8 FA :1;
217 u8 NTSCSWEEP :1;
218 u8 OFFSET :1;
219 } PACKED ACQUIRE0; /* control_byte */
220
221 struct {
222 u8 IF_FREQ :3;
223 u8 zero0 :1;
224 u8 SYM_RATE :3;
225 u8 zero1 :1;
226 } PACKED ACQUIRE1; /* sym_if */
227
228 u8 TUNER_FREQ0;
229 u8 TUNER_FREQ1;
230 u8 TUNER_FREQ2;
231 u8 TUNER_FREQ3;
232 u8 IF_OFFSET0; /* IF_Offset_10hz */
233 u8 IF_OFFSET1;
234 u8 SYM_OFFSET0; /* SymbolRateOffset */
235 u8 SYM_OFFSET1;
236 u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
237 u8 NTSC_OFFSET1;
238} PACKED;
239
240/* modes */
241#define BCM3510_QAM16 = 0x01
242#define BCM3510_QAM32 = 0x02
243#define BCM3510_QAM64 = 0x03
244#define BCM3510_QAM128 = 0x04
245#define BCM3510_QAM256 = 0x05
246#define BCM3510_8VSB = 0x0B
247#define BCM3510_16VSB = 0x0D
248
249/* IF_FREQS */
250#define BCM3510_IF_TERRESTRIAL 0x0
251#define BCM3510_IF_CABLE 0x1
252#define BCM3510_IF_USE_CMD 0x7
253
254/* SYM_RATE */
255#define BCM3510_SR_8VSB 0x0 /* 5381119 s/sec */
256#define BCM3510_SR_256QAM 0x1 /* 5360537 s/sec */
257#define BCM3510_SR_16QAM 0x2 /* 5056971 s/sec */
258#define BCM3510_SR_MISC 0x3 /* 5000000 s/sec */
259#define BCM3510_SR_USE_CMD 0x7
260
261/* special symbol rate */
262#define CMD_SET_VALUE_NOT_LISTED 0x2d
263#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c
264struct bcm3510_hab_cmd_set_sr_not_listed {
265 u8 HOST_SYM_RATE0;
266 u8 HOST_SYM_RATE1;
267 u8 HOST_SYM_RATE2;
268 u8 HOST_SYM_RATE3;
269} PACKED;
270
271/* special IF */
272#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d
273struct bcm3510_hab_cmd_set_if_freq_not_listed {
274 u8 HOST_IF_FREQ0;
275 u8 HOST_IF_FREQ1;
276 u8 HOST_IF_FREQ2;
277 u8 HOST_IF_FREQ3;
278} PACKED;
279
280/* auto reacquire */
281#define CMD_AUTO_PARAM 0x2a
282#define MSGID_AUTO_REACQUIRE 0x0e
283struct bcm3510_hab_cmd_auto_reacquire {
284 u8 ACQ :1; /* on/off*/
285 u8 unused :7;
286} PACKED;
287
288#define MSGID_SET_RF_AGC_SEL 0x12
289struct bcm3510_hab_cmd_set_agc {
290 u8 LVL :1;
291 u8 unused :6;
292 u8 SEL :1;
293} PACKED;
294
295#define MSGID_SET_AUTO_INVERSION 0x14
296struct bcm3510_hab_cmd_auto_inversion {
297 u8 AI :1;
298 u8 unused :7;
299} PACKED;
300
301
302/* bert control */
303#define CMD_STATE_CONTROL 0x12
304#define MSGID_BERT_CONTROL 0x0e
305#define MSGID_BERT_SET 0xfa
306struct bcm3510_hab_cmd_bert_control {
307 u8 BE :1;
308 u8 unused :7;
309} PACKED;
310
311#define MSGID_TRI_STATE 0x2e
312struct bcm3510_hab_cmd_tri_state {
313 u8 RE :1; /* a/d ram port pins */
314 u8 PE :1; /* baud clock pin */
315 u8 AC :1; /* a/d clock pin */
316 u8 BE :1; /* baud clock pin */
317 u8 unused :4;
318} PACKED;
319
320
321/* tune */
322#define CMD_TUNE 0x38
323#define MSGID_TUNE 0x16
324struct bcm3510_hab_cmd_tune_ctrl_data_pair {
325 struct {
326#define BITS_8 0x07
327#define BITS_7 0x06
328#define BITS_6 0x05
329#define BITS_5 0x04
330#define BITS_4 0x03
331#define BITS_3 0x02
332#define BITS_2 0x01
333#define BITS_1 0x00
334 u8 size :3;
335 u8 unk :2;
336 u8 clk_off :1;
337 u8 cs0 :1;
338 u8 cs1 :1;
339
340 } PACKED ctrl;
341
342 u8 data;
343} PACKED;
344
345struct bcm3510_hab_cmd_tune {
346 u8 length;
347 u8 clock_width;
348 u8 misc;
349 u8 TUNCTL_state;
350
351 struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16];
352} PACKED;
353
354#define CMD_STATUS 0x38
355#define MSGID_STATUS1 0x08
356struct bcm3510_hab_cmd_status1 {
357 struct {
358 u8 EQ_MODE :4;
359 u8 reserved :2;
360 u8 QRE :1; /* if QSE and the spectrum is inversed */
361 u8 QSE :1; /* automatic spectral inversion */
362 } PACKED STATUS0;
363
364 struct {
365 u8 RECEIVER_LOCK :1;
366 u8 FEC_LOCK :1;
367 u8 OUT_PLL_LOCK :1;
368 u8 reserved :5;
369 } PACKED STATUS1;
370
371 struct {
372 u8 reserved :2;
373 u8 BW :1;
374 u8 NTE :1; /* NTSC filter sweep enabled */
375 u8 AQI :1; /* currently acquiring */
376 u8 FA :1; /* fast acquisition */
377 u8 ARI :1; /* auto reacquire */
378 u8 TI :1; /* programming the tuner */
379 } PACKED STATUS2;
380 u8 STATUS3;
381 u8 SNR_EST0;
382 u8 SNR_EST1;
383 u8 TUNER_FREQ0;
384 u8 TUNER_FREQ1;
385 u8 TUNER_FREQ2;
386 u8 TUNER_FREQ3;
387 u8 SYM_RATE0;
388 u8 SYM_RATE1;
389 u8 SYM_RATE2;
390 u8 SYM_RATE3;
391 u8 SYM_OFFSET0;
392 u8 SYM_OFFSET1;
393 u8 SYM_ERROR0;
394 u8 SYM_ERROR1;
395 u8 IF_FREQ0;
396 u8 IF_FREQ1;
397 u8 IF_FREQ2;
398 u8 IF_FREQ3;
399 u8 IF_OFFSET0;
400 u8 IF_OFFSET1;
401 u8 IF_ERROR0;
402 u8 IF_ERROR1;
403 u8 NTSC_FILTER0;
404 u8 NTSC_FILTER1;
405 u8 NTSC_FILTER2;
406 u8 NTSC_FILTER3;
407 u8 NTSC_OFFSET0;
408 u8 NTSC_OFFSET1;
409 u8 NTSC_ERROR0;
410 u8 NTSC_ERROR1;
411 u8 INT_AGC_LEVEL0;
412 u8 INT_AGC_LEVEL1;
413 u8 EXT_AGC_LEVEL0;
414 u8 EXT_AGC_LEVEL1;
415} PACKED;
416
417#define MSGID_STATUS2 0x14
418struct bcm3510_hab_cmd_status2 {
419 struct {
420 u8 EQ_MODE :4;
421 u8 reserved :2;
422 u8 QRE :1;
423 u8 QSR :1;
424 } PACKED STATUS0;
425 struct {
426 u8 RL :1;
427 u8 FL :1;
428 u8 OL :1;
429 u8 reserved :5;
430 } PACKED STATUS1;
431 u8 SYMBOL_RATE0;
432 u8 SYMBOL_RATE1;
433 u8 SYMBOL_RATE2;
434 u8 SYMBOL_RATE3;
435 u8 LDCERC0;
436 u8 LDCERC1;
437 u8 LDCERC2;
438 u8 LDCERC3;
439 u8 LDUERC0;
440 u8 LDUERC1;
441 u8 LDUERC2;
442 u8 LDUERC3;
443 u8 LDBER0;
444 u8 LDBER1;
445 u8 LDBER2;
446 u8 LDBER3;
447 struct {
448 u8 MODE_TYPE :4; /* acquire mode 0 */
449 u8 reservd :4;
450 } MODE_TYPE;
451 u8 SNR_EST0;
452 u8 SNR_EST1;
453 u8 SIGNAL;
454} PACKED;
455
456#define CMD_SET_RF_BW_NOT_LISTED 0x3f
457#define MSGID_SET_RF_BW_NOT_LISTED 0x11
458/* TODO */
459
460#endif
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
index 47ab02e133d1..1a4f1f7c228a 100644
--- a/drivers/media/dvb/frontends/dib3000-common.c
+++ b/drivers/media/dvb/frontends/dib3000-common.c
@@ -73,7 +73,7 @@ u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
73 }; 73 };
74 74
75MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de"); 75MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
76MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb-frontend drivers"); 76MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers");
77MODULE_LICENSE("GPL"); 77MODULE_LICENSE("GPL");
78 78
79EXPORT_SYMBOL(dib3000_seq); 79EXPORT_SYMBOL(dib3000_seq);
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
index 80687c130836..2d5475b5c063 100644
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -32,9 +32,8 @@ struct dib3000_config
32 u8 demod_address; 32 u8 demod_address;
33 33
34 /* PLL maintenance and the i2c address of the PLL */ 34 /* PLL maintenance and the i2c address of the PLL */
35 u8 (*pll_addr)(struct dvb_frontend *fe); 35 int (*pll_init)(struct dvb_frontend *fe);
36 int (*pll_init)(struct dvb_frontend *fe, u8 pll_buf[5]); 36 int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params);
37 int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params, u8 pll_buf[5]);
38}; 37};
39 38
40struct dib_fe_xfer_ops 39struct dib_fe_xfer_ops
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index 6f52d649e97e..cd434b7cf9db 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -48,8 +48,6 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a
48#define deb_setf(args...) dprintk(0x04,args) 48#define deb_setf(args...) dprintk(0x04,args)
49#define deb_getf(args...) dprintk(0x08,args) 49#define deb_getf(args...) dprintk(0x08,args)
50 50
51static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mb_get_frontend(struct dvb_frontend* fe, 51static int dib3000mb_get_frontend(struct dvb_frontend* fe,
54 struct dvb_frontend_parameters *fep); 52 struct dvb_frontend_parameters *fep);
55 53
@@ -61,10 +59,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
61 fe_code_rate_t fe_cr = FEC_NONE; 59 fe_code_rate_t fe_cr = FEC_NONE;
62 int search_state, seq; 60 int search_state, seq;
63 61
64 if (tuner && state->config.pll_addr && state->config.pll_set) { 62 if (tuner && state->config.pll_set) {
65 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); 63 state->config.pll_set(fe, fep);
66 state->config.pll_set(fe, fep, NULL);
67 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
68 64
69 deb_setf("bandwidth: "); 65 deb_setf("bandwidth: ");
70 switch (ofdm->bandwidth) { 66 switch (ofdm->bandwidth) {
@@ -389,11 +385,8 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
389 385
390 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); 386 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
391 387
392 if (state->config.pll_init) { 388 if (state->config.pll_init)
393 dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); 389 state->config.pll_init(fe);
394 state->config.pll_init(fe,NULL);
395 dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
396 }
397 390
398 return 0; 391 return 0;
399} 392}
@@ -623,7 +616,7 @@ static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
623{ 616{
624 struct dib3000_state* state = fe->demodulator_priv; 617 struct dib3000_state* state = fe->demodulator_priv;
625 618
626 *unc = rd(DIB3000MB_REG_UNC); 619 *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
627 return 0; 620 return 0;
628} 621}
629 622
@@ -638,9 +631,6 @@ static int dib3000mb_sleep(struct dvb_frontend* fe)
638static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 631static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
639{ 632{
640 tune->min_delay_ms = 800; 633 tune->min_delay_ms = 800;
641 tune->step_size = 166667;
642 tune->max_drift = 166667 * 2;
643
644 return 0; 634 return 0;
645} 635}
646 636
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
index 57e61aa5b07b..999b19047816 100644
--- a/drivers/media/dvb/frontends/dib3000mb_priv.h
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -294,7 +294,7 @@ static u16 dib3000mb_reg_filter_coeffs[] = {
294 294
295static u16 dib3000mb_filter_coeffs[] = { 295static u16 dib3000mb_filter_coeffs[] = {
296 226, 160, 29, 296 226, 160, 29,
297 979, 998, 19, 297 979, 998, 19,
298 22, 1019, 1006, 298 22, 1019, 1006,
299 1022, 12, 6, 299 1022, 12, 6,
300 1017, 1017, 3, 300 1017, 1017, 3,
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 888f10a5e96b..cd33705a4320 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -48,8 +48,6 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=s
48#define deb_getf(args...) dprintk(0x08,args) 48#define deb_getf(args...) dprintk(0x08,args)
49#define deb_stat(args...) dprintk(0x10,args) 49#define deb_stat(args...) dprintk(0x10,args)
50 50
51static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
52
53static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode, 51static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
54 fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth) 52 fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
55{ 53{
@@ -463,10 +461,8 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
463 int search_state,auto_val; 461 int search_state,auto_val;
464 u16 val; 462 u16 val;
465 463
466 if (tuner && state->config.pll_addr && state->config.pll_set) { /* initial call from dvb */ 464 if (tuner && state->config.pll_set) { /* initial call from dvb */
467 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); 465 state->config.pll_set(fe,fep);
468 state->config.pll_set(fe,fep,NULL);
469 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
470 466
471 state->last_tuned_freq = fep->frequency; 467 state->last_tuned_freq = fep->frequency;
472 // if (!scanboost) { 468 // if (!scanboost) {
@@ -554,19 +550,15 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
554 dib3000mc_set_adp_cfg(state,ofdm->constellation); 550 dib3000mc_set_adp_cfg(state,ofdm->constellation);
555 wr_foreach(dib3000mc_reg_offset, 551 wr_foreach(dib3000mc_reg_offset,
556 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); 552 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
557
558
559 } 553 }
560 return 0; 554 return 0;
561} 555}
562 556
563static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) 557static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
564{ 558{
565 struct dib3000_state *state; 559 struct dib3000_state *state = fe->demodulator_priv;
566
567 deb_info("init start\n"); 560 deb_info("init start\n");
568 561
569 state = fe->demodulator_priv;
570 state->timing_offset = 0; 562 state->timing_offset = 0;
571 state->timing_offset_comp_done = 0; 563 state->timing_offset_comp_done = 0;
572 564
@@ -649,11 +641,9 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
649 641
650 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); 642 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
651 643
652/* if (state->config->pll_init) { 644 if (state->config.pll_init)
653 dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); 645 state->config.pll_init(fe);
654 state->config->pll_init(fe,NULL); 646
655 dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
656 }*/
657 deb_info("init end\n"); 647 deb_info("init end\n");
658 return 0; 648 return 0;
659} 649}
@@ -688,7 +678,7 @@ static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
688{ 678{
689 struct dib3000_state* state = fe->demodulator_priv; 679 struct dib3000_state* state = fe->demodulator_priv;
690 680
691 *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT); 681 *unc = rd(DIB3000MC_REG_PACKET_ERRORS);
692 return 0; 682 return 0;
693} 683}
694 684
@@ -737,10 +727,7 @@ static int dib3000mc_sleep(struct dvb_frontend* fe)
737 727
738static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 728static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
739{ 729{
740 tune->min_delay_ms = 2000; 730 tune->min_delay_ms = 1000;
741 tune->step_size = 166667;
742 tune->max_drift = 166667 * 2;
743
744 return 0; 731 return 0;
745} 732}
746 733
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 2a3c2ce7b2aa..f73b5f48e235 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * $Id: dvb-pll.c,v 1.7 2005/02/10 11:52:02 kraxel Exp $
3 *
4 * descriptions + helper functions for simple dvb plls. 2 * descriptions + helper functions for simple dvb plls.
5 * 3 *
6 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
@@ -114,6 +112,92 @@ struct dvb_pll_desc dvb_pll_unknown_1 = {
114}; 112};
115EXPORT_SYMBOL(dvb_pll_unknown_1); 113EXPORT_SYMBOL(dvb_pll_unknown_1);
116 114
115/* Infineon TUA6010XS
116 * used in Thomson Cable Tuner
117 */
118struct dvb_pll_desc dvb_pll_tua6010xs = {
119 .name = "Infineon TUA6010XS",
120 .min = 44250000,
121 .max = 858000000,
122 .count = 3,
123 .entries = {
124 { 115750000, 36125000, 62500, 0x8e, 0x03 },
125 { 403250000, 36125000, 62500, 0x8e, 0x06 },
126 { 999999999, 36125000, 62500, 0x8e, 0x85 },
127 },
128};
129EXPORT_SYMBOL(dvb_pll_tua6010xs);
130
131/* Panasonic env57h1xd5 (some Philips PLL ?) */
132struct dvb_pll_desc dvb_pll_env57h1xd5 = {
133 .name = "Panasonic ENV57H1XD5",
134 .min = 44250000,
135 .max = 858000000,
136 .count = 4,
137 .entries = {
138 { 153000000, 36291666, 166666, 0xc2, 0x41 },
139 { 470000000, 36291666, 166666, 0xc2, 0x42 },
140 { 526000000, 36291666, 166666, 0xc2, 0x84 },
141 { 999999999, 36291666, 166666, 0xc2, 0xa4 },
142 },
143};
144EXPORT_SYMBOL(dvb_pll_env57h1xd5);
145
146/* Philips TDA6650/TDA6651
147 * used in Panasonic ENV77H11D5
148 */
149static void tda665x_bw(u8 *buf, int bandwidth)
150{
151 if (bandwidth == BANDWIDTH_8_MHZ)
152 buf[3] |= 0x08;
153}
154
155struct dvb_pll_desc dvb_pll_tda665x = {
156 .name = "Philips TDA6650/TDA6651",
157 .min = 44250000,
158 .max = 858000000,
159 .setbw = tda665x_bw,
160 .count = 12,
161 .entries = {
162 { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
163 { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
164 { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
165 { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
166 { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
167 { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
168 { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
169 { 444000000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ },
170 { 583834000, 36249333, 166667, 0xca, 0x63 /* 011 0 0 0 11 */ },
171 { 793834000, 36249333, 166667, 0xca, 0xa3 /* 101 0 0 0 11 */ },
172 { 444834000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ },
173 { 861000000, 36249333, 166667, 0xca, 0xe3 /* 111 0 0 0 11 */ },
174 }
175};
176EXPORT_SYMBOL(dvb_pll_tda665x);
177
178/* Infineon TUA6034
179 * used in LG TDTP E102P
180 */
181static void tua6034_bw(u8 *buf, int bandwidth)
182{
183 if (BANDWIDTH_7_MHZ != bandwidth)
184 buf[3] |= 0x08;
185}
186
187struct dvb_pll_desc dvb_pll_tua6034 = {
188 .name = "Infineon TUA6034",
189 .min = 44250000,
190 .max = 858000000,
191 .count = 3,
192 .setbw = tua6034_bw,
193 .entries = {
194 { 174500000, 36166667, 62500, 0xce, 0x01 },
195 { 230000000, 36166667, 62500, 0xce, 0x02 },
196 { 999999999, 36166667, 62500, 0xce, 0x04 },
197 },
198};
199EXPORT_SYMBOL(dvb_pll_tua6034);
200
117/* ----------------------------------------------------------- */ 201/* ----------------------------------------------------------- */
118/* code */ 202/* code */
119 203
@@ -160,9 +244,3 @@ EXPORT_SYMBOL(dvb_pll_configure);
160MODULE_DESCRIPTION("dvb pll library"); 244MODULE_DESCRIPTION("dvb pll library");
161MODULE_AUTHOR("Gerd Knorr"); 245MODULE_AUTHOR("Gerd Knorr");
162MODULE_LICENSE("GPL"); 246MODULE_LICENSE("GPL");
163
164/*
165 * Local variables:
166 * c-basic-offset: 8
167 * End:
168 */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index c4c3c56c4a81..b796778624b6 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $ 2 * descriptions + helper functions for simple dvb plls.
3 */ 3 */
4 4
5#ifndef __DVB_PLL_H__ 5#ifndef __DVB_PLL_H__
@@ -17,7 +17,7 @@ struct dvb_pll_desc {
17 u32 stepsize; 17 u32 stepsize;
18 u8 cb1; 18 u8 cb1;
19 u8 cb2; 19 u8 cb2;
20 } entries[9]; 20 } entries[12];
21}; 21};
22 22
23extern struct dvb_pll_desc dvb_pll_thomson_dtt7579; 23extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
@@ -26,6 +26,11 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
26extern struct dvb_pll_desc dvb_pll_lg_z201; 26extern struct dvb_pll_desc dvb_pll_lg_z201;
27extern struct dvb_pll_desc dvb_pll_unknown_1; 27extern struct dvb_pll_desc dvb_pll_unknown_1;
28 28
29extern struct dvb_pll_desc dvb_pll_tua6010xs;
30extern struct dvb_pll_desc dvb_pll_env57h1xd5;
31extern struct dvb_pll_desc dvb_pll_tua6034;
32extern struct dvb_pll_desc dvb_pll_tda665x;
33
29int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 34int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
30 u32 freq, int bandwidth); 35 u32 freq, int bandwidth);
31 36
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 6c05fddb69ab..f9383e7f34ff 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -7,6 +7,19 @@ menu "Video For Linux"
7 7
8comment "Video Adapters" 8comment "Video Adapters"
9 9
10config CONFIG_TUNER_MULTI_I2C
11 bool "Enable support for multiple I2C devices on Video Adapters (EXPERIMENTAL)"
12 depends on VIDEO_DEV && EXPERIMENTAL
13 ---help---
14 Some video adapters have more than one tuner inside. This patch
15 enables support for using more than one tuner. This is required
16 for some cards to allow tunning both video and radio.
17 It also improves I2C autodetection for these cards.
18
19 Only few tuners currently is supporting this. More to come.
20
21 It is safe to say 'Y' here even if your card has only one I2C tuner.
22
10config VIDEO_BT848 23config VIDEO_BT848
11 tristate "BT848 Video For Linux" 24 tristate "BT848 Video For Linux"
12 depends on VIDEO_DEV && PCI && I2C 25 depends on VIDEO_DEV && PCI && I2C
@@ -330,6 +343,7 @@ config VIDEO_CX88_DVB
330 select VIDEO_BUF_DVB 343 select VIDEO_BUF_DVB
331 select DVB_MT352 344 select DVB_MT352
332 select DVB_OR51132 345 select DVB_OR51132
346 select DVB_CX22702
333 ---help--- 347 ---help---
334 This adds support for DVB/ATSC cards based on the 348 This adds support for DVB/ATSC cards based on the
335 Connexant 2388x chip. 349 Connexant 2388x chip.
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 07f72f64c5f7..9a642c7de545 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -6,7 +6,7 @@
6 It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly 6 It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
7 connected to bt848/bt878 GPIO pins on this purpose. 7 connected to bt848/bt878 GPIO pins on this purpose.
8 (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets) 8 (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)
9 9
10 Supported Cards: 10 Supported Cards:
11 - Pixelview Rev.4E: 0x8a 11 - Pixelview Rev.4E: 0x8a
12 GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 ! 12 GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !
@@ -31,8 +31,8 @@
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include "id.h" 34#include <media/audiochip.h>
35#include "audiochip.h" 35#include <media/id.h>
36#include "bttv.h" 36#include "bttv.h"
37#include "bt832.h" 37#include "bt832.h"
38 38
@@ -95,7 +95,7 @@ int bt832_init(struct i2c_client *i2c_client_s)
95 95
96 buf=kmalloc(65,GFP_KERNEL); 96 buf=kmalloc(65,GFP_KERNEL);
97 bt832_hexdump(i2c_client_s,buf); 97 bt832_hexdump(i2c_client_s,buf);
98 98
99 if(buf[0x40] != 0x31) { 99 if(buf[0x40] != 0x31) {
100 printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]); 100 printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
101 kfree(buf); 101 kfree(buf);
@@ -135,7 +135,7 @@ int bt832_init(struct i2c_client *i2c_client_s)
135 buf[1]= 0x27 & (~0x01); // Default | !skip 135 buf[1]= 0x27 & (~0x01); // Default | !skip
136 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 136 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
137 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); 137 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
138 138
139 bt832_hexdump(i2c_client_s,buf); 139 bt832_hexdump(i2c_client_s,buf);
140 140
141#if 0 141#if 0
@@ -168,8 +168,7 @@ int bt832_init(struct i2c_client *i2c_client_s)
168 168
169 169
170 170
171static int bt832_attach(struct i2c_adapter *adap, int addr, 171static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
172 unsigned short flags, int kind)
173{ 172{
174 struct bt832 *t; 173 struct bt832 *t;
175 174
@@ -184,27 +183,32 @@ static int bt832_attach(struct i2c_adapter *adap, int addr,
184 return -ENOMEM; 183 return -ENOMEM;
185 memset(t,0,sizeof(*t)); 184 memset(t,0,sizeof(*t));
186 t->client = client_template; 185 t->client = client_template;
187 t->client.data = t; 186 i2c_set_clientdata(&t->client, t);
188 i2c_attach_client(&t->client); 187 i2c_attach_client(&t->client);
189 188
190 if(! bt832_init(&t->client)) { 189 if(! bt832_init(&t->client)) {
191 bt832_detach(&t->client); 190 bt832_detach(&t->client);
192 return -1; 191 return -1;
193 } 192 }
194 193
195 return 0; 194 return 0;
196} 195}
197 196
198static int bt832_probe(struct i2c_adapter *adap) 197static int bt832_probe(struct i2c_adapter *adap)
199{ 198{
199#ifdef I2C_CLASS_TV_ANALOG
200 if (adap->class & I2C_CLASS_TV_ANALOG) 200 if (adap->class & I2C_CLASS_TV_ANALOG)
201 return i2c_probe(adap, &addr_data, bt832_attach); 201 return i2c_probe(adap, &addr_data, bt832_attach);
202#else
203 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
204 return i2c_probe(adap, &addr_data, bt832_attach);
205#endif
202 return 0; 206 return 0;
203} 207}
204 208
205static int bt832_detach(struct i2c_client *client) 209static int bt832_detach(struct i2c_client *client)
206{ 210{
207 struct bt832 *t = (struct bt832*)client->data; 211 struct bt832 *t = i2c_get_clientdata(client);
208 212
209 printk("bt832: detach.\n"); 213 printk("bt832: detach.\n");
210 i2c_detach_client(client); 214 i2c_detach_client(client);
@@ -215,7 +219,7 @@ static int bt832_detach(struct i2c_client *client)
215static int 219static int
216bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) 220bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
217{ 221{
218 struct bt832 *t = (struct bt832*)client->data; 222 struct bt832 *t = i2c_get_clientdata(client);
219 223
220 printk("bt832: command %x\n",cmd); 224 printk("bt832: command %x\n",cmd);
221 225
@@ -249,19 +253,18 @@ static struct i2c_driver driver = {
249}; 253};
250static struct i2c_client client_template = 254static struct i2c_client client_template =
251{ 255{
252 .name = "bt832", 256 I2C_DEVNAME("bt832"),
253 .flags = I2C_CLIENT_ALLOW_USE, 257 .flags = I2C_CLIENT_ALLOW_USE,
254 .driver = &driver, 258 .driver = &driver,
255}; 259};
256 260
257 261
258int bt832_init_module(void) 262static int __init bt832_init_module(void)
259{ 263{
260 i2c_add_driver(&driver); 264 return i2c_add_driver(&driver);
261 return 0;
262} 265}
263 266
264static void bt832_cleanup_module(void) 267static void __exit bt832_cleanup_module(void)
265{ 268{
266 i2c_del_driver(&driver); 269 i2c_del_driver(&driver);
267} 270}
@@ -269,3 +272,10 @@ static void bt832_cleanup_module(void)
269module_init(bt832_init_module); 272module_init(bt832_init_module);
270module_exit(bt832_cleanup_module); 273module_exit(bt832_cleanup_module);
271 274
275/*
276 * Overrides for Emacs so that we follow Linus's tabbing style.
277 * ---------------------------------------------------------------------------
278 * Local variables:
279 * c-basic-offset: 8
280 * End:
281 */
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
index 7a98c06e0e34..9b6a8d2c96b5 100644
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -1,6 +1,6 @@
1/* Bt832 CMOS Camera Video Processor (VP) 1/* Bt832 CMOS Camera Video Processor (VP)
2 2
3 The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS 3 The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
4 color digital camera directly to video capture devices via an 8-bit, 4 color digital camera directly to video capture devices via an 8-bit,
5 4:2:2 YUV or YCrCb video interface. 5 4:2:2 YUV or YCrCb video interface.
6 6
@@ -85,7 +85,7 @@
85#define BT832_DEVICE_ID 63 85#define BT832_DEVICE_ID 63
86# define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31 86# define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31
87 87
88/* STMicroelectronivcs VV5404 camera module 88/* STMicroelectronivcs VV5404 camera module
89 i2c: 0x20: sensor address 89 i2c: 0x20: sensor address
90 i2c: 0xa0: eeprom for ccd defect map 90 i2c: 0xa0: eeprom for ccd defect map
91 */ 91 */
@@ -256,26 +256,26 @@ For the CCIR-601 standards, the sampling is based on a static orthogonal samplin
256//=========================================================================== 256//===========================================================================
257// Timing generator SRAM table values for CCIR601 720x480 NTSC 257// Timing generator SRAM table values for CCIR601 720x480 NTSC
258//=========================================================================== 258//===========================================================================
259// For NTSC CCIR656 259// For NTSC CCIR656
260BYTE BtCard::SRAMTable_NTSC[] = 260BYTE BtCard::SRAMTable_NTSC[] =
261{ 261{
262 // SRAM Timing Table for NTSC 262 // SRAM Timing Table for NTSC
263 0x0c, 0xc0, 0x00, 263 0x0c, 0xc0, 0x00,
264 0x00, 0x90, 0xc2, 264 0x00, 0x90, 0xc2,
265 0x03, 0x10, 0x03, 265 0x03, 0x10, 0x03,
266 0x06, 0x10, 0x34, 266 0x06, 0x10, 0x34,
267 0x12, 0x12, 0x65, 267 0x12, 0x12, 0x65,
268 0x02, 0x13, 0x24, 268 0x02, 0x13, 0x24,
269 0x19, 0x00, 0x24, 269 0x19, 0x00, 0x24,
270 0x39, 0x00, 0x96, 270 0x39, 0x00, 0x96,
271 0x59, 0x08, 0x93, 271 0x59, 0x08, 0x93,
272 0x83, 0x08, 0x97, 272 0x83, 0x08, 0x97,
273 0x03, 0x50, 0x30, 273 0x03, 0x50, 0x30,
274 0xc0, 0x40, 0x30, 274 0xc0, 0x40, 0x30,
275 0x86, 0x01, 0x01, 275 0x86, 0x01, 0x01,
276 0xa6, 0x0d, 0x62, 276 0xa6, 0x0d, 0x62,
277 0x03, 0x11, 0x61, 277 0x03, 0x11, 0x61,
278 0x05, 0x37, 0x30, 278 0x05, 0x37, 0x30,
279 0xac, 0x21, 0x50 279 0xac, 0x21, 0x50
280}; 280};
281 281
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 6334122704ae..251092e7f19f 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -1,5 +1,5 @@
1/* 1/*
2 $Id: bttv-cards.c,v 1.47 2005/02/22 14:06:32 kraxel Exp $ 2 $Id: bttv-cards.c,v 1.49 2005/06/10 17:20:24 mchehab Exp $
3 3
4 bttv-cards.c 4 bttv-cards.c
5 5
@@ -51,6 +51,7 @@ static void avermedia_eeprom(struct bttv *btv);
51static void osprey_eeprom(struct bttv *btv); 51static void osprey_eeprom(struct bttv *btv);
52static void modtec_eeprom(struct bttv *btv); 52static void modtec_eeprom(struct bttv *btv);
53static void init_PXC200(struct bttv *btv); 53static void init_PXC200(struct bttv *btv);
54static void init_RTV24(struct bttv *btv);
54 55
55static void winview_audio(struct bttv *btv, struct video_audio *v, int set); 56static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
56static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set); 57static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
@@ -2251,6 +2252,20 @@ struct tvcard bttv_tvcards[] = {
2251 .no_tda7432 = 1, 2252 .no_tda7432 = 1,
2252 .no_tda9875 = 1, 2253 .no_tda9875 = 1,
2253 .muxsel_hook = kodicom4400r_muxsel, 2254 .muxsel_hook = kodicom4400r_muxsel,
2255},
2256{
2257 /* ---- card 0x85---------------------------------- */
2258 /* Michael Henson <mhenson@clarityvi.com> */
2259 /* Adlink RTV24 with special unlock codes */
2260 .name = "Adlink RTV24",
2261 .video_inputs = 4,
2262 .audio_inputs = 1,
2263 .tuner = 0,
2264 .svhs = 2,
2265 .muxsel = { 2, 3, 1, 0},
2266 .tuner_type = -1,
2267 .pll = PLL_28,
2268
2254}}; 2269}};
2255 2270
2256static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2271static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -2636,6 +2651,10 @@ void __devinit bttv_init_card1(struct bttv *btv)
2636 case BTTV_AVDVBT_771: 2651 case BTTV_AVDVBT_771:
2637 btv->use_i2c_hw = 1; 2652 btv->use_i2c_hw = 1;
2638 break; 2653 break;
2654 case BTTV_ADLINK_RTV24:
2655 init_RTV24( btv );
2656 break;
2657
2639 } 2658 }
2640 if (!bttv_tvcards[btv->c.type].has_dvb) 2659 if (!bttv_tvcards[btv->c.type].has_dvb)
2641 bttv_reset_audio(btv); 2660 bttv_reset_audio(btv);
@@ -2784,6 +2803,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
2784 } 2803 }
2785 btv->pll.pll_current = -1; 2804 btv->pll.pll_current = -1;
2786 2805
2806 bttv_reset_audio(btv);
2807
2787 /* tuner configuration (from card list / autodetect / insmod option) */ 2808 /* tuner configuration (from card list / autodetect / insmod option) */
2788 if (UNSET != bttv_tvcards[btv->c.type].tuner_type) 2809 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2789 if(UNSET == btv->tuner_type) 2810 if(UNSET == btv->tuner_type)
@@ -3304,6 +3325,83 @@ static void __devinit init_PXC200(struct bttv *btv)
3304} 3325}
3305 3326
3306 3327
3328
3329/* ----------------------------------------------------------------------- */
3330/*
3331 * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock
3332 * it. This apparently involves the following procedure for each 878 chip:
3333 *
3334 * 1) write 0x00C3FEFF to the GPIO_OUT_EN register
3335 *
3336 * 2) write to GPIO_DATA
3337 * - 0x0E
3338 * - sleep 1ms
3339 * - 0x10 + 0x0E
3340 * - sleep 10ms
3341 * - 0x0E
3342 * read from GPIO_DATA into buf (uint_32)
3343 * - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 )
3344 * error. ERROR_CPLD_Check_Failed stop.
3345 *
3346 * 3) write to GPIO_DATA
3347 * - write 0x4400 + 0x0E
3348 * - sleep 10ms
3349 * - write 0x4410 + 0x0E
3350 * - sleep 1ms
3351 * - write 0x0E
3352 * read from GPIO_DATA into buf (uint_32)
3353 * - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 )
3354 * error. ERROR_CPLD_Check_Failed.
3355 */
3356/* ----------------------------------------------------------------------- */
3357void
3358init_RTV24 (struct bttv *btv)
3359{
3360 uint32_t dataRead = 0;
3361 long watchdog_value = 0x0E;
3362
3363 printk (KERN_INFO
3364 "bttv%d: Adlink RTV-24 initialisation in progress ...\n",
3365 btv->c.nr);
3366
3367 btwrite (0x00c3feff, BT848_GPIO_OUT_EN);
3368
3369 btwrite (0 + watchdog_value, BT848_GPIO_DATA);
3370 msleep (1);
3371 btwrite (0x10 + watchdog_value, BT848_GPIO_DATA);
3372 msleep (10);
3373 btwrite (0 + watchdog_value, BT848_GPIO_DATA);
3374
3375 dataRead = btread (BT848_GPIO_DATA);
3376
3377 if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 1)) {
3378 printk (KERN_INFO
3379 "bttv%d: Adlink RTV-24 initialisation(1) ERROR_CPLD_Check_Failed (read %d)\n",
3380 btv->c.nr, dataRead);
3381 }
3382
3383 btwrite (0x4400 + watchdog_value, BT848_GPIO_DATA);
3384 msleep (10);
3385 btwrite (0x4410 + watchdog_value, BT848_GPIO_DATA);
3386 msleep (1);
3387 btwrite (watchdog_value, BT848_GPIO_DATA);
3388 msleep (1);
3389 dataRead = btread (BT848_GPIO_DATA);
3390
3391 if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 0)) {
3392 printk (KERN_INFO
3393 "bttv%d: Adlink RTV-24 initialisation(2) ERROR_CPLD_Check_Failed (read %d)\n",
3394 btv->c.nr, dataRead);
3395
3396 return;
3397 }
3398
3399 printk (KERN_INFO
3400 "bttv%d: Adlink RTV-24 initialisation complete.\n", btv->c.nr);
3401}
3402
3403
3404
3307/* ----------------------------------------------------------------------- */ 3405/* ----------------------------------------------------------------------- */
3308/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ 3406/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
3309/* 3407/*
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 033cc5498f23..290289a99757 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1,5 +1,5 @@
1/* 1/*
2 $Id: bttv-driver.c,v 1.37 2005/02/21 13:57:59 kraxel Exp $ 2 $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $
3 3
4 bttv - Bt848 frame grabber driver 4 bttv - Bt848 frame grabber driver
5 5
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index c2368bc832ed..da448a5f9e9c 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -1,5 +1,5 @@
1/* 1/*
2 $Id: bttv-i2c.c,v 1.18 2005/02/16 12:14:10 kraxel Exp $ 2 $Id: bttv-i2c.c,v 1.21 2005/06/10 17:20:24 mchehab Exp $
3 3
4 bttv-i2c.c -- all the i2c code is here 4 bttv-i2c.c -- all the i2c code is here
5 5
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index 8322b66e0905..191eaf1714ba 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: bttv.h,v 1.17 2005/02/22 14:06:32 kraxel Exp $ 2 * $Id: bttv.h,v 1.18 2005/05/24 23:41:42 nsh Exp $
3 * 3 *
4 * bttv - Bt848 frame grabber driver 4 * bttv - Bt848 frame grabber driver
5 * 5 *
@@ -135,6 +135,7 @@
135#define BTTV_DVICO_DVBT_LITE 0x80 135#define BTTV_DVICO_DVBT_LITE 0x80
136#define BTTV_TIBET_CS16 0x83 136#define BTTV_TIBET_CS16 0x83
137#define BTTV_KODICOM_4400R 0x84 137#define BTTV_KODICOM_4400R 0x84
138#define BTTV_ADLINK_RTV24 0x85
138 139
139/* i2c address list */ 140/* i2c address list */
140#define I2C_TSA5522 0xc2 141#define I2C_TSA5522 0xc2
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 1a9ba7e1cf51..7b6f1e856028 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -226,10 +226,6 @@ extern int fini_bttv_i2c(struct bttv *btv);
226#define dprintk if (bttv_debug >= 1) printk 226#define dprintk if (bttv_debug >= 1) printk
227#define d2printk if (bttv_debug >= 2) printk 227#define d2printk if (bttv_debug >= 2) printk
228 228
229/* our devices */
230#define BTTV_MAX 16
231extern unsigned int bttv_num;
232
233#define BTTV_MAX_FBUF 0x208000 229#define BTTV_MAX_FBUF 0x208000
234#define VBIBUF_SIZE (2048*VBI_MAXLINES*2) 230#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
235#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ 231#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */
@@ -375,6 +371,10 @@ struct bttv {
375 unsigned int users; 371 unsigned int users;
376 struct bttv_fh init; 372 struct bttv_fh init;
377}; 373};
374
375/* our devices */
376#define BTTV_MAX 16
377extern unsigned int bttv_num;
378extern struct bttv bttvs[BTTV_MAX]; 378extern struct bttv bttvs[BTTV_MAX];
379 379
380/* private ioctls */ 380/* private ioctls */
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 46d6778b863b..91f8afeded88 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-blackbird.c,v 1.26 2005/03/07 15:58:05 kraxel Exp $ 2 * $Id: cx88-blackbird.c,v 1.27 2005/06/03 13:31:50 mchehab Exp $
3 * 3 *
4 * Support for a cx23416 mpeg encoder via cx2388x host port. 4 * Support for a cx23416 mpeg encoder via cx2388x host port.
5 * "blackbird" reference design. 5 * "blackbird" reference design.
@@ -61,37 +61,304 @@ static LIST_HEAD(cx8802_devlist);
61 61
62#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF 62#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
63 63
64/*Firmware API commands*/ 64/* Firmware API commands */
65#define IVTV_API_ENC_PING_FW 0x00000080 65/* #define IVTV_API_STD_TIMEOUT 0x00010000 // 65536, units?? */
66#define IVTV_API_ENC_GETVER 0x000000C4 66#define IVTV_API_STD_TIMEOUT 500
67#define IVTV_API_ENC_HALT_FW 0x000000C3 67
68#define IVTV_API_STD_TIMEOUT 0x00010000 /*units??*/ 68#define BLACKBIRD_API_PING 0x80
69//#define IVTV_API_ASSIGN_PGM_INDEX_INFO 0x000000c7 69#define BLACKBIRD_API_BEGIN_CAPTURE 0x81
70#define IVTV_API_ASSIGN_STREAM_TYPE 0x000000b9 70enum blackbird_capture_type {
71#define IVTV_API_ASSIGN_OUTPUT_PORT 0x000000bb 71 BLACKBIRD_MPEG_CAPTURE,
72#define IVTV_API_ASSIGN_FRAMERATE 0x0000008f 72 BLACKBIRD_RAW_CAPTURE,
73#define IVTV_API_ASSIGN_FRAME_SIZE 0x00000091 73 BLACKBIRD_RAW_PASSTHRU_CAPTURE
74#define IVTV_API_ASSIGN_ASPECT_RATIO 0x00000099 74};
75#define IVTV_API_ASSIGN_BITRATES 0x00000095 75enum blackbird_capture_bits {
76#define IVTV_API_ASSIGN_GOP_PROPERTIES 0x00000097 76 BLACKBIRD_RAW_BITS_NONE = 0x00,
77#define IVTV_API_ASSIGN_3_2_PULLDOWN 0x000000b1 77 BLACKBIRD_RAW_BITS_YUV_CAPTURE = 0x01,
78#define IVTV_API_ASSIGN_GOP_CLOSURE 0x000000c5 78 BLACKBIRD_RAW_BITS_PCM_CAPTURE = 0x02,
79#define IVTV_API_ASSIGN_AUDIO_PROPERTIES 0x000000bd 79 BLACKBIRD_RAW_BITS_VBI_CAPTURE = 0x04,
80#define IVTV_API_ASSIGN_DNR_FILTER_MODE 0x0000009b 80 BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
81#define IVTV_API_ASSIGN_DNR_FILTER_PROPS 0x0000009d 81 BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10
82#define IVTV_API_ASSIGN_CORING_LEVELS 0x0000009f 82};
83#define IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE 0x000000a1 83#define BLACKBIRD_API_END_CAPTURE 0x82
84#define IVTV_API_ASSIGN_FRAME_DROP_RATE 0x000000d0 84enum blackbird_capture_end {
85#define IVTV_API_ASSIGN_PLACEHOLDER 0x000000d8 85 BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */
86#define IVTV_API_MUTE_VIDEO 0x000000d9 86 BLACKBIRD_END_NOW, /* stop immediately, no irq */
87#define IVTV_API_MUTE_AUDIO 0x000000da 87};
88#define IVTV_API_INITIALIZE_INPUT 0x000000cd 88#define BLACKBIRD_API_SET_AUDIO_ID 0x89
89#define IVTV_API_REFRESH_INPUT 0x000000d3 89#define BLACKBIRD_API_SET_VIDEO_ID 0x8B
90#define IVTV_API_ASSIGN_NUM_VSYNC_LINES 0x000000d6 90#define BLACKBIRD_API_SET_PCR_ID 0x8D
91#define IVTV_API_BEGIN_CAPTURE 0x00000081 91#define BLACKBIRD_API_SET_FRAMERATE 0x8F
92//#define IVTV_API_PAUSE_ENCODER 0x000000d2 92enum blackbird_framerate {
93//#define IVTV_API_EVENT_NOTIFICATION 0x000000d5 93 BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */
94#define IVTV_API_END_CAPTURE 0x00000082 94 BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */
95};
96#define BLACKBIRD_API_SET_RESOLUTION 0x91
97#define BLACKBIRD_API_SET_VIDEO_BITRATE 0x95
98enum blackbird_video_bitrate_type {
99 BLACKBIRD_VIDEO_VBR,
100 BLACKBIRD_VIDEO_CBR
101};
102#define BLACKBIRD_PEAK_RATE_DIVISOR 400
103enum blackbird_mux_rate {
104 BLACKBIRD_MUX_RATE_DEFAULT,
105 /* dvd mux rate: multiply by 400 to get the actual rate */
106 BLACKBIRD_MUX_RATE_DVD = 25200
107};
108#define BLACKBIRD_API_SET_GOP_STRUCTURE 0x97
109#define BLACKBIRD_API_SET_ASPECT_RATIO 0x99
110enum blackbird_aspect_ratio {
111 BLACKBIRD_ASPECT_RATIO_FORBIDDEN,
112 BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
113 BLACKBIRD_ASPECT_RATIO_4_3,
114 BLACKBIRD_ASPECT_RATIO_16_9,
115 BLACKBIRD_ASPECT_RATIO_221_100,
116 BLACKBIRD_ASPECT_RATIO_RESERVED
117};
118#define BLACKBIRD_API_SET_DNR_MODE 0x9B
119enum blackbird_dnr_bits {
120 BLACKBIRD_DNR_BITS_MANUAL,
121 BLACKBIRD_DNR_BITS_AUTO_SPATIAL,
122 BLACKBIRD_DNR_BITS_AUTO_TEMPORAL,
123 BLACKBIRD_DNR_BITS_AUTO
124};
125enum blackbird_median_filter {
126 BLACKBIRD_MEDIAN_FILTER_DISABLED,
127 BLACKBIRD_MEDIAN_FILTER_HORIZONTAL,
128 BLACKBIRD_MEDIAN_FILTER_VERTICAL,
129 BLACKBIRD_MEDIAN_FILTER_HV,
130 BLACKBIRD_MEDIAN_FILTER_DIAGONAL
131};
132#define BLACKBIRD_API_SET_MANUAL_DNR 0x9D
133#define BLACKBIRD_API_SET_DNR_MEDIAN 0x9F
134#define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1
135enum blackbird_spatial_filter_luma {
136 BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED,
137 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
138 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT,
139 BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV, /* separable, default */
140 BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM /* symmetric non-separable */
141};
142enum blackbird_spatial_filter_chroma {
143 BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED,
144 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ /* default */
145};
146#define BLACKBIRD_API_SET_3_2_PULLDOWN 0xB1
147enum blackbird_pulldown {
148 BLACKBIRD_3_2_PULLDOWN_DISABLED,
149 BLACKBIRD_3_2_PULLDOWN_ENABLED
150};
151#define BLACKBIRD_API_SET_VBI_LINE_NO 0xB7
152enum blackbird_vbi_line_bits {
153 BLACKBIRD_VBI_LINE_BITS_TOP_FIELD,
154 BLACKBIRD_VBI_LINE_BITS_BOT_FIELD = (1 << 31),
155 BLACKBIRD_VBI_LINE_BITS_ALL_LINES = 0xFFFFFFFF
156};
157enum blackbird_vbi_line {
158 BLACKBIRD_VBI_LINE_DISABLED,
159 BLACKBIRD_VBI_LINE_ENABLED
160};
161enum blackbird_vbi_slicing {
162 BLACKBIRD_VBI_SLICING_NONE,
163 BLACKBIRD_VBI_SLICING_CLOSED_CAPTION
164};
165#define BLACKBIRD_API_SET_STREAM_TYPE 0xB9
166enum blackbird_stream_type {
167 BLACKBIRD_STREAM_PROGRAM,
168 BLACKBIRD_STREAM_TRANSPORT,
169 BLACKBIRD_STREAM_MPEG1,
170 BLACKBIRD_STREAM_PES_AV,
171 BLACKBIRD_STREAM_UNKNOWN4,
172 BLACKBIRD_STREAM_PES_VIDEO,
173 BLACKBIRD_STREAM_UNKNOWN6,
174 BLACKBIRD_STREAM_PES_AUDIO,
175 BLACKBIRD_STREAM_UNKNOWN8,
176 BLACKBIRD_STREAM_UNKNOWN9, /* audio/pcm ? */
177 BLACKBIRD_STREAM_DVD,
178 BLACKBIRD_STREAM_VCD,
179 BLACKBIRD_STREAM_UNKNOWN12 /* svcd/xvcd ? */
180};
181#define BLACKBIRD_API_SET_OUTPUT_PORT 0xBB
182enum blackbird_stream_port {
183 BLACKBIRD_OUTPUT_PORT_MEMORY,
184 BLACKBIRD_OUTPUT_PORT_STREAMING,
185 BLACKBIRD_OUTPUT_PORT_SERIAL
186};
187#define BLACKBIRD_API_SET_AUDIO_PARAMS 0xBD
188enum blackbird_audio_bits_sample_rate {
189 BLACKBIRD_AUDIO_BITS_44100HZ,
190 BLACKBIRD_AUDIO_BITS_48000HZ,
191 BLACKBIRD_AUDIO_BITS_32000HZ,
192 BLACKBIRD_AUDIO_BITS_RESERVED_HZ,
193};
194enum blackbird_audio_bits_encoding {
195 BLACKBIRD_AUDIO_BITS_LAYER_1 = 0x1 << 2,
196 BLACKBIRD_AUDIO_BITS_LAYER_2 = 0x2 << 2,
197};
198enum blackbird_audio_bits_bitrate_layer_1 {
199 BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT,
200 BLACKBIRD_AUDIO_BITS_LAYER_1_32 = 0x01 << 4,
201 BLACKBIRD_AUDIO_BITS_LAYER_1_64 = 0x02 << 4,
202 BLACKBIRD_AUDIO_BITS_LAYER_1_96 = 0x03 << 4,
203 BLACKBIRD_AUDIO_BITS_LAYER_1_128 = 0x04 << 4,
204 BLACKBIRD_AUDIO_BITS_LAYER_1_160 = 0x05 << 4,
205 BLACKBIRD_AUDIO_BITS_LAYER_1_192 = 0x06 << 4,
206 BLACKBIRD_AUDIO_BITS_LAYER_1_224 = 0x07 << 4,
207 BLACKBIRD_AUDIO_BITS_LAYER_1_256 = 0x08 << 4,
208 BLACKBIRD_AUDIO_BITS_LAYER_1_288 = 0x09 << 4,
209 BLACKBIRD_AUDIO_BITS_LAYER_1_320 = 0x0A << 4,
210 BLACKBIRD_AUDIO_BITS_LAYER_1_352 = 0x0B << 4,
211 BLACKBIRD_AUDIO_BITS_LAYER_1_384 = 0x0C << 4,
212 BLACKBIRD_AUDIO_BITS_LAYER_1_416 = 0x0D << 4,
213 BLACKBIRD_AUDIO_BITS_LAYER_1_448 = 0x0E << 4,
214};
215enum blackbird_audio_bits_bitrate_layer_2 {
216 BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT,
217 BLACKBIRD_AUDIO_BITS_LAYER_2_32 = 0x01 << 4,
218 BLACKBIRD_AUDIO_BITS_LAYER_2_48 = 0x02 << 4,
219 BLACKBIRD_AUDIO_BITS_LAYER_2_56 = 0x03 << 4,
220 BLACKBIRD_AUDIO_BITS_LAYER_2_64 = 0x04 << 4,
221 BLACKBIRD_AUDIO_BITS_LAYER_2_80 = 0x05 << 4,
222 BLACKBIRD_AUDIO_BITS_LAYER_2_96 = 0x06 << 4,
223 BLACKBIRD_AUDIO_BITS_LAYER_2_112 = 0x07 << 4,
224 BLACKBIRD_AUDIO_BITS_LAYER_2_128 = 0x08 << 4,
225 BLACKBIRD_AUDIO_BITS_LAYER_2_160 = 0x09 << 4,
226 BLACKBIRD_AUDIO_BITS_LAYER_2_192 = 0x0A << 4,
227 BLACKBIRD_AUDIO_BITS_LAYER_2_224 = 0x0B << 4,
228 BLACKBIRD_AUDIO_BITS_LAYER_2_256 = 0x0C << 4,
229 BLACKBIRD_AUDIO_BITS_LAYER_2_320 = 0x0D << 4,
230 BLACKBIRD_AUDIO_BITS_LAYER_2_384 = 0x0E << 4,
231};
232enum blackbird_audio_bits_mode {
233 BLACKBIRD_AUDIO_BITS_STEREO,
234 BLACKBIRD_AUDIO_BITS_JOINT_STEREO = 0x1 << 8,
235 BLACKBIRD_AUDIO_BITS_DUAL = 0x2 << 8,
236 BLACKBIRD_AUDIO_BITS_MONO = 0x3 << 8,
237};
238enum blackbird_audio_bits_mode_extension {
239 BLACKBIRD_AUDIO_BITS_BOUND_4,
240 BLACKBIRD_AUDIO_BITS_BOUND_8 = 0x1 << 10,
241 BLACKBIRD_AUDIO_BITS_BOUND_12 = 0x2 << 10,
242 BLACKBIRD_AUDIO_BITS_BOUND_16 = 0x3 << 10,
243};
244enum blackbird_audio_bits_emphasis {
245 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE,
246 BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15 = 0x1 << 12,
247 BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED = 0x2 << 12,
248 BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17 = 0x3 << 12,
249};
250enum blackbird_audio_bits_crc {
251 BLACKBIRD_AUDIO_BITS_CRC_OFF,
252 BLACKBIRD_AUDIO_BITS_CRC_ON = 0x1 << 14,
253};
254enum blackbird_audio_bits_copyright {
255 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF,
256 BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON = 0x1 << 15,
257};
258enum blackbird_audio_bits_original {
259 BLACKBIRD_AUDIO_BITS_COPY,
260 BLACKBIRD_AUDIO_BITS_ORIGINAL = 0x1 << 16,
261};
262#define BLACKBIRD_API_HALT 0xC3
263#define BLACKBIRD_API_GET_VERSION 0xC4
264#define BLACKBIRD_API_SET_GOP_CLOSURE 0xC5
265enum blackbird_gop_closure {
266 BLACKBIRD_GOP_CLOSURE_OFF,
267 BLACKBIRD_GOP_CLOSURE_ON,
268};
269#define BLACKBIRD_API_DATA_XFER_STATUS 0xC6
270enum blackbird_data_xfer_status {
271 BLACKBIRD_MORE_BUFFERS_FOLLOW,
272 BLACKBIRD_LAST_BUFFER,
273};
274#define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7
275enum blackbird_picture_mask {
276 BLACKBIRD_PICTURE_MASK_NONE,
277 BLACKBIRD_PICTURE_MASK_I_FRAMES,
278 BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3,
279 BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7,
280};
281#define BLACKBIRD_API_SET_VBI_PARAMS 0xC8
282enum blackbird_vbi_mode_bits {
283 BLACKBIRD_VBI_BITS_SLICED,
284 BLACKBIRD_VBI_BITS_RAW,
285};
286enum blackbird_vbi_insertion_bits {
287 BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
288 BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
289 BLACKBIRD_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
290 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
291 BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
292};
293#define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9
294enum blackbird_dma_unit {
295 BLACKBIRD_DMA_BYTES,
296 BLACKBIRD_DMA_FRAMES,
297};
298#define BLACKBIRD_API_DMA_TRANSFER_INFO 0xCA
299#define BLACKBIRD_API_DMA_TRANSFER_STAT 0xCB
300enum blackbird_dma_transfer_status_bits {
301 BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01,
302 BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04,
303 BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
304};
305#define BLACKBIRD_API_SET_DMA2HOST_ADDR 0xCC
306#define BLACKBIRD_API_INIT_VIDEO_INPUT 0xCD
307#define BLACKBIRD_API_SET_FRAMESKIP 0xD0
308#define BLACKBIRD_API_PAUSE 0xD2
309enum blackbird_pause {
310 BLACKBIRD_PAUSE_ENCODING,
311 BLACKBIRD_RESUME_ENCODING,
312};
313#define BLACKBIRD_API_REFRESH_INPUT 0xD3
314#define BLACKBIRD_API_SET_COPYRIGHT 0xD4
315enum blackbird_copyright {
316 BLACKBIRD_COPYRIGHT_OFF,
317 BLACKBIRD_COPYRIGHT_ON,
318};
319#define BLACKBIRD_API_SET_NOTIFICATION 0xD5
320enum blackbird_notification_type {
321 BLACKBIRD_NOTIFICATION_REFRESH,
322};
323enum blackbird_notification_status {
324 BLACKBIRD_NOTIFICATION_OFF,
325 BLACKBIRD_NOTIFICATION_ON,
326};
327enum blackbird_notification_mailbox {
328 BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1,
329};
330#define BLACKBIRD_API_SET_CAPTURE_LINES 0xD6
331enum blackbird_field1_lines {
332 BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */
333 BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */
334 BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */
335};
336enum blackbird_field2_lines {
337 BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */
338 BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */
339 BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */
340};
341#define BLACKBIRD_API_SET_CUSTOM_DATA 0xD7
342enum blackbird_custom_data_type {
343 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
344 BLACKBIRD_CUSTOM_PRIVATE_PACKET,
345};
346#define BLACKBIRD_API_MUTE_VIDEO 0xD9
347enum blackbird_mute {
348 BLACKBIRD_UNMUTE,
349 BLACKBIRD_MUTE,
350};
351enum blackbird_mute_video_mask {
352 BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00,
353 BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000,
354 BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000,
355};
356enum blackbird_mute_video_shift {
357 BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8,
358 BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16,
359 BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24,
360};
361#define BLACKBIRD_API_MUTE_AUDIO 0xDA
95 362
96/* Registers */ 363/* Registers */
97#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/) 364#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
@@ -405,68 +672,100 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
405 return 0; 672 return 0;
406} 673}
407 674
675/**
676 Settings used by the windows tv app for PVR2000:
677=================================================================================================================
678Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode
679-----------------------------------------------------------------------------------------------------------------
680MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
681MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
682VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
683DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
684DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
685=================================================================================================================
686*DB: "DirectBurn"
687*/
408static void blackbird_codec_settings(struct cx8802_dev *dev) 688static void blackbird_codec_settings(struct cx8802_dev *dev)
409{ 689{
410 int bitrate_mode = 1; 690 int bitrate_mode = 1;
411 int bitrate = 7500000; 691 int bitrate = 7500000;
412 int bitrate_peak = 7500000; 692 int bitrate_peak = 7500000;
693#if 1
694 bitrate_mode = BLACKBIRD_VIDEO_CBR;
695 bitrate = 4000*1024;
696 bitrate_peak = 4000*1024;
697#endif
413 698
414 /* assign stream type */ 699 /* assign stream type */
415 blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */ 700 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
416 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */ 701 /* blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_TRANSPORT); */
417 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */
418 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */
419 702
420 /* assign output port */ 703 /* assign output port */
421 blackbird_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */ 704 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
422 705
423 /* assign framerate */ 706 /* assign framerate */
424 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0); 707 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
425 708
426 /* assign frame size */ 709 /* assign frame size */
427 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0, 710 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
428 dev->height, dev->width); 711 dev->height, dev->width);
429 712
430 /* assign aspect ratio */ 713 /* assign aspect ratio */
431 blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2); 714 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3);
432 715
433 /* assign bitrates */ 716 /* assign bitrates */
434 blackbird_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0, 717 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
435 bitrate_mode, /* mode */ 718 bitrate_mode, /* mode */
436 bitrate, /* bps */ 719 bitrate, /* bps */
437 bitrate_peak / 400, /* peak/400 */ 720 bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
438 0, 0x70); /* encoding buffer, ckennedy */ 721 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
439 722
440 /* assign gop properties */ 723 /* assign gop properties */
441 blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3); 724 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3);
442 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1); 725
443 726 /* assign 3 2 pulldown */
444 /* assign 3 2 pulldown */ 727 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED);
445 blackbird_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0); 728
446 729 /* assign audio properties */
447 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ 730 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
448 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); 731 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
732 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
733 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
734 BLACKBIRD_AUDIO_BITS_44100HZ |
735 BLACKBIRD_AUDIO_BITS_LAYER_2 |
736 BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
737 BLACKBIRD_AUDIO_BITS_STEREO |
738 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
739 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
740 BLACKBIRD_AUDIO_BITS_CRC_OFF |
741 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
742 BLACKBIRD_AUDIO_BITS_COPY
743 );
449 744
450 /* assign gop closure */ 745 /* assign gop closure */
451 blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0); 746 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF);
452 747
453 /* assign audio properties */
454 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4));
455 748
456 /* assign dnr filter mode */ 749 /* assign dnr filter mode */
457 blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0); 750 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
751 BLACKBIRD_DNR_BITS_MANUAL,
752 BLACKBIRD_MEDIAN_FILTER_DISABLED
753 );
458 754
459 /* assign dnr filter props*/ 755 /* assign dnr filter props*/
460 blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0); 756 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0);
461 757
462 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ 758 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
463 blackbird_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255); 759 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
464 760
465 /* assign spatial filter type: luma_t: 1 = horiz_only, chroma_t: 1 = horiz_only */ 761 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
466 blackbird_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1); 762 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
763 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
764 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
765 );
467 766
468 /* assign frame drop rate */ 767 /* assign frame drop rate */
469 blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); 768 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
470} 769}
471 770
472static int blackbird_initialize_codec(struct cx8802_dev *dev) 771static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -476,7 +775,7 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
476 int retval; 775 int retval;
477 776
478 dprintk(1,"Initialize codec\n"); 777 dprintk(1,"Initialize codec\n");
479 retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */ 778 retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */
480 if (retval < 0) { 779 if (retval < 0) {
481 /* ping was not successful, reset and upload firmware */ 780 /* ping was not successful, reset and upload firmware */
482 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ 781 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
@@ -491,13 +790,13 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
491 if (dev->mailbox < 0) 790 if (dev->mailbox < 0)
492 return -1; 791 return -1;
493 792
494 retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */ 793 retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */
495 if (retval < 0) { 794 if (retval < 0) {
496 dprintk(0, "ERROR: Firmware ping failed!\n"); 795 dprintk(0, "ERROR: Firmware ping failed!\n");
497 return -1; 796 return -1;
498 } 797 }
499 798
500 retval = blackbird_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &version); 799 retval = blackbird_api_cmd(dev, BLACKBIRD_API_GET_VERSION, 0, 1, &version);
501 if (retval < 0) { 800 if (retval < 0) {
502 dprintk(0, "ERROR: Firmware get encoder version failed!\n"); 801 dprintk(0, "ERROR: Firmware get encoder version failed!\n");
503 return -1; 802 return -1;
@@ -517,25 +816,36 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
517 blackbird_codec_settings(dev); 816 blackbird_codec_settings(dev);
518 msleep(1); 817 msleep(1);
519 818
520 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef); 819 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
521 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0); 820 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
522 //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); 821 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
523 blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 822 blackbird_api_cmd(dev, BLACKBIRD_API_SET_CAPTURE_LINES, 2, 0,
823 BLACKBIRD_FIELD1_SAA7115,
824 BLACKBIRD_FIELD1_SAA7115
825 );
826
827 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
828 blackbird_api_cmd(dev, BLACKBIRD_API_SET_CUSTOM_DATA, 12, 0,
829 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
830 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
524 831
525 blackbird_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */ 832 blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); /* initialize the video input */
526 833
527 msleep(1); 834 msleep(1);
528 835
529 blackbird_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0); 836 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
530 msleep(1); 837 msleep(1);
531 blackbird_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0); 838 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
532 msleep(1); 839 msleep(1);
533 840
534 blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */ 841 /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); // start capturing to the host interface */
535 //blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */ 842 blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0,
536 msleep(1); 843 BLACKBIRD_MPEG_CAPTURE,
844 BLACKBIRD_RAW_BITS_NONE
845 ); /* start capturing to the host interface */
846 msleep(10);
537 847
538 blackbird_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0); 848 blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0);
539 return 0; 849 return 0;
540} 850}
541 851
@@ -709,7 +1019,12 @@ static int mpeg_release(struct inode *inode, struct file *file)
709{ 1019{
710 struct cx8802_fh *fh = file->private_data; 1020 struct cx8802_fh *fh = file->private_data;
711 1021
712 blackbird_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13); 1022 /* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
1023 blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0,
1024 BLACKBIRD_END_NOW,
1025 BLACKBIRD_MPEG_CAPTURE,
1026 BLACKBIRD_RAW_BITS_NONE
1027 );
713 1028
714 /* stop mpeg capture */ 1029 /* stop mpeg capture */
715 if (fh->mpegq.streaming) 1030 if (fh->mpegq.streaming)
@@ -908,4 +1223,5 @@ module_exit(blackbird_fini);
908 * Local variables: 1223 * Local variables:
909 * c-basic-offset: 8 1224 * c-basic-offset: 8
910 * End: 1225 * End:
1226 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
911 */ 1227 */
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 367624822d77..b3fb04356b71 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-cards.c,v 1.66 2005/03/04 09:12:23 kraxel Exp $ 2 * $Id: cx88-cards.c,v 1.76 2005/06/08 01:28:09 mchehab Exp $
3 * 3 *
4 * device driver for Conexant 2388x based TV cards 4 * device driver for Conexant 2388x based TV cards
5 * card-specific stuff. 5 * card-specific stuff.
@@ -35,6 +35,9 @@ struct cx88_board cx88_boards[] = {
35 [CX88_BOARD_UNKNOWN] = { 35 [CX88_BOARD_UNKNOWN] = {
36 .name = "UNKNOWN/GENERIC", 36 .name = "UNKNOWN/GENERIC",
37 .tuner_type = UNSET, 37 .tuner_type = UNSET,
38 .radio_type = UNSET,
39 .tuner_addr = ADDR_UNSET,
40 .radio_addr = ADDR_UNSET,
38 .input = {{ 41 .input = {{
39 .type = CX88_VMUX_COMPOSITE1, 42 .type = CX88_VMUX_COMPOSITE1,
40 .vmux = 0, 43 .vmux = 0,
@@ -52,6 +55,9 @@ struct cx88_board cx88_boards[] = {
52 [CX88_BOARD_HAUPPAUGE] = { 55 [CX88_BOARD_HAUPPAUGE] = {
53 .name = "Hauppauge WinTV 34xxx models", 56 .name = "Hauppauge WinTV 34xxx models",
54 .tuner_type = UNSET, 57 .tuner_type = UNSET,
58 .radio_type = UNSET,
59 .tuner_addr = ADDR_UNSET,
60 .radio_addr = ADDR_UNSET,
55 .tda9887_conf = TDA9887_PRESENT, 61 .tda9887_conf = TDA9887_PRESENT,
56 .input = {{ 62 .input = {{
57 .type = CX88_VMUX_TELEVISION, 63 .type = CX88_VMUX_TELEVISION,
@@ -78,6 +84,9 @@ struct cx88_board cx88_boards[] = {
78 [CX88_BOARD_GDI] = { 84 [CX88_BOARD_GDI] = {
79 .name = "GDI Black Gold", 85 .name = "GDI Black Gold",
80 .tuner_type = UNSET, 86 .tuner_type = UNSET,
87 .radio_type = UNSET,
88 .tuner_addr = ADDR_UNSET,
89 .radio_addr = ADDR_UNSET,
81 .input = {{ 90 .input = {{
82 .type = CX88_VMUX_TELEVISION, 91 .type = CX88_VMUX_TELEVISION,
83 .vmux = 0, 92 .vmux = 0,
@@ -85,7 +94,10 @@ struct cx88_board cx88_boards[] = {
85 }, 94 },
86 [CX88_BOARD_PIXELVIEW] = { 95 [CX88_BOARD_PIXELVIEW] = {
87 .name = "PixelView", 96 .name = "PixelView",
88 .tuner_type = 5, 97 .tuner_type = TUNER_PHILIPS_PAL,
98 .radio_type = UNSET,
99 .tuner_addr = ADDR_UNSET,
100 .radio_addr = ADDR_UNSET,
89 .input = {{ 101 .input = {{
90 .type = CX88_VMUX_TELEVISION, 102 .type = CX88_VMUX_TELEVISION,
91 .vmux = 0, 103 .vmux = 0,
@@ -104,7 +116,10 @@ struct cx88_board cx88_boards[] = {
104 }, 116 },
105 [CX88_BOARD_ATI_WONDER_PRO] = { 117 [CX88_BOARD_ATI_WONDER_PRO] = {
106 .name = "ATI TV Wonder Pro", 118 .name = "ATI TV Wonder Pro",
107 .tuner_type = 44, 119 .tuner_type = TUNER_PHILIPS_4IN1,
120 .radio_type = UNSET,
121 .tuner_addr = ADDR_UNSET,
122 .radio_addr = ADDR_UNSET,
108 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER, 123 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
109 .input = {{ 124 .input = {{
110 .type = CX88_VMUX_TELEVISION, 125 .type = CX88_VMUX_TELEVISION,
@@ -122,7 +137,10 @@ struct cx88_board cx88_boards[] = {
122 }, 137 },
123 [CX88_BOARD_WINFAST2000XP_EXPERT] = { 138 [CX88_BOARD_WINFAST2000XP_EXPERT] = {
124 .name = "Leadtek Winfast 2000XP Expert", 139 .name = "Leadtek Winfast 2000XP Expert",
125 .tuner_type = 44, 140 .tuner_type = TUNER_PHILIPS_4IN1,
141 .radio_type = UNSET,
142 .tuner_addr = ADDR_UNSET,
143 .radio_addr = ADDR_UNSET,
126 .tda9887_conf = TDA9887_PRESENT, 144 .tda9887_conf = TDA9887_PRESENT,
127 .input = {{ 145 .input = {{
128 .type = CX88_VMUX_TELEVISION, 146 .type = CX88_VMUX_TELEVISION,
@@ -156,7 +174,10 @@ struct cx88_board cx88_boards[] = {
156 }, 174 },
157 [CX88_BOARD_AVERTV_303] = { 175 [CX88_BOARD_AVERTV_303] = {
158 .name = "AverTV Studio 303 (M126)", 176 .name = "AverTV Studio 303 (M126)",
159 .tuner_type = 38, 177 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
178 .radio_type = UNSET,
179 .tuner_addr = ADDR_UNSET,
180 .radio_addr = ADDR_UNSET,
160 .tda9887_conf = TDA9887_PRESENT, 181 .tda9887_conf = TDA9887_PRESENT,
161 .input = {{ 182 .input = {{
162 .type = CX88_VMUX_TELEVISION, 183 .type = CX88_VMUX_TELEVISION,
@@ -179,7 +200,10 @@ struct cx88_board cx88_boards[] = {
179 // added gpio values thanks to Michal 200 // added gpio values thanks to Michal
180 // values for PAL from DScaler 201 // values for PAL from DScaler
181 .name = "MSI TV-@nywhere Master", 202 .name = "MSI TV-@nywhere Master",
182 .tuner_type = 33, 203 .tuner_type = TUNER_MT2032,
204 .radio_type = UNSET,
205 .tuner_addr = ADDR_UNSET,
206 .radio_addr = ADDR_UNSET,
183 .tda9887_conf = TDA9887_PRESENT, 207 .tda9887_conf = TDA9887_PRESENT,
184 .input = {{ 208 .input = {{
185 .type = CX88_VMUX_TELEVISION, 209 .type = CX88_VMUX_TELEVISION,
@@ -206,7 +230,10 @@ struct cx88_board cx88_boards[] = {
206 }, 230 },
207 [CX88_BOARD_WINFAST_DV2000] = { 231 [CX88_BOARD_WINFAST_DV2000] = {
208 .name = "Leadtek Winfast DV2000", 232 .name = "Leadtek Winfast DV2000",
209 .tuner_type = 38, 233 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
234 .radio_type = UNSET,
235 .tuner_addr = ADDR_UNSET,
236 .radio_addr = ADDR_UNSET,
210 .tda9887_conf = TDA9887_PRESENT, 237 .tda9887_conf = TDA9887_PRESENT,
211 .input = {{ 238 .input = {{
212 .type = CX88_VMUX_TELEVISION, 239 .type = CX88_VMUX_TELEVISION,
@@ -239,34 +266,40 @@ struct cx88_board cx88_boards[] = {
239 .gpio3 = 0x02000000, 266 .gpio3 = 0x02000000,
240 }, 267 },
241 }, 268 },
242 [CX88_BOARD_LEADTEK_PVR2000] = { 269 [CX88_BOARD_LEADTEK_PVR2000] = {
243 // gpio values for PAL version from regspy by DScaler 270 // gpio values for PAL version from regspy by DScaler
244 .name = "Leadtek PVR 2000", 271 .name = "Leadtek PVR 2000",
245 .tuner_type = 38, 272 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
273 .radio_type = UNSET,
274 .tuner_addr = ADDR_UNSET,
275 .radio_addr = ADDR_UNSET,
246 .tda9887_conf = TDA9887_PRESENT, 276 .tda9887_conf = TDA9887_PRESENT,
247 .input = {{ 277 .input = {{
248 .type = CX88_VMUX_TELEVISION, 278 .type = CX88_VMUX_TELEVISION,
249 .vmux = 0, 279 .vmux = 0,
250 .gpio0 = 0x0000bde6, 280 .gpio0 = 0x0000bde2,
251 },{ 281 },{
252 .type = CX88_VMUX_COMPOSITE1, 282 .type = CX88_VMUX_COMPOSITE1,
253 .vmux = 1, 283 .vmux = 1,
254 .gpio0 = 0x0000bde6, 284 .gpio0 = 0x0000bde6,
255 },{ 285 },{
256 .type = CX88_VMUX_SVIDEO, 286 .type = CX88_VMUX_SVIDEO,
257 .vmux = 2, 287 .vmux = 2,
258 .gpio0 = 0x0000bde6, 288 .gpio0 = 0x0000bde6,
259 }}, 289 }},
260 .radio = { 290 .radio = {
261 .type = CX88_RADIO, 291 .type = CX88_RADIO,
262 .gpio0 = 0x0000bd62, 292 .gpio0 = 0x0000bd62,
263 }, 293 },
264 .blackbird = 1, 294 .blackbird = 1,
265 }, 295 },
266 [CX88_BOARD_IODATA_GVVCP3PCI] = { 296 [CX88_BOARD_IODATA_GVVCP3PCI] = {
267 .name = "IODATA GV-VCP3/PCI", 297 .name = "IODATA GV-VCP3/PCI",
268 .tuner_type = TUNER_ABSENT, 298 .tuner_type = TUNER_ABSENT,
269 .input = {{ 299 .radio_type = UNSET,
300 .tuner_addr = ADDR_UNSET,
301 .radio_addr = ADDR_UNSET,
302 .input = {{
270 .type = CX88_VMUX_COMPOSITE1, 303 .type = CX88_VMUX_COMPOSITE1,
271 .vmux = 0, 304 .vmux = 0,
272 },{ 305 },{
@@ -279,7 +312,10 @@ struct cx88_board cx88_boards[] = {
279 }, 312 },
280 [CX88_BOARD_PROLINK_PLAYTVPVR] = { 313 [CX88_BOARD_PROLINK_PLAYTVPVR] = {
281 .name = "Prolink PlayTV PVR", 314 .name = "Prolink PlayTV PVR",
282 .tuner_type = 43, 315 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
316 .radio_type = UNSET,
317 .tuner_addr = ADDR_UNSET,
318 .radio_addr = ADDR_UNSET,
283 .tda9887_conf = TDA9887_PRESENT, 319 .tda9887_conf = TDA9887_PRESENT,
284 .input = {{ 320 .input = {{
285 .type = CX88_VMUX_TELEVISION, 321 .type = CX88_VMUX_TELEVISION,
@@ -301,8 +337,11 @@ struct cx88_board cx88_boards[] = {
301 }, 337 },
302 [CX88_BOARD_ASUS_PVR_416] = { 338 [CX88_BOARD_ASUS_PVR_416] = {
303 .name = "ASUS PVR-416", 339 .name = "ASUS PVR-416",
304 .tuner_type = 43, 340 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
305 .tda9887_conf = TDA9887_PRESENT, 341 .radio_type = UNSET,
342 .tuner_addr = ADDR_UNSET,
343 .radio_addr = ADDR_UNSET,
344 .tda9887_conf = TDA9887_PRESENT,
306 .input = {{ 345 .input = {{
307 .type = CX88_VMUX_TELEVISION, 346 .type = CX88_VMUX_TELEVISION,
308 .vmux = 0, 347 .vmux = 0,
@@ -320,7 +359,10 @@ struct cx88_board cx88_boards[] = {
320 }, 359 },
321 [CX88_BOARD_MSI_TVANYWHERE] = { 360 [CX88_BOARD_MSI_TVANYWHERE] = {
322 .name = "MSI TV-@nywhere", 361 .name = "MSI TV-@nywhere",
323 .tuner_type = 33, 362 .tuner_type = TUNER_MT2032,
363 .radio_type = UNSET,
364 .tuner_addr = ADDR_UNSET,
365 .radio_addr = ADDR_UNSET,
324 .tda9887_conf = TDA9887_PRESENT, 366 .tda9887_conf = TDA9887_PRESENT,
325 .input = {{ 367 .input = {{
326 .type = CX88_VMUX_TELEVISION, 368 .type = CX88_VMUX_TELEVISION,
@@ -342,6 +384,9 @@ struct cx88_board cx88_boards[] = {
342 [CX88_BOARD_KWORLD_DVB_T] = { 384 [CX88_BOARD_KWORLD_DVB_T] = {
343 .name = "KWorld/VStream XPert DVB-T", 385 .name = "KWorld/VStream XPert DVB-T",
344 .tuner_type = TUNER_ABSENT, 386 .tuner_type = TUNER_ABSENT,
387 .radio_type = UNSET,
388 .tuner_addr = ADDR_UNSET,
389 .radio_addr = ADDR_UNSET,
345 .input = {{ 390 .input = {{
346 .type = CX88_VMUX_COMPOSITE1, 391 .type = CX88_VMUX_COMPOSITE1,
347 .vmux = 1, 392 .vmux = 1,
@@ -358,6 +403,9 @@ struct cx88_board cx88_boards[] = {
358 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { 403 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
359 .name = "DVICO FusionHDTV DVB-T1", 404 .name = "DVICO FusionHDTV DVB-T1",
360 .tuner_type = TUNER_ABSENT, /* No analog tuner */ 405 .tuner_type = TUNER_ABSENT, /* No analog tuner */
406 .radio_type = UNSET,
407 .tuner_addr = ADDR_UNSET,
408 .radio_addr = ADDR_UNSET,
361 .input = {{ 409 .input = {{
362 .type = CX88_VMUX_COMPOSITE1, 410 .type = CX88_VMUX_COMPOSITE1,
363 .vmux = 1, 411 .vmux = 1,
@@ -371,7 +419,10 @@ struct cx88_board cx88_boards[] = {
371 }, 419 },
372 [CX88_BOARD_KWORLD_LTV883] = { 420 [CX88_BOARD_KWORLD_LTV883] = {
373 .name = "KWorld LTV883RF", 421 .name = "KWorld LTV883RF",
374 .tuner_type = 48, 422 .tuner_type = TUNER_TNF_8831BGFF,
423 .radio_type = UNSET,
424 .tuner_addr = ADDR_UNSET,
425 .radio_addr = ADDR_UNSET,
375 .input = {{ 426 .input = {{
376 .type = CX88_VMUX_TELEVISION, 427 .type = CX88_VMUX_TELEVISION,
377 .vmux = 0, 428 .vmux = 0,
@@ -397,6 +448,9 @@ struct cx88_board cx88_boards[] = {
397 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = { 448 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = {
398 .name = "DViCO - FusionHDTV 3 Gold", 449 .name = "DViCO - FusionHDTV 3 Gold",
399 .tuner_type = TUNER_MICROTUNE_4042FI5, 450 .tuner_type = TUNER_MICROTUNE_4042FI5,
451 .radio_type = UNSET,
452 .tuner_addr = ADDR_UNSET,
453 .radio_addr = ADDR_UNSET,
400 /* 454 /*
401 GPIO[0] resets DT3302 DTV receiver 455 GPIO[0] resets DT3302 DTV receiver
402 0 - reset asserted 456 0 - reset asserted
@@ -428,17 +482,14 @@ struct cx88_board cx88_boards[] = {
428 .vmux = 2, 482 .vmux = 2,
429 .gpio0 = 0x0f00, 483 .gpio0 = 0x0f00,
430 }}, 484 }},
431#if 0
432 .ts = {
433 .type = CX88_TS,
434 .gpio0 = 0x00000f01, /* Hooked to tuner reset bit */
435 }
436#endif
437 }, 485 },
438 [CX88_BOARD_HAUPPAUGE_DVB_T1] = { 486 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
439 .name = "Hauppauge Nova-T DVB-T", 487 .name = "Hauppauge Nova-T DVB-T",
440 .tuner_type = TUNER_ABSENT, 488 .tuner_type = TUNER_ABSENT,
441 .input = {{ 489 .radio_type = UNSET,
490 .tuner_addr = ADDR_UNSET,
491 .radio_addr = ADDR_UNSET,
492 .input = {{
442 .type = CX88_VMUX_DVB, 493 .type = CX88_VMUX_DVB,
443 .vmux = 0, 494 .vmux = 0,
444 }}, 495 }},
@@ -447,6 +498,9 @@ struct cx88_board cx88_boards[] = {
447 [CX88_BOARD_CONEXANT_DVB_T1] = { 498 [CX88_BOARD_CONEXANT_DVB_T1] = {
448 .name = "Conexant DVB-T reference design", 499 .name = "Conexant DVB-T reference design",
449 .tuner_type = TUNER_ABSENT, 500 .tuner_type = TUNER_ABSENT,
501 .radio_type = UNSET,
502 .tuner_addr = ADDR_UNSET,
503 .radio_addr = ADDR_UNSET,
450 .input = {{ 504 .input = {{
451 .type = CX88_VMUX_DVB, 505 .type = CX88_VMUX_DVB,
452 .vmux = 0, 506 .vmux = 0,
@@ -456,6 +510,9 @@ struct cx88_board cx88_boards[] = {
456 [CX88_BOARD_PROVIDEO_PV259] = { 510 [CX88_BOARD_PROVIDEO_PV259] = {
457 .name = "Provideo PV259", 511 .name = "Provideo PV259",
458 .tuner_type = TUNER_PHILIPS_FQ1216ME, 512 .tuner_type = TUNER_PHILIPS_FQ1216ME,
513 .radio_type = UNSET,
514 .tuner_addr = ADDR_UNSET,
515 .radio_addr = ADDR_UNSET,
459 .input = {{ 516 .input = {{
460 .type = CX88_VMUX_TELEVISION, 517 .type = CX88_VMUX_TELEVISION,
461 .vmux = 0, 518 .vmux = 0,
@@ -465,6 +522,9 @@ struct cx88_board cx88_boards[] = {
465 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = { 522 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
466 .name = "DVICO FusionHDTV DVB-T Plus", 523 .name = "DVICO FusionHDTV DVB-T Plus",
467 .tuner_type = TUNER_ABSENT, /* No analog tuner */ 524 .tuner_type = TUNER_ABSENT, /* No analog tuner */
525 .radio_type = UNSET,
526 .tuner_addr = ADDR_UNSET,
527 .radio_addr = ADDR_UNSET,
468 .input = {{ 528 .input = {{
469 .type = CX88_VMUX_COMPOSITE1, 529 .type = CX88_VMUX_COMPOSITE1,
470 .vmux = 1, 530 .vmux = 1,
@@ -479,6 +539,9 @@ struct cx88_board cx88_boards[] = {
479 [CX88_BOARD_DNTV_LIVE_DVB_T] = { 539 [CX88_BOARD_DNTV_LIVE_DVB_T] = {
480 .name = "digitalnow DNTV Live! DVB-T", 540 .name = "digitalnow DNTV Live! DVB-T",
481 .tuner_type = TUNER_ABSENT, 541 .tuner_type = TUNER_ABSENT,
542 .radio_type = UNSET,
543 .tuner_addr = ADDR_UNSET,
544 .radio_addr = ADDR_UNSET,
482 .input = {{ 545 .input = {{
483 .type = CX88_VMUX_COMPOSITE1, 546 .type = CX88_VMUX_COMPOSITE1,
484 .vmux = 1, 547 .vmux = 1,
@@ -495,6 +558,9 @@ struct cx88_board cx88_boards[] = {
495 [CX88_BOARD_PCHDTV_HD3000] = { 558 [CX88_BOARD_PCHDTV_HD3000] = {
496 .name = "pcHDTV HD3000 HDTV", 559 .name = "pcHDTV HD3000 HDTV",
497 .tuner_type = TUNER_THOMSON_DTT7610, 560 .tuner_type = TUNER_THOMSON_DTT7610,
561 .radio_type = UNSET,
562 .tuner_addr = ADDR_UNSET,
563 .radio_addr = ADDR_UNSET,
498 .input = {{ 564 .input = {{
499 .type = CX88_VMUX_TELEVISION, 565 .type = CX88_VMUX_TELEVISION,
500 .vmux = 0, 566 .vmux = 0,
@@ -530,8 +596,11 @@ struct cx88_board cx88_boards[] = {
530 [CX88_BOARD_HAUPPAUGE_ROSLYN] = { 596 [CX88_BOARD_HAUPPAUGE_ROSLYN] = {
531 // entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu> 597 // entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
532 // GPIO values obtained from regspy, courtesy Sean Covel 598 // GPIO values obtained from regspy, courtesy Sean Covel
533 .name = "Hauppauge WinTV 28xxx (Roslyn) models", 599 .name = "Hauppauge WinTV 28xxx (Roslyn) models",
534 .tuner_type = UNSET, 600 .tuner_type = UNSET,
601 .radio_type = UNSET,
602 .tuner_addr = ADDR_UNSET,
603 .radio_addr = ADDR_UNSET,
535 .input = {{ 604 .input = {{
536 .type = CX88_VMUX_TELEVISION, 605 .type = CX88_VMUX_TELEVISION,
537 .vmux = 0, 606 .vmux = 0,
@@ -559,33 +628,37 @@ struct cx88_board cx88_boards[] = {
559 .blackbird = 1, 628 .blackbird = 1,
560 }, 629 },
561 [CX88_BOARD_DIGITALLOGIC_MEC] = { 630 [CX88_BOARD_DIGITALLOGIC_MEC] = {
562 /* params copied over from Leadtek PVR 2000 */
563 .name = "Digital-Logic MICROSPACE Entertainment Center (MEC)", 631 .name = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
564 /* not sure yet about the tuner type */ 632 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
565 .tuner_type = 38, 633 .radio_type = UNSET,
634 .tuner_addr = ADDR_UNSET,
635 .radio_addr = ADDR_UNSET,
566 .tda9887_conf = TDA9887_PRESENT, 636 .tda9887_conf = TDA9887_PRESENT,
567 .input = {{ 637 .input = {{
568 .type = CX88_VMUX_TELEVISION, 638 .type = CX88_VMUX_TELEVISION,
569 .vmux = 0, 639 .vmux = 0,
570 .gpio0 = 0x0000bde6, 640 .gpio0 = 0x00009d80,
571 },{ 641 },{
572 .type = CX88_VMUX_COMPOSITE1, 642 .type = CX88_VMUX_COMPOSITE1,
573 .vmux = 1, 643 .vmux = 1,
574 .gpio0 = 0x0000bde6, 644 .gpio0 = 0x00009d76,
575 },{ 645 },{
576 .type = CX88_VMUX_SVIDEO, 646 .type = CX88_VMUX_SVIDEO,
577 .vmux = 2, 647 .vmux = 2,
578 .gpio0 = 0x0000bde6, 648 .gpio0 = 0x00009d76,
579 }}, 649 }},
580 .radio = { 650 .radio = {
581 .type = CX88_RADIO, 651 .type = CX88_RADIO,
582 .gpio0 = 0x0000bd62, 652 .gpio0 = 0x00009d00,
583 }, 653 },
584 .blackbird = 1, 654 .blackbird = 1,
585 }, 655 },
586 [CX88_BOARD_IODATA_GVBCTV7E] = { 656 [CX88_BOARD_IODATA_GVBCTV7E] = {
587 .name = "IODATA GV/BCTV7E", 657 .name = "IODATA GV/BCTV7E",
588 .tuner_type = TUNER_PHILIPS_FQ1286, 658 .tuner_type = TUNER_PHILIPS_FQ1286,
659 .radio_type = UNSET,
660 .tuner_addr = ADDR_UNSET,
661 .radio_addr = ADDR_UNSET,
589 .tda9887_conf = TDA9887_PRESENT, 662 .tda9887_conf = TDA9887_PRESENT,
590 .input = {{ 663 .input = {{
591 .type = CX88_VMUX_TELEVISION, 664 .type = CX88_VMUX_TELEVISION,
@@ -601,6 +674,56 @@ struct cx88_board cx88_boards[] = {
601 .gpio1 = 0x0000e07f, 674 .gpio1 = 0x0000e07f,
602 }} 675 }}
603 }, 676 },
677 [CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = {
678 .name = "PixelView PlayTV Ultra Pro (Stereo)",
679 /* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
680 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
681 .radio_type = TUNER_TEA5767,
682 .tuner_addr = 0xc2>>1,
683 .radio_addr = 0xc0>>1,
684 .input = {{
685 .type = CX88_VMUX_TELEVISION,
686 .vmux = 0,
687 .gpio0 = 0xbf61, /* internal decoder */
688 },{
689 .type = CX88_VMUX_COMPOSITE1,
690 .vmux = 1,
691 .gpio0 = 0xbf63,
692 },{
693 .type = CX88_VMUX_SVIDEO,
694 .vmux = 2,
695 .gpio0 = 0xbf63,
696 }},
697 .radio = {
698 .type = CX88_RADIO,
699 .gpio0 = 0xbf60,
700 },
701 },
702 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
703 .name = "DViCO - FusionHDTV 3 Gold-T",
704 .tuner_type = TUNER_THOMSON_DTT7611,
705 .radio_type = UNSET,
706 .tuner_addr = ADDR_UNSET,
707 .radio_addr = ADDR_UNSET,
708 /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */
709 .input = {{
710 .type = CX88_VMUX_TELEVISION,
711 .vmux = 0,
712 .gpio0 = 0x0f0d,
713 },{
714 .type = CX88_VMUX_CABLE,
715 .vmux = 0,
716 .gpio0 = 0x0f05,
717 },{
718 .type = CX88_VMUX_COMPOSITE1,
719 .vmux = 1,
720 .gpio0 = 0x0f00,
721 },{
722 .type = CX88_VMUX_SVIDEO,
723 .vmux = 2,
724 .gpio0 = 0x0f00,
725 }},
726 },
604}; 727};
605const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 728const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
606 729
@@ -673,6 +796,10 @@ struct cx88_subid cx88_subids[] = {
673 .subdevice = 0xd810, 796 .subdevice = 0xd810,
674 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD, 797 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD,
675 },{ 798 },{
799 .subvendor = 0x18ac,
800 .subdevice = 0xd820,
801 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
802 },{
676 .subvendor = 0x18AC, 803 .subvendor = 0x18AC,
677 .subdevice = 0xDB00, 804 .subdevice = 0xDB00,
678 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, 805 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
@@ -935,4 +1062,5 @@ EXPORT_SYMBOL(cx88_card_setup);
935 * Local variables: 1062 * Local variables:
936 * c-basic-offset: 8 1063 * c-basic-offset: 8
937 * End: 1064 * End:
1065 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
938 */ 1066 */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 1ff79b5a8835..c046a23537d3 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $ 2 * $Id: cx88-core.c,v 1.28 2005/06/12 04:19:19 mchehab Exp $
3 * 3 *
4 * device driver for Conexant 2388x based TV cards 4 * device driver for Conexant 2388x based TV cards
5 * driver core 5 * driver core
@@ -51,12 +51,15 @@ module_param(latency,int,0444);
51MODULE_PARM_DESC(latency,"pci latency timer"); 51MODULE_PARM_DESC(latency,"pci latency timer");
52 52
53static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; 53static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
54static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
54static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET }; 55static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
55 56
56module_param_array(tuner, int, NULL, 0444); 57module_param_array(tuner, int, NULL, 0444);
58module_param_array(radio, int, NULL, 0444);
57module_param_array(card, int, NULL, 0444); 59module_param_array(card, int, NULL, 0444);
58 60
59MODULE_PARM_DESC(tuner,"tuner type"); 61MODULE_PARM_DESC(tuner,"tuner type");
62MODULE_PARM_DESC(radio,"radio tuner type");
60MODULE_PARM_DESC(card,"card type"); 63MODULE_PARM_DESC(card,"card type");
61 64
62static unsigned int nicam = 0; 65static unsigned int nicam = 0;
@@ -429,7 +432,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
429/* ------------------------------------------------------------------ */ 432/* ------------------------------------------------------------------ */
430/* debug helper code */ 433/* debug helper code */
431 434
432static int cx88_risc_decode(u32 risc) 435int cx88_risc_decode(u32 risc)
433{ 436{
434 static char *instr[16] = { 437 static char *instr[16] = {
435 [ RISC_SYNC >> 28 ] = "sync", 438 [ RISC_SYNC >> 28 ] = "sync",
@@ -736,6 +739,10 @@ static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
736{ 739{
737 static const unsigned int ntsc = 28636360; 740 static const unsigned int ntsc = 28636360;
738 static const unsigned int pal = 35468950; 741 static const unsigned int pal = 35468950;
742 static const unsigned int palm = 28604892;
743
744 if (norm->id & V4L2_STD_PAL_M)
745 return palm;
739 746
740 return (norm->id & V4L2_STD_625_50) ? pal : ntsc; 747 return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
741} 748}
@@ -749,6 +756,11 @@ static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
749 756
750static unsigned int inline norm_htotal(struct cx88_tvnorm *norm) 757static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
751{ 758{
759 /* Should always be Line Draw Time / (4*FSC) */
760
761 if (norm->id & V4L2_STD_PAL_M)
762 return 909;
763
752 return (norm->id & V4L2_STD_625_50) ? 1135 : 910; 764 return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
753} 765}
754 766
@@ -1164,8 +1176,20 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1164 "insmod option" : "autodetected"); 1176 "insmod option" : "autodetected");
1165 1177
1166 core->tuner_type = tuner[core->nr]; 1178 core->tuner_type = tuner[core->nr];
1179 core->radio_type = radio[core->nr];
1167 if (UNSET == core->tuner_type) 1180 if (UNSET == core->tuner_type)
1168 core->tuner_type = cx88_boards[core->board].tuner_type; 1181 core->tuner_type = cx88_boards[core->board].tuner_type;
1182 if (UNSET == core->radio_type)
1183 core->radio_type = cx88_boards[core->board].radio_type;
1184 if (!core->tuner_addr)
1185 core->tuner_addr = cx88_boards[core->board].tuner_addr;
1186 if (!core->radio_addr)
1187 core->radio_addr = cx88_boards[core->board].radio_addr;
1188
1189 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1190 core->tuner_type, core->tuner_addr<<1,
1191 core->radio_type, core->radio_addr<<1);
1192
1169 core->tda9887_conf = cx88_boards[core->board].tda9887_conf; 1193 core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
1170 1194
1171 /* init hardware */ 1195 /* init hardware */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 9d15d3d5a2b7..1a259c3966cd 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $ 2 * $Id: cx88-dvb.c,v 1.33 2005/06/12 04:19:19 mchehab Exp $
3 * 3 *
4 * device driver for Conexant 2388x based TV cards 4 * device driver for Conexant 2388x based TV cards
5 * MPEG Transport Stream (DVB) routines 5 * MPEG Transport Stream (DVB) routines
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 0725b1288f4f..e20adefcfc6c 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,5 +1,5 @@
1/* 1/*
2 $Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $ 2 $Id: cx88-i2c.c,v 1.23 2005/06/12 04:19:19 mchehab Exp $
3 3
4 cx88-i2c.c -- all the i2c code is here 4 cx88-i2c.c -- all the i2c code is here
5 5
@@ -91,6 +91,7 @@ static int cx8800_bit_getsda(void *data)
91 91
92static int attach_inform(struct i2c_client *client) 92static int attach_inform(struct i2c_client *client)
93{ 93{
94 struct tuner_addr tun_addr;
94 struct cx88_core *core = i2c_get_adapdata(client->adapter); 95 struct cx88_core *core = i2c_get_adapdata(client->adapter);
95 96
96 dprintk(1, "i2c attach [addr=0x%x,client=%s]\n", 97 dprintk(1, "i2c attach [addr=0x%x,client=%s]\n",
@@ -98,8 +99,19 @@ static int attach_inform(struct i2c_client *client)
98 if (!client->driver->command) 99 if (!client->driver->command)
99 return 0; 100 return 0;
100 101
101 if (core->tuner_type != UNSET) 102 if (core->radio_type != UNSET) {
102 client->driver->command(client, TUNER_SET_TYPE, &core->tuner_type); 103 tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
104 tun_addr.type = core->radio_type;
105 tun_addr.addr = core->radio_addr;
106 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
107 }
108 if (core->tuner_type != UNSET) {
109 tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
110 tun_addr.type = core->tuner_type;
111 tun_addr.addr = core->tuner_addr;
112 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
113 }
114
103 if (core->tda9887_conf) 115 if (core->tda9887_conf)
104 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); 116 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
105 return 0; 117 return 0;
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index af6ad8cdbdb7..dc0dcf249aac 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-input.c,v 1.9 2005/03/04 09:12:23 kraxel Exp $ 2 * $Id: cx88-input.c,v 1.11 2005/05/22 20:57:56 nsh Exp $
3 * 3 *
4 * Device driver for GPIO attached remote control interfaces 4 * Device driver for GPIO attached remote control interfaces
5 * on Conexant 2388x based TV/DVB cards. 5 * on Conexant 2388x based TV/DVB cards.
@@ -235,6 +235,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
235 /* detect & configure */ 235 /* detect & configure */
236 switch (core->board) { 236 switch (core->board) {
237 case CX88_BOARD_DNTV_LIVE_DVB_T: 237 case CX88_BOARD_DNTV_LIVE_DVB_T:
238 case CX88_BOARD_KWORLD_DVB_T:
238 ir_codes = ir_codes_dntv_live_dvb_t; 239 ir_codes = ir_codes_dntv_live_dvb_t;
239 ir->gpio_addr = MO_GP1_IO; 240 ir->gpio_addr = MO_GP1_IO;
240 ir->mask_keycode = 0x1f; 241 ir->mask_keycode = 0x1f;
@@ -261,7 +262,15 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
261 ir->mask_keydown = 0x02; 262 ir->mask_keydown = 0x02;
262 ir->polling = 5; // ms 263 ir->polling = 5; // ms
263 break; 264 break;
265 case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
266 ir_codes = ir_codes_pixelview;
267 ir->gpio_addr = MO_GP1_IO;
268 ir->mask_keycode = 0x1f;
269 ir->mask_keyup = 0x80;
270 ir->polling = 1; // ms
271 break;
264 } 272 }
273
265 if (NULL == ir_codes) { 274 if (NULL == ir_codes) {
266 kfree(ir); 275 kfree(ir);
267 return -ENODEV; 276 return -ENODEV;
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 07aae1899e17..9ade2ae91e9b 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $ 2 * $Id: cx88-mpeg.c,v 1.26 2005/06/03 13:31:51 mchehab Exp $
3 * 3 *
4 * Support for the mpeg transport stream transfers 4 * Support for the mpeg transport stream transfers
5 * PCI function #2 of the cx2388x. 5 * PCI function #2 of the cx2388x.
@@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
55{ 55{
56 struct cx88_core *core = dev->core; 56 struct cx88_core *core = dev->core;
57 57
58 dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width); 58 dprintk(0, "cx8802_start_dma %d\n", buf->vb.width);
59 59
60 /* setup fifo + format */ 60 /* setup fifo + format */
61 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 61 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -100,18 +100,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
100 q->count = 1; 100 q->count = 1;
101 101
102 /* enable irqs */ 102 /* enable irqs */
103 dprintk( 0, "setting the interrupt mask\n" );
103 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); 104 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
104 cx_write(MO_TS_INTMSK, 0x1f0011); 105 cx_set(MO_TS_INTMSK, 0x1f0011);
106 //cx_write(MO_TS_INTMSK, 0x0f0011);
105 107
106 /* start dma */ 108 /* start dma */
107 cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */ 109 cx_set(MO_DEV_CNTRL2, (1<<5));
108 cx_write(MO_TS_DMACNTRL, 0x11); 110 cx_set(MO_TS_DMACNTRL, 0x11);
109 return 0; 111 return 0;
110} 112}
111 113
112static int cx8802_stop_dma(struct cx8802_dev *dev) 114static int cx8802_stop_dma(struct cx8802_dev *dev)
113{ 115{
114 struct cx88_core *core = dev->core; 116 struct cx88_core *core = dev->core;
117 dprintk( 0, "cx8802_stop_dma\n" );
115 118
116 /* stop dma */ 119 /* stop dma */
117 cx_clear(MO_TS_DMACNTRL, 0x11); 120 cx_clear(MO_TS_DMACNTRL, 0x11);
@@ -131,8 +134,12 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
131 struct cx88_buffer *buf; 134 struct cx88_buffer *buf;
132 struct list_head *item; 135 struct list_head *item;
133 136
137 dprintk( 0, "cx8802_restart_queue\n" );
134 if (list_empty(&q->active)) 138 if (list_empty(&q->active))
139 {
140 dprintk( 0, "cx8802_restart_queue: queue is empty\n" );
135 return 0; 141 return 0;
142 }
136 143
137 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); 144 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
138 dprintk(2,"restart_queue [%p/%d]: restart dma\n", 145 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
@@ -182,27 +189,32 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
182 struct cx88_buffer *prev; 189 struct cx88_buffer *prev;
183 struct cx88_dmaqueue *q = &dev->mpegq; 190 struct cx88_dmaqueue *q = &dev->mpegq;
184 191
192 dprintk( 1, "cx8802_buf_queue\n" );
185 /* add jump to stopper */ 193 /* add jump to stopper */
186 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); 194 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
187 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); 195 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
188 196
189 if (list_empty(&q->active)) { 197 if (list_empty(&q->active)) {
198 dprintk( 0, "queue is empty - first active\n" );
190 list_add_tail(&buf->vb.queue,&q->active); 199 list_add_tail(&buf->vb.queue,&q->active);
191 cx8802_start_dma(dev, q, buf); 200 cx8802_start_dma(dev, q, buf);
192 buf->vb.state = STATE_ACTIVE; 201 buf->vb.state = STATE_ACTIVE;
193 buf->count = q->count++; 202 buf->count = q->count++;
194 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); 203 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
195 dprintk(2,"[%p/%d] %s - first active\n", 204 dprintk(0,"[%p/%d] %s - first active\n",
196 buf, buf->vb.i, __FUNCTION__); 205 buf, buf->vb.i, __FUNCTION__);
206 //udelay(100);
197 207
198 } else { 208 } else {
209 dprintk( 1, "queue is not empty - append to active\n" );
199 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); 210 prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
200 list_add_tail(&buf->vb.queue,&q->active); 211 list_add_tail(&buf->vb.queue,&q->active);
201 buf->vb.state = STATE_ACTIVE; 212 buf->vb.state = STATE_ACTIVE;
202 buf->count = q->count++; 213 buf->count = q->count++;
203 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 214 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
204 dprintk(2,"[%p/%d] %s - append to active\n", 215 dprintk( 1, "[%p/%d] %s - append to active\n",
205 buf, buf->vb.i, __FUNCTION__); 216 buf, buf->vb.i, __FUNCTION__);
217 //udelay(100);
206 } 218 }
207} 219}
208 220
@@ -224,7 +236,10 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
224 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); 236 buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
225 } 237 }
226 if (restart) 238 if (restart)
239 {
240 dprintk(0, "restarting queue\n" );
227 cx8802_restart_queue(dev,q); 241 cx8802_restart_queue(dev,q);
242 }
228 spin_unlock_irqrestore(&dev->slock,flags); 243 spin_unlock_irqrestore(&dev->slock,flags);
229} 244}
230 245
@@ -232,6 +247,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev)
232{ 247{
233 struct cx88_dmaqueue *q = &dev->mpegq; 248 struct cx88_dmaqueue *q = &dev->mpegq;
234 249
250 dprintk( 1, "cx8802_cancel_buffers" );
235 del_timer_sync(&q->timeout); 251 del_timer_sync(&q->timeout);
236 cx8802_stop_dma(dev); 252 cx8802_stop_dma(dev);
237 do_cancel_buffers(dev,"cancel",0); 253 do_cancel_buffers(dev,"cancel",0);
@@ -241,7 +257,7 @@ static void cx8802_timeout(unsigned long data)
241{ 257{
242 struct cx8802_dev *dev = (struct cx8802_dev*)data; 258 struct cx8802_dev *dev = (struct cx8802_dev*)data;
243 259
244 dprintk(1, "%s\n",__FUNCTION__); 260 dprintk(0, "%s\n",__FUNCTION__);
245 261
246 if (debug) 262 if (debug)
247 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); 263 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
@@ -254,12 +270,17 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
254 struct cx88_core *core = dev->core; 270 struct cx88_core *core = dev->core;
255 u32 status, mask, count; 271 u32 status, mask, count;
256 272
273 dprintk( 1, "cx8802_mpeg_irq\n" );
257 status = cx_read(MO_TS_INTSTAT); 274 status = cx_read(MO_TS_INTSTAT);
258 mask = cx_read(MO_TS_INTMSK); 275 mask = cx_read(MO_TS_INTMSK);
259 if (0 == (status & mask)) 276 if (0 == (status & mask))
260 return; 277 return;
261 278
262 cx_write(MO_TS_INTSTAT, status); 279 cx_write(MO_TS_INTSTAT, status);
280#if 0
281 cx88_print_irqbits(core->name, "irq mpeg ",
282 cx88_mpeg_irqs, status, mask);
283#endif
263 if (debug || (status & mask & ~0xff)) 284 if (debug || (status & mask & ~0xff))
264 cx88_print_irqbits(core->name, "irq mpeg ", 285 cx88_print_irqbits(core->name, "irq mpeg ",
265 cx88_mpeg_irqs, status, mask); 286 cx88_mpeg_irqs, status, mask);
@@ -273,6 +294,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
273 294
274 /* risc1 y */ 295 /* risc1 y */
275 if (status & 0x01) { 296 if (status & 0x01) {
297 dprintk( 1, "wake up\n" );
276 spin_lock(&dev->slock); 298 spin_lock(&dev->slock);
277 count = cx_read(MO_TS_GPCNT); 299 count = cx_read(MO_TS_GPCNT);
278 cx88_wakeup(dev->core, &dev->mpegq, count); 300 cx88_wakeup(dev->core, &dev->mpegq, count);
@@ -288,6 +310,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
288 310
289 /* other general errors */ 311 /* other general errors */
290 if (status & 0x1f0100) { 312 if (status & 0x1f0100) {
313 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
291 spin_lock(&dev->slock); 314 spin_lock(&dev->slock);
292 cx8802_stop_dma(dev); 315 cx8802_stop_dma(dev);
293 cx8802_restart_queue(dev,&dev->mpegq); 316 cx8802_restart_queue(dev,&dev->mpegq);
@@ -295,6 +318,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
295 } 318 }
296} 319}
297 320
321#define MAX_IRQ_LOOP 10
322
298static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) 323static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
299{ 324{
300 struct cx8802_dev *dev = dev_id; 325 struct cx8802_dev *dev = dev_id;
@@ -302,10 +327,13 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
302 u32 status; 327 u32 status;
303 int loop, handled = 0; 328 int loop, handled = 0;
304 329
305 for (loop = 0; loop < 10; loop++) { 330 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
306 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04); 331 status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
307 if (0 == status) 332 if (0 == status)
308 goto out; 333 goto out;
334 dprintk( 1, "cx8802_irq\n" );
335 dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
336 dprintk( 1, " status: %d\n", status );
309 handled = 1; 337 handled = 1;
310 cx_write(MO_PCI_INTSTAT, status); 338 cx_write(MO_PCI_INTSTAT, status);
311 339
@@ -314,7 +342,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
314 if (status & 0x04) 342 if (status & 0x04)
315 cx8802_mpeg_irq(dev); 343 cx8802_mpeg_irq(dev);
316 }; 344 };
317 if (10 == loop) { 345 if (MAX_IRQ_LOOP == loop) {
346 dprintk( 0, "clearing mask\n" );
318 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", 347 printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
319 core->name); 348 core->name);
320 cx_write(MO_PCI_INTMSK,0); 349 cx_write(MO_PCI_INTMSK,0);
@@ -378,6 +407,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
378 407
379void cx8802_fini_common(struct cx8802_dev *dev) 408void cx8802_fini_common(struct cx8802_dev *dev)
380{ 409{
410 dprintk( 2, "cx8802_fini_common\n" );
381 cx8802_stop_dma(dev); 411 cx8802_stop_dma(dev);
382 pci_disable_device(dev->pci); 412 pci_disable_device(dev->pci);
383 413
@@ -399,6 +429,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
399 /* stop mpeg dma */ 429 /* stop mpeg dma */
400 spin_lock(&dev->slock); 430 spin_lock(&dev->slock);
401 if (!list_empty(&dev->mpegq.active)) { 431 if (!list_empty(&dev->mpegq.active)) {
432 dprintk( 2, "suspend\n" );
402 printk("%s: suspend mpeg\n", core->name); 433 printk("%s: suspend mpeg\n", core->name);
403 cx8802_stop_dma(dev); 434 cx8802_stop_dma(dev);
404 del_timer(&dev->mpegq.timeout); 435 del_timer(&dev->mpegq.timeout);
@@ -463,4 +494,5 @@ EXPORT_SYMBOL(cx8802_resume_common);
463 * Local variables: 494 * Local variables:
464 * c-basic-offset: 8 495 * c-basic-offset: 8
465 * End: 496 * End:
497 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
466 */ 498 */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 8638ce57d84c..63ad33f5818b 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -1,5 +1,5 @@
1/* 1/*
2 $Id: cx88-reg.h,v 1.6 2004/10/13 10:39:00 kraxel Exp $ 2 $Id: cx88-reg.h,v 1.7 2005/06/03 13:31:51 mchehab Exp $
3 3
4 cx88x-hw.h - CX2388x register offsets 4 cx88x-hw.h - CX2388x register offsets
5 5
@@ -397,6 +397,7 @@
397#define AUD_RATE_ADJ4 0x3205e4 397#define AUD_RATE_ADJ4 0x3205e4
398#define AUD_RATE_ADJ5 0x3205e8 398#define AUD_RATE_ADJ5 0x3205e8
399#define AUD_APB_IN_RATE_ADJ 0x3205ec 399#define AUD_APB_IN_RATE_ADJ 0x3205ec
400#define AUD_I2SCNTL 0x3205ec
400#define AUD_PHASE_FIX_CTL 0x3205f0 401#define AUD_PHASE_FIX_CTL 0x3205f0
401#define AUD_PLL_PRESCALE 0x320600 402#define AUD_PLL_PRESCALE 0x320600
402#define AUD_PLL_DDS 0x320604 403#define AUD_PLL_DDS 0x320604
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index f2a9475a2fee..46d78b1dc9b2 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 $Id: cx88-tvaudio.c,v 1.34 2005/03/07 16:10:51 kraxel Exp $ 2 $Id: cx88-tvaudio.c,v 1.36 2005/06/05 05:53:45 mchehab Exp $
3 3
4 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver 4 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
5 5
@@ -127,7 +127,8 @@ static void set_audio_start(struct cx88_core *core,
127 cx_write(AUD_VOL_CTL, (1 << 6)); 127 cx_write(AUD_VOL_CTL, (1 << 6));
128 128
129 // increase level of input by 12dB 129 // increase level of input by 12dB
130 cx_write(AUD_AFE_12DB_EN, 0x0001); 130// cx_write(AUD_AFE_12DB_EN, 0x0001);
131 cx_write(AUD_AFE_12DB_EN, 0x0000);
131 132
132 // start programming 133 // start programming
133 cx_write(AUD_CTL, 0x0000); 134 cx_write(AUD_CTL, 0x0000);
@@ -143,9 +144,15 @@ static void set_audio_finish(struct cx88_core *core)
143 u32 volume; 144 u32 volume;
144 145
145 if (cx88_boards[core->board].blackbird) { 146 if (cx88_boards[core->board].blackbird) {
147 // sets sound input from external adc
148 cx_set(AUD_CTL, EN_I2SIN_ENABLE);
149 //cx_write(AUD_I2SINPUTCNTL, 0);
150 cx_write(AUD_I2SINPUTCNTL, 4);
151 cx_write(AUD_BAUDRATE, 1);
146 // 'pass-thru mode': this enables the i2s output to the mpeg encoder 152 // 'pass-thru mode': this enables the i2s output to the mpeg encoder
147 cx_set(AUD_CTL, 0x2000); 153 cx_set(AUD_CTL, EN_I2SOUT_ENABLE);
148 cx_write(AUD_I2SOUTPUTCNTL, 1); 154 cx_write(AUD_I2SOUTPUTCNTL, 1);
155 cx_write(AUD_I2SCNTL, 0);
149 //cx_write(AUD_APB_IN_RATE_ADJ, 0); 156 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 } 157 }
151 158
@@ -707,50 +714,65 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
707 set_audio_finish(core); 714 set_audio_finish(core);
708} 715}
709 716
710static void set_audio_standard_FM(struct cx88_core *core) 717static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph)
711{ 718{
712#if 0 /* FIXME */ 719 static const struct rlist fm_deemph_50[] = {
713 switch (dev->audio_properties.FM_deemphasis) 720 { AUD_DEEMPH0_G0, 0x0C45 },
714 { 721 { AUD_DEEMPH0_A0, 0x6262 },
715 case WW_FM_DEEMPH_50: 722 { AUD_DEEMPH0_B0, 0x1C29 },
716 //Set De-emphasis filter coefficients for 50 usec 723 { AUD_DEEMPH0_A1, 0x3FC66},
717 cx_write(AUD_DEEMPH0_G0, 0x0C45); 724 { AUD_DEEMPH0_B1, 0x399A },
718 cx_write(AUD_DEEMPH0_A0, 0x6262); 725
719 cx_write(AUD_DEEMPH0_B0, 0x1C29); 726 { AUD_DEEMPH1_G0, 0x0D80 },
720 cx_write(AUD_DEEMPH0_A1, 0x3FC66); 727 { AUD_DEEMPH1_A0, 0x6262 },
721 cx_write(AUD_DEEMPH0_B1, 0x399A); 728 { AUD_DEEMPH1_B0, 0x1C29 },
722 729 { AUD_DEEMPH1_A1, 0x3FC66},
723 cx_write(AUD_DEEMPH1_G0, 0x0D80); 730 { AUD_DEEMPH1_B1, 0x399A},
724 cx_write(AUD_DEEMPH1_A0, 0x6262); 731
725 cx_write(AUD_DEEMPH1_B0, 0x1C29); 732 { AUD_POLYPH80SCALEFAC, 0x0003},
726 cx_write(AUD_DEEMPH1_A1, 0x3FC66); 733 { /* end of list */ },
727 cx_write(AUD_DEEMPH1_B1, 0x399A); 734 };
735 static const struct rlist fm_deemph_75[] = {
736 { AUD_DEEMPH0_G0, 0x091B },
737 { AUD_DEEMPH0_A0, 0x6B68 },
738 { AUD_DEEMPH0_B0, 0x11EC },
739 { AUD_DEEMPH0_A1, 0x3FC66},
740 { AUD_DEEMPH0_B1, 0x399A },
741
742 { AUD_DEEMPH1_G0, 0x0AA0 },
743 { AUD_DEEMPH1_A0, 0x6B68 },
744 { AUD_DEEMPH1_B0, 0x11EC },
745 { AUD_DEEMPH1_A1, 0x3FC66},
746 { AUD_DEEMPH1_B1, 0x399A},
747
748 { AUD_POLYPH80SCALEFAC, 0x0003},
749 { /* end of list */ },
750 };
728 751
729 break; 752 /* It is enough to leave default values? */
753 static const struct rlist fm_no_deemph[] = {
730 754
731 case WW_FM_DEEMPH_75: 755 { AUD_POLYPH80SCALEFAC, 0x0003},
732 //Set De-emphasis filter coefficients for 75 usec 756 { /* end of list */ },
733 cx_write(AUD_DEEMPH0_G0, 0x91B ); 757 };
734 cx_write(AUD_DEEMPH0_A0, 0x6B68);
735 cx_write(AUD_DEEMPH0_B0, 0x11EC);
736 cx_write(AUD_DEEMPH0_A1, 0x3FC66);
737 cx_write(AUD_DEEMPH0_B1, 0x399A);
738 758
739 cx_write(AUD_DEEMPH1_G0, 0xAA0 ); 759 dprintk("%s (status: unknown)\n",__FUNCTION__);
740 cx_write(AUD_DEEMPH1_A0, 0x6B68); 760 set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
741 cx_write(AUD_DEEMPH1_B0, 0x11EC);
742 cx_write(AUD_DEEMPH1_A1, 0x3FC66);
743 cx_write(AUD_DEEMPH1_B1, 0x399A);
744 761
762 switch (deemph)
763 {
764 case FM_NO_DEEMPH:
765 set_audio_registers(core, fm_no_deemph);
745 break; 766 break;
746 }
747#endif
748 767
749 dprintk("%s (status: unknown)\n",__FUNCTION__); 768 case FM_DEEMPH_50:
750 set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO); 769 set_audio_registers(core, fm_deemph_50);
770 break;
751 771
752 // AB: 10/2/01: this register is not being reset appropriately on occasion. 772 case FM_DEEMPH_75:
753 cx_write(AUD_POLYPH80SCALEFAC,3); 773 set_audio_registers(core, fm_deemph_75);
774 break;
775 }
754 776
755 set_audio_finish(core); 777 set_audio_finish(core);
756} 778}
@@ -778,7 +800,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
778 set_audio_standard_EIAJ(core); 800 set_audio_standard_EIAJ(core);
779 break; 801 break;
780 case WW_FM: 802 case WW_FM:
781 set_audio_standard_FM(core); 803 set_audio_standard_FM(core,FM_NO_DEEMPH);
782 break; 804 break;
783 case WW_SYSTEM_L_AM: 805 case WW_SYSTEM_L_AM:
784 set_audio_standard_NICAM_L(core, 1); 806 set_audio_standard_NICAM_L(core, 1);
@@ -1029,4 +1051,5 @@ EXPORT_SYMBOL(cx88_audio_thread);
1029 * Local variables: 1051 * Local variables:
1030 * c-basic-offset: 8 1052 * c-basic-offset: 8
1031 * End: 1053 * End:
1054 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
1032 */ 1055 */
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 0584ff476387..320d57888bbd 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $ 2 * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $
3 */ 3 */
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5#include <linux/module.h> 5#include <linux/module.h>
@@ -47,8 +47,8 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f)
47} 47}
48 48
49static int cx8800_start_vbi_dma(struct cx8800_dev *dev, 49static int cx8800_start_vbi_dma(struct cx8800_dev *dev,
50 struct cx88_dmaqueue *q, 50 struct cx88_dmaqueue *q,
51 struct cx88_buffer *buf) 51 struct cx88_buffer *buf)
52{ 52{
53 struct cx88_core *core = dev->core; 53 struct cx88_core *core = dev->core;
54 54
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index d1f5c92f0ce5..e4ca7350df15 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $ 2 * $Id: cx88-video.c,v 1.63 2005/06/12 04:19:19 mchehab Exp $
3 * 3 *
4 * device driver for Conexant 2388x based TV cards 4 * device driver for Conexant 2388x based TV cards
5 * video4linux video interface 5 * video4linux video interface
@@ -1187,9 +1187,24 @@ static void init_controls(struct cx8800_dev *dev)
1187 .id = V4L2_CID_AUDIO_VOLUME, 1187 .id = V4L2_CID_AUDIO_VOLUME,
1188 .value = 0x3f, 1188 .value = 0x3f,
1189 }; 1189 };
1190 static struct v4l2_control hue = {
1191 .id = V4L2_CID_HUE,
1192 .value = 0x80,
1193 };
1194 static struct v4l2_control contrast = {
1195 .id = V4L2_CID_CONTRAST,
1196 .value = 0x80,
1197 };
1198 static struct v4l2_control brightness = {
1199 .id = V4L2_CID_BRIGHTNESS,
1200 .value = 0x80,
1201 };
1190 1202
1191 set_control(dev,&mute); 1203 set_control(dev,&mute);
1192 set_control(dev,&volume); 1204 set_control(dev,&volume);
1205 set_control(dev,&hue);
1206 set_control(dev,&contrast);
1207 set_control(dev,&brightness);
1193} 1208}
1194 1209
1195/* ------------------------------------------------------------------ */ 1210/* ------------------------------------------------------------------ */
@@ -1336,6 +1351,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1336 V4L2_CAP_STREAMING | 1351 V4L2_CAP_STREAMING |
1337 V4L2_CAP_VBI_CAPTURE | 1352 V4L2_CAP_VBI_CAPTURE |
1338#if 0 1353#if 0
1354 V4L2_TUNER_CAP_LOW |
1355#endif
1356#if 0
1339 V4L2_CAP_VIDEO_OVERLAY | 1357 V4L2_CAP_VIDEO_OVERLAY |
1340#endif 1358#endif
1341 0; 1359 0;
@@ -1696,7 +1714,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1696 sizeof(cap->card)); 1714 sizeof(cap->card));
1697 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); 1715 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
1698 cap->version = CX88_VERSION_CODE; 1716 cap->version = CX88_VERSION_CODE;
1699 cap->capabilities = V4L2_CAP_TUNER; 1717 cap->capabilities = V4L2_CAP_TUNER
1718#if 0
1719 | V4L2_TUNER_CAP_LOW
1720#endif
1721 ;
1700 return 0; 1722 return 0;
1701 } 1723 }
1702 case VIDIOC_G_TUNER: 1724 case VIDIOC_G_TUNER:
@@ -1992,6 +2014,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1992{ 2014{
1993 struct cx8800_dev *dev; 2015 struct cx8800_dev *dev;
1994 struct cx88_core *core; 2016 struct cx88_core *core;
2017 struct tuner_addr tun_addr;
1995 int err; 2018 int err;
1996 2019
1997 dev = kmalloc(sizeof(*dev),GFP_KERNEL); 2020 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
@@ -2065,8 +2088,19 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
2065 request_module("tuner"); 2088 request_module("tuner");
2066 if (core->tda9887_conf) 2089 if (core->tda9887_conf)
2067 request_module("tda9887"); 2090 request_module("tda9887");
2068 if (core->tuner_type != UNSET) 2091 if (core->radio_type != UNSET) {
2069 cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type); 2092 tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
2093 tun_addr.type = core->radio_type;
2094 tun_addr.addr = core->radio_addr;
2095 cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
2096 }
2097 if (core->tuner_type != UNSET) {
2098 tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
2099 tun_addr.type = core->tuner_type;
2100 tun_addr.addr = core->tuner_addr;
2101 cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
2102 }
2103
2070 if (core->tda9887_conf) 2104 if (core->tda9887_conf)
2071 cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf); 2105 cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
2072 2106
@@ -2162,7 +2196,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
2162 2196
2163static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) 2197static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
2164{ 2198{
2165 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 2199 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2166 struct cx88_core *core = dev->core; 2200 struct cx88_core *core = dev->core;
2167 2201
2168 /* stop video+vbi capture */ 2202 /* stop video+vbi capture */
@@ -2194,7 +2228,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
2194 2228
2195static int cx8800_resume(struct pci_dev *pci_dev) 2229static int cx8800_resume(struct pci_dev *pci_dev)
2196{ 2230{
2197 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 2231 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
2198 struct cx88_core *core = dev->core; 2232 struct cx88_core *core = dev->core;
2199 2233
2200 if (dev->state.disabled) { 2234 if (dev->state.disabled) {
@@ -2230,8 +2264,8 @@ static struct pci_device_id cx8800_pci_tbl[] = {
2230 { 2264 {
2231 .vendor = 0x14f1, 2265 .vendor = 0x14f1,
2232 .device = 0x8800, 2266 .device = 0x8800,
2233 .subvendor = PCI_ANY_ID, 2267 .subvendor = PCI_ANY_ID,
2234 .subdevice = PCI_ANY_ID, 2268 .subdevice = PCI_ANY_ID,
2235 },{ 2269 },{
2236 /* --- end of list --- */ 2270 /* --- end of list --- */
2237 } 2271 }
@@ -2239,10 +2273,10 @@ static struct pci_device_id cx8800_pci_tbl[] = {
2239MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl); 2273MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);
2240 2274
2241static struct pci_driver cx8800_pci_driver = { 2275static struct pci_driver cx8800_pci_driver = {
2242 .name = "cx8800", 2276 .name = "cx8800",
2243 .id_table = cx8800_pci_tbl, 2277 .id_table = cx8800_pci_tbl,
2244 .probe = cx8800_initdev, 2278 .probe = cx8800_initdev,
2245 .remove = __devexit_p(cx8800_finidev), 2279 .remove = __devexit_p(cx8800_finidev),
2246 2280
2247 .suspend = cx8800_suspend, 2281 .suspend = cx8800_suspend,
2248 .resume = cx8800_resume, 2282 .resume = cx8800_resume,
@@ -2274,4 +2308,5 @@ module_exit(cx8800_fini);
2274 * Local variables: 2308 * Local variables:
2275 * c-basic-offset: 8 2309 * c-basic-offset: 8
2276 * End: 2310 * End:
2311 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
2277 */ 2312 */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 88eaaaba5ad8..ac0dc27bb38f 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $ 2 * $Id: cx88.h,v 1.62 2005/06/12 04:19:19 mchehab Exp $
3 * 3 *
4 * v4l2 device driver for cx2388x based TV cards 4 * v4l2 device driver for cx2388x based TV cards
5 * 5 *
@@ -64,6 +64,13 @@
64#define SHADOW_AUD_BAL_CTL 2 64#define SHADOW_AUD_BAL_CTL 2
65#define SHADOW_MAX 2 65#define SHADOW_MAX 2
66 66
67/* FM Radio deemphasis type */
68enum cx88_deemph_type {
69 FM_NO_DEEMPH = 0,
70 FM_DEEMPH_50,
71 FM_DEEMPH_75
72};
73
67/* ----------------------------------------------------------- */ 74/* ----------------------------------------------------------- */
68/* tv norms */ 75/* tv norms */
69 76
@@ -162,6 +169,8 @@ extern struct sram_channel cx88_sram_channels[];
162#define CX88_BOARD_HAUPPAUGE_ROSLYN 24 169#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
163#define CX88_BOARD_DIGITALLOGIC_MEC 25 170#define CX88_BOARD_DIGITALLOGIC_MEC 25
164#define CX88_BOARD_IODATA_GVBCTV7E 26 171#define CX88_BOARD_IODATA_GVBCTV7E 26
172#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27
173#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28
165 174
166enum cx88_itype { 175enum cx88_itype {
167 CX88_VMUX_COMPOSITE1 = 1, 176 CX88_VMUX_COMPOSITE1 = 1,
@@ -185,6 +194,9 @@ struct cx88_input {
185struct cx88_board { 194struct cx88_board {
186 char *name; 195 char *name;
187 unsigned int tuner_type; 196 unsigned int tuner_type;
197 unsigned int radio_type;
198 unsigned char tuner_addr;
199 unsigned char radio_addr;
188 int tda9887_conf; 200 int tda9887_conf;
189 struct cx88_input input[8]; 201 struct cx88_input input[8];
190 struct cx88_input radio; 202 struct cx88_input radio;
@@ -255,6 +267,9 @@ struct cx88_core {
255 /* config info -- analog */ 267 /* config info -- analog */
256 unsigned int board; 268 unsigned int board;
257 unsigned int tuner_type; 269 unsigned int tuner_type;
270 unsigned int radio_type;
271 unsigned char tuner_addr;
272 unsigned char radio_addr;
258 unsigned int tda9887_conf; 273 unsigned int tda9887_conf;
259 unsigned int has_radio; 274 unsigned int has_radio;
260 275
@@ -420,6 +435,7 @@ struct cx8802_dev {
420/* ----------------------------------------------------------- */ 435/* ----------------------------------------------------------- */
421/* cx88-core.c */ 436/* cx88-core.c */
422 437
438extern char *cx88_pci_irqs[32];
423extern char *cx88_vid_irqs[32]; 439extern char *cx88_vid_irqs[32];
424extern char *cx88_mpeg_irqs[32]; 440extern char *cx88_mpeg_irqs[32];
425extern void cx88_print_irqbits(char *name, char *tag, char **strings, 441extern void cx88_print_irqbits(char *name, char *tag, char **strings,
@@ -471,6 +487,11 @@ extern void cx88_core_put(struct cx88_core *core,
471/* cx88-vbi.c */ 487/* cx88-vbi.c */
472 488
473void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f); 489void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f);
490/*
491int cx8800_start_vbi_dma(struct cx8800_dev *dev,
492 struct cx88_dmaqueue *q,
493 struct cx88_buffer *buf);
494*/
474int cx8800_stop_vbi_dma(struct cx8800_dev *dev); 495int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
475int cx8800_restart_vbi_queue(struct cx8800_dev *dev, 496int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
476 struct cx88_dmaqueue *q); 497 struct cx88_dmaqueue *q);
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index ab6620de4b3b..a565823330aa 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ir-kbd-gpio.c,v 1.12 2005/02/22 12:28:40 kraxel Exp $ 2 * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $
3 * 3 *
4 * Copyright (c) 2003 Gerd Knorr 4 * Copyright (c) 2003 Gerd Knorr
5 * Copyright (c) 2003 Pavel Machek 5 * Copyright (c) 2003 Pavel Machek
@@ -114,38 +114,6 @@ static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
114 [ 0x3e ] = KEY_VOLUMEUP, // 'volume +' 114 [ 0x3e ] = KEY_VOLUMEUP, // 'volume +'
115}; 115};
116 116
117static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
118 [ 2 ] = KEY_KP0,
119 [ 1 ] = KEY_KP1,
120 [ 11 ] = KEY_KP2,
121 [ 27 ] = KEY_KP3,
122 [ 5 ] = KEY_KP4,
123 [ 9 ] = KEY_KP5,
124 [ 21 ] = KEY_KP6,
125 [ 6 ] = KEY_KP7,
126 [ 10 ] = KEY_KP8,
127 [ 18 ] = KEY_KP9,
128
129 [ 3 ] = KEY_TUNER, // TV/FM
130 [ 7 ] = KEY_SEARCH, // scan
131 [ 28 ] = KEY_ZOOM, // full screen
132 [ 30 ] = KEY_POWER,
133 [ 23 ] = KEY_VOLUMEDOWN,
134 [ 31 ] = KEY_VOLUMEUP,
135 [ 20 ] = KEY_CHANNELDOWN,
136 [ 22 ] = KEY_CHANNELUP,
137 [ 24 ] = KEY_MUTE,
138
139 [ 0 ] = KEY_LIST, // source
140 [ 19 ] = KEY_INFO, // loop
141 [ 16 ] = KEY_LAST, // +100
142 [ 13 ] = KEY_CLEAR, // reset
143 [ 12 ] = BTN_RIGHT, // fun++
144 [ 4 ] = BTN_LEFT, // fun--
145 [ 14 ] = KEY_GOTO, // function
146 [ 15 ] = KEY_STOP, // freeze
147};
148
149/* Attila Kondoros <attila.kondoros@chello.hu> */ 117/* Attila Kondoros <attila.kondoros@chello.hu> */
150static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { 118static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
151 119
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index 09464d624a6b..1b7d38e96f14 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -735,7 +735,6 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
735{ 735{
736 DECLARE_WAITQUEUE(wait, current); 736 DECLARE_WAITQUEUE(wait, current);
737 737
738again:
739 add_wait_queue(&msp->wq, &wait); 738 add_wait_queue(&msp->wq, &wait);
740 if (!kthread_should_stop()) { 739 if (!kthread_should_stop()) {
741 if (timeout < 0) { 740 if (timeout < 0) {
@@ -751,12 +750,9 @@ again:
751#endif 750#endif
752 } 751 }
753 } 752 }
754 753 if (current->flags & PF_FREEZE)
754 refrigerator(PF_FREEZE);
755 remove_wait_queue(&msp->wq, &wait); 755 remove_wait_queue(&msp->wq, &wait);
756
757 if (try_to_freeze(PF_FREEZE))
758 goto again;
759
760 return msp->restart; 756 return msp->restart;
761} 757}
762 758
@@ -1436,7 +1432,7 @@ static int msp_detach(struct i2c_client *client);
1436static int msp_probe(struct i2c_adapter *adap); 1432static int msp_probe(struct i2c_adapter *adap);
1437static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg); 1433static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
1438 1434
1439static int msp_suspend(struct device * dev, pm_message_t state, u32 level); 1435static int msp_suspend(struct device * dev, u32 state, u32 level);
1440static int msp_resume(struct device * dev, u32 level); 1436static int msp_resume(struct device * dev, u32 level);
1441 1437
1442static void msp_wake_thread(struct i2c_client *client); 1438static void msp_wake_thread(struct i2c_client *client);
@@ -1841,7 +1837,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1841 return 0; 1837 return 0;
1842} 1838}
1843 1839
1844static int msp_suspend(struct device * dev, pm_message_t state, u32 level) 1840static int msp_suspend(struct device * dev, u32 state, u32 level)
1845{ 1841{
1846 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 1842 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
1847 1843
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
index d70a954e13aa..023f33056a4f 100644
--- a/drivers/media/video/msp3400.h
+++ b/drivers/media/video/msp3400.h
@@ -1,3 +1,7 @@
1/*
2 * $Id: msp3400.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $
3 */
4
1#ifndef MSP3400_H 5#ifndef MSP3400_H
2#define MSP3400_H 6#define MSP3400_H
3 7
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 42c2b565c9fe..e6d0a18833d6 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -41,16 +41,16 @@ enum saa6752hs_videoformat {
41 41
42static const struct v4l2_format v4l2_format_table[] = 42static const struct v4l2_format v4l2_format_table[] =
43{ 43{
44 [SAA6752HS_VF_D1] = { 44 [SAA6752HS_VF_D1] =
45 .fmt = { .pix = { .width = 720, .height = 576 }, }, }, 45 { .fmt = { .pix = { .width = 720, .height = 576 }}},
46 [SAA6752HS_VF_2_3_D1] = { 46 [SAA6752HS_VF_2_3_D1] =
47 .fmt = { .pix = { .width = 480, .height = 576 }, }, }, 47 { .fmt = { .pix = { .width = 480, .height = 576 }}},
48 [SAA6752HS_VF_1_2_D1] = { 48 [SAA6752HS_VF_1_2_D1] =
49 .fmt = { .pix = { .width = 352, .height = 576 }, }, }, 49 { .fmt = { .pix = { .width = 352, .height = 576 }}},
50 [SAA6752HS_VF_SIF] = { 50 [SAA6752HS_VF_SIF] =
51 .fmt = { .pix = { .width = 352, .height = 288 }, }, }, 51 { .fmt = { .pix = { .width = 352, .height = 288 }}},
52 [SAA6752HS_VF_UNKNOWN] = { 52 [SAA6752HS_VF_UNKNOWN] =
53 .fmt = { .pix = { .width = 0, .height = 0 }, }, }, 53 { .fmt = { .pix = { .width = 0, .height = 0}}},
54}; 54};
55 55
56struct saa6752hs_state { 56struct saa6752hs_state {
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index c51eb7f078d3..0c781e24c446 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1,6 +1,6 @@
1 1
2/* 2/*
3 * $Id: saa7134-cards.c,v 1.54 2005/03/07 12:01:51 kraxel Exp $ 3 * $Id: saa7134-cards.c,v 1.58 2005/06/07 18:05:00 nsh Exp $
4 * 4 *
5 * device driver for philips saa7134 based TV cards 5 * device driver for philips saa7134 based TV cards
6 * card-specific stuff. 6 * card-specific stuff.
@@ -165,7 +165,7 @@ struct saa7134_board saa7134_boards[] = {
165 .inputs = {{ 165 .inputs = {{
166 .name = name_tv, 166 .name = name_tv,
167 .vmux = 1, 167 .vmux = 1,
168 .amux = LINE2, 168 .amux = TV,
169 .tv = 1, 169 .tv = 1,
170 },{ 170 },{
171 .name = name_comp1, 171 .name = name_comp1,
@@ -878,7 +878,7 @@ struct saa7134_board saa7134_boards[] = {
878 }, 878 },
879 [SAA7134_BOARD_MANLI_MTV002] = { 879 [SAA7134_BOARD_MANLI_MTV002] = {
880 /* Ognjen Nastic <ognjen@logosoft.ba> */ 880 /* Ognjen Nastic <ognjen@logosoft.ba> */
881 .name = "Manli MuchTV M-TV002", 881 .name = "Manli MuchTV M-TV002/Behold TV 403 FM",
882 .audio_clock = 0x00200000, 882 .audio_clock = 0x00200000,
883 .tuner_type = TUNER_PHILIPS_PAL, 883 .tuner_type = TUNER_PHILIPS_PAL,
884 .inputs = {{ 884 .inputs = {{
@@ -899,14 +899,10 @@ struct saa7134_board saa7134_boards[] = {
899 .name = name_radio, 899 .name = name_radio,
900 .amux = LINE2, 900 .amux = LINE2,
901 }, 901 },
902 .mute = {
903 .name = name_mute,
904 .amux = LINE1,
905 },
906 }, 902 },
907 [SAA7134_BOARD_MANLI_MTV001] = { 903 [SAA7134_BOARD_MANLI_MTV001] = {
908 /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */ 904 /* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
909 .name = "Manli MuchTV M-TV001", 905 .name = "Manli MuchTV M-TV001/Behold TV 401",
910 .audio_clock = 0x00200000, 906 .audio_clock = 0x00200000,
911 .tuner_type = TUNER_PHILIPS_PAL, 907 .tuner_type = TUNER_PHILIPS_PAL,
912 .inputs = {{ 908 .inputs = {{
@@ -923,6 +919,10 @@ struct saa7134_board saa7134_boards[] = {
923 .amux = LINE2, 919 .amux = LINE2,
924 .tv = 1, 920 .tv = 1,
925 }}, 921 }},
922 .mute = {
923 .name = name_mute,
924 .amux = LINE1,
925 },
926 }, 926 },
927 [SAA7134_BOARD_TG3000TV] = { 927 [SAA7134_BOARD_TG3000TV] = {
928 /* TransGear 3000TV */ 928 /* TransGear 3000TV */
@@ -1078,7 +1078,6 @@ struct saa7134_board saa7134_boards[] = {
1078 .audio_clock = 0x00187de7, 1078 .audio_clock = 0x00187de7,
1079 .tuner_type = TUNER_PHILIPS_FM1256_IH3, 1079 .tuner_type = TUNER_PHILIPS_FM1256_IH3,
1080 .tda9887_conf = TDA9887_PRESENT, 1080 .tda9887_conf = TDA9887_PRESENT,
1081 .gpiomask = 0x3,
1082 .inputs = {{ 1081 .inputs = {{
1083 .name = name_tv, 1082 .name = name_tv,
1084 .vmux = 1, 1083 .vmux = 1,
@@ -1285,7 +1284,7 @@ struct saa7134_board saa7134_boards[] = {
1285 .gpio =0x8000, 1284 .gpio =0x8000,
1286 } 1285 }
1287 }, 1286 },
1288 [SAA7134_BOARD_AVERMEDIA_307] = { 1287 [SAA7134_BOARD_AVERMEDIA_STUDIO_307] = {
1289 /* 1288 /*
1290 Nickolay V. Shmyrev <nshmyrev@yandex.ru> 1289 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
1291 Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru> 1290 Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
@@ -1323,6 +1322,35 @@ struct saa7134_board saa7134_boards[] = {
1323 .gpio = 0x01, 1322 .gpio = 0x01,
1324 }, 1323 },
1325 }, 1324 },
1325 [SAA7134_BOARD_AVERMEDIA_GO_007_FM] = {
1326 .name = "Avermedia AVerTV GO 007 FM",
1327 .audio_clock = 0x00187de7,
1328 .tuner_type = TUNER_PHILIPS_TDA8290,
1329 .gpiomask = 0x00300003,
1330// .gpiomask = 0x8c240003,
1331 .inputs = {{
1332 .name = name_tv,
1333 .vmux = 1,
1334 .amux = TV,
1335 .tv = 1,
1336 .gpio = 0x01,
1337 },{
1338 .name = name_comp1,
1339 .vmux = 0,
1340 .amux = LINE2,
1341 .gpio = 0x02,
1342 },{
1343 .name = name_svideo,
1344 .vmux = 6,
1345 .amux = LINE2,
1346 .gpio = 0x02,
1347 }},
1348 .radio = {
1349 .name = name_radio,
1350 .amux = LINE1,
1351 .gpio = 0x00300001,
1352 },
1353 },
1326 [SAA7134_BOARD_AVERMEDIA_CARDBUS] = { 1354 [SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
1327 /* Jon Westgate <oryn@oryn.fsck.tv> */ 1355 /* Jon Westgate <oryn@oryn.fsck.tv> */
1328 .name = "AVerMedia Cardbus TV/Radio", 1356 .name = "AVerMedia Cardbus TV/Radio",
@@ -1492,7 +1520,6 @@ struct saa7134_board saa7134_boards[] = {
1492 .audio_clock = 0x00187de7, 1520 .audio_clock = 0x00187de7,
1493 .tuner_type = TUNER_PHILIPS_FQ1216ME, 1521 .tuner_type = TUNER_PHILIPS_FQ1216ME,
1494 .tda9887_conf = TDA9887_PRESENT, 1522 .tda9887_conf = TDA9887_PRESENT,
1495 .gpiomask = 0x3,
1496 .inputs = {{ 1523 .inputs = {{
1497 .name = name_tv, 1524 .name = name_tv,
1498 .vmux = 1, 1525 .vmux = 1,
@@ -1546,7 +1573,82 @@ struct saa7134_board saa7134_boards[] = {
1546// .gpio = 0x4000, 1573// .gpio = 0x4000,
1547 }}, 1574 }},
1548 }, 1575 },
1549}; 1576 [SAA7134_BOARD_AVERMEDIA_307] = {
1577 /*
1578 Davydov Vladimir <vladimir@iqmedia.com>
1579 */
1580 .name = "Avermedia AVerTV 307",
1581 .audio_clock = 0x00187de7,
1582 .tuner_type = TUNER_PHILIPS_FQ1216ME,
1583 .tda9887_conf = TDA9887_PRESENT,
1584 .inputs = {{
1585 .name = name_tv,
1586 .vmux = 1,
1587 .amux = TV,
1588 .tv = 1,
1589 },{
1590 .name = name_comp1,
1591 .vmux = 0,
1592 .amux = LINE1,
1593 },{
1594 .name = name_comp2,
1595 .vmux = 3,
1596 .amux = LINE1,
1597 },{
1598 .name = name_svideo,
1599 .vmux = 8,
1600 .amux = LINE1,
1601 }},
1602 },
1603 [SAA7134_BOARD_ADS_INSTANT_TV] = {
1604 .name = "ADS Tech Instant TV (saa7135)",
1605 .audio_clock = 0x00187de7,
1606 .tuner_type = TUNER_PHILIPS_TDA8290,
1607 .inputs = {{
1608 .name = name_tv,
1609 .vmux = 1,
1610 .amux = TV,
1611 .tv = 1,
1612 },{
1613 .name = name_comp1,
1614 .vmux = 3,
1615 .amux = LINE2,
1616 },{
1617 .name = name_svideo,
1618 .vmux = 8,
1619 .amux = LINE2,
1620 }},
1621 },
1622 [SAA7134_BOARD_KWORLD_VSTREAM_XPERT] = {
1623 .name = "Kworld/Tevion V-Stream Xpert TV PVR7134",
1624 .audio_clock = 0x00187de7,
1625 .tuner_type = TUNER_PHILIPS_PAL_I,
1626 .gpiomask = 0x0700,
1627 .inputs = {{
1628 .name = name_tv,
1629 .vmux = 1,
1630 .amux = TV,
1631 .tv = 1,
1632 .gpio = 0x000,
1633 },{
1634 .name = name_comp1,
1635 .vmux = 3,
1636 .amux = LINE1,
1637 .gpio = 0x200, //gpio by DScaler
1638 },{
1639 .name = name_svideo,
1640 .vmux = 0,
1641 .amux = LINE1,
1642 .gpio = 0x200,
1643 }},
1644 .radio = {
1645 .name = name_radio,
1646 .amux = LINE1,
1647 .gpio = 0x100,
1648 },
1649 },
1650 };
1651
1550const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 1652const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
1551 1653
1552/* ------------------------------------------------------------------ */ 1654/* ------------------------------------------------------------------ */
@@ -1663,7 +1765,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
1663 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134, 1765 .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
1664 },{ 1766 },{
1665 .vendor = PCI_VENDOR_ID_PHILIPS, 1767 .vendor = PCI_VENDOR_ID_PHILIPS,
1666 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 1768 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1667 .subvendor = PCI_VENDOR_ID_ASUSTEK, 1769 .subvendor = PCI_VENDOR_ID_ASUSTEK,
1668 .subdevice = 0x4845, 1770 .subdevice = 0x4845,
1669 .driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135, 1771 .driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135,
@@ -1824,6 +1926,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
1824 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 1926 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1825 .subvendor = 0x1461, /* Avermedia Technologies Inc */ 1927 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1826 .subdevice = 0x9715, 1928 .subdevice = 0x9715,
1929 .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_307,
1930 },{
1931 .vendor = PCI_VENDOR_ID_PHILIPS,
1932 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
1933 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1934 .subdevice = 0xa70a,
1827 .driver_data = SAA7134_BOARD_AVERMEDIA_307, 1935 .driver_data = SAA7134_BOARD_AVERMEDIA_307,
1828 },{ 1936 },{
1829 .vendor = PCI_VENDOR_ID_PHILIPS, 1937 .vendor = PCI_VENDOR_ID_PHILIPS,
@@ -1844,6 +1952,26 @@ struct pci_device_id saa7134_pci_tbl[] = {
1844 .subvendor = 0x5168, 1952 .subvendor = 0x5168,
1845 .subdevice = 0x0306, 1953 .subdevice = 0x0306,
1846 .driver_data = SAA7134_BOARD_FLYDVBTDUO, 1954 .driver_data = SAA7134_BOARD_FLYDVBTDUO,
1955 },{
1956 .vendor = PCI_VENDOR_ID_PHILIPS,
1957 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
1958 .subvendor = 0x1461, /* Avermedia Technologies Inc */
1959 .subdevice = 0xf31f,
1960 .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM,
1961
1962 },{
1963 .vendor = PCI_VENDOR_ID_PHILIPS,
1964 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1965 .subvendor = 0x1421,
1966 .subdevice = 0x0350, /* PCI version */
1967 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
1968
1969 },{
1970 .vendor = PCI_VENDOR_ID_PHILIPS,
1971 .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
1972 .subvendor = 0x1421,
1973 .subdevice = 0x0370, /* cardbus version */
1974 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
1847 1975
1848 },{ 1976 },{
1849 /* --- boards without eeprom + subsystem ID --- */ 1977 /* --- boards without eeprom + subsystem ID --- */
@@ -1954,20 +2082,23 @@ int saa7134_board_init1(struct saa7134_dev *dev)
1954 dev->has_remote = 1; 2082 dev->has_remote = 1;
1955 board_flyvideo(dev); 2083 board_flyvideo(dev);
1956 break; 2084 break;
1957 case SAA7134_BOARD_FLYTVPLATINUM_FM: 2085 case SAA7134_BOARD_FLYTVPLATINUM_FM:
1958 case SAA7134_BOARD_CINERGY400: 2086 case SAA7134_BOARD_CINERGY400:
1959 case SAA7134_BOARD_CINERGY600: 2087 case SAA7134_BOARD_CINERGY600:
1960 case SAA7134_BOARD_CINERGY600_MK3: 2088 case SAA7134_BOARD_CINERGY600_MK3:
1961 case SAA7134_BOARD_ECS_TVP3XP: 2089 case SAA7134_BOARD_ECS_TVP3XP:
1962 case SAA7134_BOARD_ECS_TVP3XP_4CB5: 2090 case SAA7134_BOARD_ECS_TVP3XP_4CB5:
1963 case SAA7134_BOARD_MD2819: 2091 case SAA7134_BOARD_MD2819:
2092 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
1964 case SAA7134_BOARD_AVERMEDIA_STUDIO_305: 2093 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
1965 case SAA7134_BOARD_AVERMEDIA_305: 2094 case SAA7134_BOARD_AVERMEDIA_305:
2095 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
1966 case SAA7134_BOARD_AVERMEDIA_307: 2096 case SAA7134_BOARD_AVERMEDIA_307:
2097 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
1967// case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */ 2098// case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */
1968 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 2099 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
1969 dev->has_remote = 1; 2100 case SAA7134_BOARD_MANLI_MTV001:
1970 break; 2101 case SAA7134_BOARD_MANLI_MTV002:
1971 case SAA7134_BOARD_AVACSSMARTTV: 2102 case SAA7134_BOARD_AVACSSMARTTV:
1972 dev->has_remote = 1; 2103 dev->has_remote = 1;
1973 break; 2104 break;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index d506cafba8ff..f61ed1849a2a 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $ 2 * $Id: saa7134-core.c,v 1.30 2005/05/22 19:23:39 nsh Exp $
3 * 3 *
4 * device driver for philips saa7134 based TV cards 4 * device driver for philips saa7134 based TV cards
5 * driver core 5 * driver core
@@ -316,7 +316,7 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
316 316
317int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) 317int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
318{ 318{
319 u32 *cpu; 319 __le32 *cpu;
320 dma_addr_t dma_addr; 320 dma_addr_t dma_addr;
321 321
322 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); 322 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
@@ -332,7 +332,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
332 struct scatterlist *list, unsigned int length, 332 struct scatterlist *list, unsigned int length,
333 unsigned int startpage) 333 unsigned int startpage)
334{ 334{
335 u32 *ptr; 335 __le32 *ptr;
336 unsigned int i,p; 336 unsigned int i,p;
337 337
338 BUG_ON(NULL == pt || NULL == pt->cpu); 338 BUG_ON(NULL == pt || NULL == pt->cpu);
@@ -340,7 +340,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
340 ptr = pt->cpu + startpage; 340 ptr = pt->cpu + startpage;
341 for (i = 0; i < length; i++, list++) 341 for (i = 0; i < length; i++, list++)
342 for (p = 0; p * 4096 < list->length; p++, ptr++) 342 for (p = 0; p * 4096 < list->length; p++, ptr++)
343 *ptr = sg_dma_address(list) - list->offset; 343 *ptr = cpu_to_le32(sg_dma_address(list) - list->offset);
344 return 0; 344 return 0;
345} 345}
346 346
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index c2873ae029f9..aa8e2cf62d55 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $ 2 * $Id: saa7134-dvb.c,v 1.13 2005/06/12 04:19:19 mchehab Exp $
3 * 3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 * 5 *
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index fa1357336907..c85348d0239f 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $ 2 * $Id: saa7134-empress.c,v 1.11 2005/05/22 19:23:39 nsh Exp $
3 * 3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
5 * 5 *
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 702bb63d9813..b6f002e8421d 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $ 2 * $Id: saa7134-i2c.c,v 1.11 2005/06/12 01:36:14 mchehab Exp $
3 * 3 *
4 * device driver for philips saa7134 based TV cards 4 * device driver for philips saa7134 based TV cards
5 * i2c interface support 5 * i2c interface support
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index ca50cf531f20..aba2b9de60de 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $ 2 * $Id: saa7134-input.c,v 1.19 2005/06/07 18:02:26 nsh Exp $
3 * 3 *
4 * handle saa7134 IR remotes via linux kernel input layer. 4 * handle saa7134 IR remotes via linux kernel input layer.
5 * 5 *
@@ -308,6 +308,102 @@ static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
308 [ 32 ] = KEY_LANGUAGE, 308 [ 32 ] = KEY_LANGUAGE,
309 [ 33 ] = KEY_SLEEP, 309 [ 33 ] = KEY_SLEEP,
310}; 310};
311
312/* Michael Tokarev <mjt@tls.msk.ru>
313 http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
314 keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
315 least, and probably other cards too.
316 The "ascii-art picture" below (in comments, first row
317 is the keycode in hex, and subsequent row(s) shows
318 the button labels (several variants when appropriate)
319 helps to descide which keycodes to assign to the buttons.
320 */
321static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
322
323 /* 0x1c 0x12 *
324 * FUNCTION POWER *
325 * FM (|) *
326 * */
327 [ 0x1c ] = KEY_RADIO, /*XXX*/
328 [ 0x12 ] = KEY_POWER,
329
330 /* 0x01 0x02 0x03 *
331 * 1 2 3 *
332 * *
333 * 0x04 0x05 0x06 *
334 * 4 5 6 *
335 * *
336 * 0x07 0x08 0x09 *
337 * 7 8 9 *
338 * */
339 [ 0x01 ] = KEY_KP1,
340 [ 0x02 ] = KEY_KP2,
341 [ 0x03 ] = KEY_KP3,
342 [ 0x04 ] = KEY_KP4,
343 [ 0x05 ] = KEY_KP5,
344 [ 0x06 ] = KEY_KP6,
345 [ 0x07 ] = KEY_KP7,
346 [ 0x08 ] = KEY_KP8,
347 [ 0x09 ] = KEY_KP9,
348
349 /* 0x0a 0x00 0x17 *
350 * RECALL 0 +100 *
351 * PLUS *
352 * */
353 [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */
354 [ 0x00 ] = KEY_KP0,
355 [ 0x17 ] = KEY_DIGITS, /*XXX*/
356
357 /* 0x14 0x10 *
358 * MENU INFO *
359 * OSD */
360 [ 0x14 ] = KEY_MENU,
361 [ 0x10 ] = KEY_INFO,
362
363 /* 0x0b *
364 * Up *
365 * *
366 * 0x18 0x16 0x0c *
367 * Left Ok Right *
368 * *
369 * 0x015 *
370 * Down *
371 * */
372 [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */
373 [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */
374 [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */
375 [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */
376 [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */
377
378 /* 0x11 0x0d *
379 * TV/AV MODE *
380 * SOURCE STEREO *
381 * */
382 [ 0x11 ] = KEY_TV, /*XXX*/
383 [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */
384
385 /* 0x0f 0x1b 0x1a *
386 * AUDIO Vol+ Chan+ *
387 * TIMESHIFT??? *
388 * *
389 * 0x0e 0x1f 0x1e *
390 * SLEEP Vol- Chan- *
391 * */
392 [ 0x0f ] = KEY_AUDIO,
393 [ 0x1b ] = KEY_VOLUMEUP,
394 [ 0x1a ] = KEY_CHANNELUP,
395 [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */
396 [ 0x1f ] = KEY_VOLUMEDOWN,
397 [ 0x1e ] = KEY_CHANNELDOWN,
398
399 /* 0x13 0x19 *
400 * MUTE SNAPSHOT*
401 * */
402 [ 0x13 ] = KEY_MUTE,
403 [ 0x19 ] = KEY_RECORD, /*XXX*/
404
405 // 0x1d unused ?
406};
311/* ---------------------------------------------------------------------- */ 407/* ---------------------------------------------------------------------- */
312 408
313static int build_key(struct saa7134_dev *dev) 409static int build_key(struct saa7134_dev *dev)
@@ -379,7 +475,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
379 switch (dev->board) { 475 switch (dev->board) {
380 case SAA7134_BOARD_FLYVIDEO2000: 476 case SAA7134_BOARD_FLYVIDEO2000:
381 case SAA7134_BOARD_FLYVIDEO3000: 477 case SAA7134_BOARD_FLYVIDEO3000:
382 case SAA7134_BOARD_FLYTVPLATINUM_FM: 478 case SAA7134_BOARD_FLYTVPLATINUM_FM:
383 ir_codes = flyvideo_codes; 479 ir_codes = flyvideo_codes;
384 mask_keycode = 0xEC00000; 480 mask_keycode = 0xEC00000;
385 mask_keydown = 0x0040000; 481 mask_keydown = 0x0040000;
@@ -405,8 +501,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
405 polling = 50; // ms 501 polling = 50; // ms
406 break; 502 break;
407 case SAA7134_BOARD_MD2819: 503 case SAA7134_BOARD_MD2819:
504 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
408 case SAA7134_BOARD_AVERMEDIA_305: 505 case SAA7134_BOARD_AVERMEDIA_305:
409 case SAA7134_BOARD_AVERMEDIA_307: 506 case SAA7134_BOARD_AVERMEDIA_307:
507 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
508 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
509 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
410 ir_codes = md2819_codes; 510 ir_codes = md2819_codes;
411 mask_keycode = 0x0007C8; 511 mask_keycode = 0x0007C8;
412 mask_keydown = 0x000010; 512 mask_keydown = 0x000010;
@@ -415,6 +515,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
415 saa_setb(SAA7134_GPIO_GPMODE0, 0x4); 515 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
416 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 516 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
417 break; 517 break;
518 case SAA7134_BOARD_MANLI_MTV001:
519 case SAA7134_BOARD_MANLI_MTV002:
520 ir_codes = manli_codes;
521 mask_keycode = 0x001f00;
522 mask_keyup = 0x004000;
523 mask_keydown = 0x002000;
524 polling = 50; // ms
525 break;
418 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 526 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
419 ir_codes = videomate_tv_pvr_codes; 527 ir_codes = videomate_tv_pvr_codes;
420 mask_keycode = 0x00003F; 528 mask_keycode = 0x00003F;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index 6b6a643bf1cd..81732904623f 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $ 2 * $Id: saa7134-oss.c,v 1.14 2005/05/18 22:45:16 hhackmann Exp $
3 * 3 *
4 * device driver for philips saa7134 based TV cards 4 * device driver for philips saa7134 based TV cards
5 * oss dsp interface 5 * oss dsp interface
@@ -49,7 +49,6 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
49 49
50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) 50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
51{ 51{
52 blksize &= ~0xff;
53 if (blksize < 0x100) 52 if (blksize < 0x100)
54 blksize = 0x100; 53 blksize = 0x100;
55 if (blksize > 0x10000) 54 if (blksize > 0x10000)
@@ -57,8 +56,6 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
57 56
58 if (blocks < 2) 57 if (blocks < 2)
59 blocks = 2; 58 blocks = 2;
60 while ((blksize * blocks) & ~PAGE_MASK)
61 blocks++;
62 if ((blksize * blocks) > 1024*1024) 59 if ((blksize * blocks) > 1024*1024)
63 blocks = 1024*1024 / blksize; 60 blocks = 1024*1024 / blksize;
64 61
@@ -79,7 +76,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
79 BUG(); 76 BUG();
80 videobuf_dma_init(&dev->oss.dma); 77 videobuf_dma_init(&dev->oss.dma);
81 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, 78 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
82 dev->oss.bufsize >> PAGE_SHIFT); 79 (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
83 if (0 != err) 80 if (0 != err)
84 return err; 81 return err;
85 return 0; 82 return 0;
@@ -163,10 +160,11 @@ static int dsp_rec_start(struct saa7134_dev *dev)
163 fmt |= 0x04; 160 fmt |= 0x04;
164 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; 161 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
165 162
166 saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff)); 163 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff));
167 saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8); 164 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8);
168 saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16); 165 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16);
169 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); 166 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
167
170 break; 168 break;
171 case PCI_DEVICE_ID_PHILIPS_SAA7133: 169 case PCI_DEVICE_ID_PHILIPS_SAA7133:
172 case PCI_DEVICE_ID_PHILIPS_SAA7135: 170 case PCI_DEVICE_ID_PHILIPS_SAA7135:
@@ -817,7 +815,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
817 reg = SAA7134_RS_BA1(6); 815 reg = SAA7134_RS_BA1(6);
818 } else { 816 } else {
819 /* even */ 817 /* even */
820 if (0 == (dev->oss.dma_blk & 0x00)) 818 if (1 == (dev->oss.dma_blk & 0x01))
821 reg = SAA7134_RS_BA2(6); 819 reg = SAA7134_RS_BA2(6);
822 } 820 }
823 if (0 == reg) { 821 if (0 == reg) {
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index ecac13c006d5..3617e7f7a410 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $ 2 * $Id: saa7134-tvaudio.c,v 1.25 2005/06/07 19:00:38 nsh Exp $
3 * 3 *
4 * device driver for philips saa7134 based TV cards 4 * device driver for philips saa7134 based TV cards
5 * tv audio decoder (fm stereo, nicam, ...) 5 * tv audio decoder (fm stereo, nicam, ...)
@@ -181,7 +181,8 @@ static void tvaudio_init(struct saa7134_dev *dev)
181 saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff); 181 saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff);
182 saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff); 182 saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff);
183 saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff); 183 saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff);
184 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01); 184 // frame locked audio was reported not to be reliable
185 saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x02);
185 186
186 saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14); 187 saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14);
187 saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50); 188 saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
@@ -250,6 +251,11 @@ static void mute_input_7134(struct saa7134_dev *dev)
250 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel); 251 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
251 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics); 252 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
252 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs); 253 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs);
254 // for oss, we need to change the clock configuration
255 if (in->amux == TV)
256 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
257 else
258 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x01);
253 259
254 /* switch gpio-connected external audio mux */ 260 /* switch gpio-connected external audio mux */
255 if (0 == card(dev).gpiomask) 261 if (0 == card(dev).gpiomask)
@@ -439,16 +445,15 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
439 nicam = saa_readb(SAA7134_NICAM_STATUS); 445 nicam = saa_readb(SAA7134_NICAM_STATUS);
440 dprintk("getstereo: nicam=0x%x\n",nicam); 446 dprintk("getstereo: nicam=0x%x\n",nicam);
441 switch (nicam & 0x0b) { 447 switch (nicam & 0x0b) {
448 case 0x08:
449 retval = V4L2_TUNER_SUB_MONO;
450 break;
442 case 0x09: 451 case 0x09:
443 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 452 retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
444 break; 453 break;
445 case 0x0a: 454 case 0x0a:
446 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 455 retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
447 break; 456 break;
448 case 0x08:
449 default:
450 retval = V4L2_TUNER_SUB_MONO;
451 break;
452 } 457 }
453 break; 458 break;
454 } 459 }
@@ -572,14 +577,14 @@ static int tvaudio_thread(void *data)
572 } else if (0 != dev->last_carrier) { 577 } else if (0 != dev->last_carrier) {
573 /* no carrier -- try last detected one as fallback */ 578 /* no carrier -- try last detected one as fallback */
574 carrier = dev->last_carrier; 579 carrier = dev->last_carrier;
575 printk(KERN_WARNING "%s/audio: audio carrier scan failed, " 580 dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
576 "using %d.%03d MHz [last detected]\n", 581 "using %d.%03d MHz [last detected]\n",
577 dev->name, carrier/1000, carrier%1000); 582 dev->name, carrier/1000, carrier%1000);
578 583
579 } else { 584 } else {
580 /* no carrier + no fallback -- use default */ 585 /* no carrier + no fallback -- use default */
581 carrier = default_carrier; 586 carrier = default_carrier;
582 printk(KERN_WARNING "%s/audio: audio carrier scan failed, " 587 dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
583 "using %d.%03d MHz [default]\n", 588 "using %d.%03d MHz [default]\n",
584 dev->name, carrier/1000, carrier%1000); 589 dev->name, carrier/1000, carrier%1000);
585 } 590 }
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
index 86954cc7c377..3c33c591cc85 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $ 2 * $Id: saa7134-vbi.c,v 1.7 2005/05/24 23:13:06 nsh Exp $
3 * 3 *
4 * device driver for philips saa7134 based TV cards 4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface 5 * video4linux video interface
@@ -60,10 +60,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
60 saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8); 60 saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8);
61 saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff); 61 saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff);
62 saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8); 62 saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8);
63 saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start & 0xff); 63 saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start_0 & 0xff);
64 saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8); 64 saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start_0 >> 8);
65 saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop & 0xff); 65 saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop_0 & 0xff);
66 saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop >> 8); 66 saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop_0 >> 8);
67 67
68 saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff); 68 saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff);
69 saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8); 69 saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8);
@@ -127,7 +127,7 @@ static int buffer_prepare(struct videobuf_queue *q,
127 unsigned int lines, llength, size; 127 unsigned int lines, llength, size;
128 int err; 128 int err;
129 129
130 lines = norm->vbi_v_stop - norm->vbi_v_start +1; 130 lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
131 if (lines > VBI_LINE_COUNT) 131 if (lines > VBI_LINE_COUNT)
132 lines = VBI_LINE_COUNT; 132 lines = VBI_LINE_COUNT;
133#if 1 133#if 1
@@ -177,7 +177,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
177 struct saa7134_dev *dev = fh->dev; 177 struct saa7134_dev *dev = fh->dev;
178 int llength,lines; 178 int llength,lines;
179 179
180 lines = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1; 180 lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
181#if 1 181#if 1
182 llength = VBI_LINE_LENGTH; 182 llength = VBI_LINE_LENGTH;
183#else 183#else
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 5d66060026ff..c0a2ee520531 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $ 2 * $Id: saa7134-video.c,v 1.30 2005/06/07 19:00:38 nsh Exp $
3 * 3 *
4 * device driver for philips saa7134 based TV cards 4 * device driver for philips saa7134 based TV cards
5 * video4linux video interface 5 * video4linux video interface
@@ -31,8 +31,6 @@
31#include "saa7134-reg.h" 31#include "saa7134-reg.h"
32#include "saa7134.h" 32#include "saa7134.h"
33 33
34#define V4L2_I2C_CLIENTS 1
35
36/* ------------------------------------------------------------------ */ 34/* ------------------------------------------------------------------ */
37 35
38static unsigned int video_debug = 0; 36static unsigned int video_debug = 0;
@@ -158,18 +156,20 @@ static struct saa7134_format formats[] = {
158 .h_stop = 719, \ 156 .h_stop = 719, \
159 .video_v_start = 24, \ 157 .video_v_start = 24, \
160 .video_v_stop = 311, \ 158 .video_v_stop = 311, \
161 .vbi_v_start = 7, \ 159 .vbi_v_start_0 = 7, \
162 .vbi_v_stop = 22, \ 160 .vbi_v_stop_0 = 22, \
161 .vbi_v_start_1 = 319, \
163 .src_timing = 4 162 .src_timing = 4
164 163
165#define NORM_525_60 \ 164#define NORM_525_60 \
166 .h_start = 0, \ 165 .h_start = 0, \
167 .h_stop = 703, \ 166 .h_stop = 703, \
168 .video_v_start = 22, \ 167 .video_v_start = 23, \
169 .video_v_stop = 22+239, \ 168 .video_v_stop = 262, \
170 .vbi_v_start = 10, /* FIXME */ \ 169 .vbi_v_start_0 = 10, \
171 .vbi_v_stop = 21, /* FIXME */ \ 170 .vbi_v_stop_0 = 21, \
172 .src_timing = 1 171 .vbi_v_start_1 = 273, \
172 .src_timing = 7
173 173
174static struct saa7134_tvnorm tvnorms[] = { 174static struct saa7134_tvnorm tvnorms[] = {
175 { 175 {
@@ -274,11 +274,12 @@ static struct saa7134_tvnorm tvnorms[] = {
274 274
275 .h_start = 0, 275 .h_start = 0,
276 .h_stop = 719, 276 .h_stop = 719,
277 .video_v_start = 22, 277 .video_v_start = 23,
278 .video_v_stop = 22+239, 278 .video_v_stop = 262,
279 .vbi_v_start = 10, /* FIXME */ 279 .vbi_v_start_0 = 10,
280 .vbi_v_stop = 21, /* FIXME */ 280 .vbi_v_stop_0 = 21,
281 .src_timing = 1, 281 .vbi_v_start_1 = 273,
282 .src_timing = 7,
282 283
283 .sync_control = 0x18, 284 .sync_control = 0x18,
284 .luma_control = 0x40, 285 .luma_control = 0x40,
@@ -335,8 +336,8 @@ static const struct v4l2_queryctrl video_ctrls[] = {
335 .default_value = 0, 336 .default_value = 0,
336 .type = V4L2_CTRL_TYPE_INTEGER, 337 .type = V4L2_CTRL_TYPE_INTEGER,
337 },{ 338 },{
338 .id = V4L2_CID_VFLIP, 339 .id = V4L2_CID_HFLIP,
339 .name = "vertical flip", 340 .name = "Mirror",
340 .minimum = 0, 341 .minimum = 0,
341 .maximum = 1, 342 .maximum = 1,
342 .type = V4L2_CTRL_TYPE_BOOLEAN, 343 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -482,7 +483,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
482 dev->crop_bounds.width = norm->h_stop - norm->h_start +1; 483 dev->crop_bounds.width = norm->h_stop - norm->h_start +1;
483 dev->crop_defrect.width = norm->h_stop - norm->h_start +1; 484 dev->crop_defrect.width = norm->h_stop - norm->h_start +1;
484 485
485 dev->crop_bounds.top = (norm->vbi_v_stop+1)*2; 486 dev->crop_bounds.top = (norm->vbi_v_stop_0+1)*2;
486 dev->crop_defrect.top = norm->video_v_start*2; 487 dev->crop_defrect.top = norm->video_v_start*2;
487 dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624) 488 dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
488 - dev->crop_bounds.top; 489 - dev->crop_bounds.top;
@@ -521,22 +522,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
521 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40); 522 saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
522 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80); 523 saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
523 524
524#ifdef V4L2_I2C_CLIENTS
525 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id); 525 saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
526#else
527 {
528 /* pass down info to the i2c chips (v4l1) */
529 struct video_channel c;
530 memset(&c,0,sizeof(c));
531 c.channel = dev->ctl_input;
532 c.norm = VIDEO_MODE_PAL;
533 if (norm->id & V4L2_STD_NTSC)
534 c.norm = VIDEO_MODE_NTSC;
535 if (norm->id & V4L2_STD_SECAM)
536 c.norm = VIDEO_MODE_SECAM;
537 saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c);
538 }
539#endif
540} 526}
541 527
542static void video_mux(struct saa7134_dev *dev, int input) 528static void video_mux(struct saa7134_dev *dev, int input)
@@ -1064,7 +1050,7 @@ static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
1064 case V4L2_CID_PRIVATE_INVERT: 1050 case V4L2_CID_PRIVATE_INVERT:
1065 c->value = dev->ctl_invert; 1051 c->value = dev->ctl_invert;
1066 break; 1052 break;
1067 case V4L2_CID_VFLIP: 1053 case V4L2_CID_HFLIP:
1068 c->value = dev->ctl_mirror; 1054 c->value = dev->ctl_mirror;
1069 break; 1055 break;
1070 case V4L2_CID_PRIVATE_Y_EVEN: 1056 case V4L2_CID_PRIVATE_Y_EVEN:
@@ -1139,7 +1125,7 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
1139 saa_writeb(SAA7134_DEC_CHROMA_SATURATION, 1125 saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1140 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); 1126 dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1141 break; 1127 break;
1142 case V4L2_CID_VFLIP: 1128 case V4L2_CID_HFLIP:
1143 dev->ctl_mirror = c->value; 1129 dev->ctl_mirror = c->value;
1144 restart_overlay = 1; 1130 restart_overlay = 1;
1145 break; 1131 break;
@@ -1407,9 +1393,9 @@ static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
1407 f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */; 1393 f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
1408 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 1394 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1409 f->fmt.vbi.offset = 64 * 4; 1395 f->fmt.vbi.offset = 64 * 4;
1410 f->fmt.vbi.start[0] = norm->vbi_v_start; 1396 f->fmt.vbi.start[0] = norm->vbi_v_start_0;
1411 f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1; 1397 f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
1412 f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1; 1398 f->fmt.vbi.start[1] = norm->vbi_v_start_1;
1413 f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; 1399 f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
1414 f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */ 1400 f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
1415 1401
@@ -1880,11 +1866,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1880 return -EINVAL; 1866 return -EINVAL;
1881 down(&dev->lock); 1867 down(&dev->lock);
1882 dev->ctl_freq = f->frequency; 1868 dev->ctl_freq = f->frequency;
1883#ifdef V4L2_I2C_CLIENTS 1869
1884 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); 1870 saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
1885#else 1871
1886 saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);
1887#endif
1888 saa7134_tvaudio_do_scan(dev); 1872 saa7134_tvaudio_do_scan(dev);
1889 up(&dev->lock); 1873 up(&dev->lock);
1890 return 0; 1874 return 0;
@@ -2139,16 +2123,19 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2139 t->rangelow = (int)(65*16); 2123 t->rangelow = (int)(65*16);
2140 t->rangehigh = (int)(108*16); 2124 t->rangehigh = (int)(108*16);
2141 2125
2142#ifdef V4L2_I2C_CLIENTS 2126 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
2143 saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t); 2127
2144#else 2128 return 0;
2145 { 2129 }
2146 struct video_tuner vt; 2130 case VIDIOC_S_TUNER:
2147 memset(&vt,0,sizeof(vt)); 2131 {
2148 saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt); 2132 struct v4l2_tuner *t = arg;
2149 t->signal = vt.signal; 2133
2150 } 2134 if (0 != t->index)
2151#endif 2135 return -EINVAL;
2136
2137 saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t);
2138
2152 return 0; 2139 return 0;
2153 } 2140 }
2154 case VIDIOC_ENUMINPUT: 2141 case VIDIOC_ENUMINPUT:
@@ -2182,7 +2169,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2182 return 0; 2169 return 0;
2183 } 2170 }
2184 case VIDIOC_S_AUDIO: 2171 case VIDIOC_S_AUDIO:
2185 case VIDIOC_S_TUNER:
2186 case VIDIOC_S_INPUT: 2172 case VIDIOC_S_INPUT:
2187 case VIDIOC_S_STD: 2173 case VIDIOC_S_STD:
2188 return 0; 2174 return 0;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index ac90a9853236..d6b1c0d4d0f9 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $ 2 * $Id: saa7134.h,v 1.41 2005/06/07 18:02:26 nsh Exp $
3 * 3 *
4 * v4l2 device driver for philips saa7134 based TV cards 4 * v4l2 device driver for philips saa7134 based TV cards
5 * 5 *
@@ -21,7 +21,7 @@
21 */ 21 */
22 22
23#include <linux/version.h> 23#include <linux/version.h>
24#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12) 24#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,13)
25 25
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
@@ -91,9 +91,10 @@ struct saa7134_tvnorm {
91 unsigned int h_stop; 91 unsigned int h_stop;
92 unsigned int video_v_start; 92 unsigned int video_v_start;
93 unsigned int video_v_stop; 93 unsigned int video_v_stop;
94 unsigned int vbi_v_start; 94 unsigned int vbi_v_start_0;
95 unsigned int vbi_v_stop; 95 unsigned int vbi_v_stop_0;
96 unsigned int src_timing; 96 unsigned int src_timing;
97 unsigned int vbi_v_start_1;
97}; 98};
98 99
99struct saa7134_tvaudio { 100struct saa7134_tvaudio {
@@ -167,7 +168,7 @@ struct saa7134_format {
167#define SAA7134_BOARD_SABRENT_SBTTVFM 42 168#define SAA7134_BOARD_SABRENT_SBTTVFM 42
168#define SAA7134_BOARD_ZOLID_XPERT_TV7134 43 169#define SAA7134_BOARD_ZOLID_XPERT_TV7134 43
169#define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44 170#define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44
170#define SAA7134_BOARD_AVERMEDIA_307 45 171#define SAA7134_BOARD_AVERMEDIA_STUDIO_307 45
171#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46 172#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
172#define SAA7134_BOARD_CINERGY400_CARDBUS 47 173#define SAA7134_BOARD_CINERGY400_CARDBUS 47
173#define SAA7134_BOARD_CINERGY600_MK3 48 174#define SAA7134_BOARD_CINERGY600_MK3 48
@@ -178,6 +179,10 @@ struct saa7134_format {
178#define SAA7135_BOARD_ASUSTeK_TVFM7135 53 179#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
179#define SAA7134_BOARD_FLYTVPLATINUM_FM 54 180#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
180#define SAA7134_BOARD_FLYDVBTDUO 55 181#define SAA7134_BOARD_FLYDVBTDUO 55
182#define SAA7134_BOARD_AVERMEDIA_307 56
183#define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
184#define SAA7134_BOARD_ADS_INSTANT_TV 58
185#define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
181 186
182#define SAA7134_MAXBOARDS 8 187#define SAA7134_MAXBOARDS 8
183#define SAA7134_INPUT_MAX 8 188#define SAA7134_INPUT_MAX 8
@@ -241,7 +246,7 @@ struct saa7134_dma;
241/* saa7134 page table */ 246/* saa7134 page table */
242struct saa7134_pgtable { 247struct saa7134_pgtable {
243 unsigned int size; 248 unsigned int size;
244 u32 *cpu; 249 __le32 *cpu;
245 dma_addr_t dma; 250 dma_addr_t dma;
246}; 251};
247 252
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 7e6e6dd966a2..39773633cc3c 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -53,6 +53,7 @@ struct tda9887 {
53 unsigned int config; 53 unsigned int config;
54 unsigned int pinnacle_id; 54 unsigned int pinnacle_id;
55 unsigned int using_v4l2; 55 unsigned int using_v4l2;
56 unsigned int radio_mode;
56}; 57};
57 58
58struct tvnorm { 59struct tvnorm {
@@ -212,12 +213,22 @@ static struct tvnorm tvnorms[] = {
212 } 213 }
213}; 214};
214 215
215static struct tvnorm radio = { 216static struct tvnorm radio_stereo = {
216 .name = "radio", 217 .name = "Radio Stereo",
218 .b = ( cFmRadio |
219 cQSS ),
220 .c = ( cDeemphasisOFF |
221 cAudioGain6 ),
222 .e = ( cAudioIF_5_5 |
223 cRadioIF_38_90 ),
224};
225
226static struct tvnorm radio_mono = {
227 .name = "Radio Mono",
217 .b = ( cFmRadio | 228 .b = ( cFmRadio |
218 cQSS ), 229 cQSS ),
219 .c = ( cDeemphasisON | 230 .c = ( cDeemphasisON |
220 cDeemphasis50 ), 231 cDeemphasis50),
221 .e = ( cAudioIF_5_5 | 232 .e = ( cAudioIF_5_5 |
222 cRadioIF_38_90 ), 233 cRadioIF_38_90 ),
223}; 234};
@@ -354,7 +365,10 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
354 int i; 365 int i;
355 366
356 if (t->radio) { 367 if (t->radio) {
357 norm = &radio; 368 if (t->radio_mode == V4L2_TUNER_MODE_MONO)
369 norm = &radio_mono;
370 else
371 norm = &radio_stereo;
358 } else { 372 } else {
359 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { 373 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
360 if (tvnorms[i].std & t->std) { 374 if (tvnorms[i].std & t->std) {
@@ -545,11 +559,14 @@ static int tda9887_configure(struct tda9887 *t)
545 559
546 memset(buf,0,sizeof(buf)); 560 memset(buf,0,sizeof(buf));
547 tda9887_set_tvnorm(t,buf); 561 tda9887_set_tvnorm(t,buf);
562
548 buf[1] |= cOutputPort1Inactive; 563 buf[1] |= cOutputPort1Inactive;
549 buf[1] |= cOutputPort2Inactive; 564 buf[1] |= cOutputPort2Inactive;
565
550 if (UNSET != t->pinnacle_id) { 566 if (UNSET != t->pinnacle_id) {
551 tda9887_set_pinnacle(t,buf); 567 tda9887_set_pinnacle(t,buf);
552 } 568 }
569
553 tda9887_set_config(t,buf); 570 tda9887_set_config(t,buf);
554 tda9887_set_insmod(t,buf); 571 tda9887_set_insmod(t,buf);
555 572
@@ -592,9 +609,12 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
592 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 609 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
593 return -ENOMEM; 610 return -ENOMEM;
594 memset(t,0,sizeof(*t)); 611 memset(t,0,sizeof(*t));
612
595 t->client = client_template; 613 t->client = client_template;
596 t->std = 0; 614 t->std = 0;
597 t->pinnacle_id = UNSET; 615 t->pinnacle_id = UNSET;
616 t->radio_mode = V4L2_TUNER_MODE_STEREO;
617
598 i2c_set_clientdata(&t->client, t); 618 i2c_set_clientdata(&t->client, t);
599 i2c_attach_client(&t->client); 619 i2c_attach_client(&t->client);
600 620
@@ -733,6 +753,16 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
733 } 753 }
734 break; 754 break;
735 } 755 }
756 case VIDIOC_S_TUNER:
757 {
758 struct v4l2_tuner* tuner = arg;
759
760 if (t->radio) {
761 t->radio_mode = tuner->audmode;
762 tda9887_configure (t);
763 }
764 break;
765 }
736 default: 766 default:
737 /* nothing */ 767 /* nothing */
738 break; 768 break;
@@ -740,7 +770,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
740 return 0; 770 return 0;
741} 771}
742 772
743static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level) 773static int tda9887_suspend(struct device * dev, u32 state, u32 level)
744{ 774{
745 dprintk("tda9887: suspend\n"); 775 dprintk("tda9887: suspend\n");
746 return 0; 776 return 0;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 81882ddab859..eaabfc858703 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: tuner-core.c,v 1.5 2005/02/15 15:59:35 kraxel Exp $ 2 * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $
3 * 3 *
4 * i2c tv tuner chip device driver 4 * i2c tv tuner chip device driver
5 * core core, i.e. kernel interfaces, registering and so on 5 * core core, i.e. kernel interfaces, registering and so on
@@ -23,6 +23,11 @@
23#include <media/tuner.h> 23#include <media/tuner.h>
24#include <media/audiochip.h> 24#include <media/audiochip.h>
25 25
26/*
27 * comment line bellow to return to old behavor, where only one I2C device is supported
28 */
29#define CONFIG_TUNER_MULTI_I2C /**/
30
26#define UNSET (-1U) 31#define UNSET (-1U)
27 32
28/* standard i2c insmod options */ 33/* standard i2c insmod options */
@@ -53,13 +58,16 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
53MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
54 59
55static int this_adap; 60static int this_adap;
61#ifdef CONFIG_TUNER_MULTI_I2C
62static unsigned short first_tuner, tv_tuner, radio_tuner;
63#endif
56 64
57static struct i2c_driver driver; 65static struct i2c_driver driver;
58static struct i2c_client client_template; 66static struct i2c_client client_template;
59 67
60/* ---------------------------------------------------------------------- */ 68/* ---------------------------------------------------------------------- */
61 69
62// Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz 70/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */
63static void set_tv_freq(struct i2c_client *c, unsigned int freq) 71static void set_tv_freq(struct i2c_client *c, unsigned int freq)
64{ 72{
65 struct tuner *t = i2c_get_clientdata(c); 73 struct tuner *t = i2c_get_clientdata(c);
@@ -73,14 +81,26 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
73 return; 81 return;
74 } 82 }
75 if (freq < tv_range[0]*16 || freq > tv_range[1]*16) { 83 if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
76 /* FIXME: better do that chip-specific, but 84
77 right now we don't have that in the config 85 if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
78 struct and this way is still better than no 86 /* V4L2_TUNER_CAP_LOW frequency */
79 check at all */ 87
80 tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", 88 tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n");
81 freq/16,freq%16*100/16,tv_range[0],tv_range[1]); 89
82 return; 90 t->tv_freq(c,freq>>10);
91
92 return;
93 } else {
94 /* FIXME: better do that chip-specific, but
95 right now we don't have that in the config
96 struct and this way is still better than no
97 check at all */
98 tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
99 freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
100 return;
101 }
83 } 102 }
103 tuner_dbg("62.5 Khz freq step selected for TV.\n");
84 t->tv_freq(c,freq); 104 t->tv_freq(c,freq);
85} 105}
86 106
@@ -97,11 +117,29 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
97 return; 117 return;
98 } 118 }
99 if (freq < radio_range[0]*16 || freq > radio_range[1]*16) { 119 if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
100 tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", 120 if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
121 /* V4L2_TUNER_CAP_LOW frequency */
122 if (t->type == TUNER_TEA5767) {
123 tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
124 t->radio_freq(c,freq>>10);
125 return;
126 }
127
128 tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n");
129
130 tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
131
132 t->radio_freq(c,freq>>10);
133 return;
134
135 } else {
136 tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
101 freq/16,freq%16*100/16, 137 freq/16,freq%16*100/16,
102 radio_range[0],radio_range[1]); 138 radio_range[0],radio_range[1]);
103 return; 139 return;
140 }
104 } 141 }
142 tuner_dbg("62.5 Khz freq step selected for Radio.\n");
105 t->radio_freq(c,freq); 143 t->radio_freq(c,freq);
106} 144}
107 145
@@ -129,8 +167,9 @@ static void set_type(struct i2c_client *c, unsigned int type)
129{ 167{
130 struct tuner *t = i2c_get_clientdata(c); 168 struct tuner *t = i2c_get_clientdata(c);
131 169
170 tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
132 /* sanity check */ 171 /* sanity check */
133 if (type == UNSET || type == TUNER_ABSENT) 172 if (type == UNSET || type == TUNER_ABSENT)
134 return; 173 return;
135 if (type >= tuner_count) 174 if (type >= tuner_count)
136 return; 175 return;
@@ -145,6 +184,7 @@ static void set_type(struct i2c_client *c, unsigned int type)
145 return; 184 return;
146 185
147 t->initialized = 1; 186 t->initialized = 1;
187
148 t->type = type; 188 t->type = type;
149 switch (t->type) { 189 switch (t->type) {
150 case TUNER_MT2032: 190 case TUNER_MT2032:
@@ -159,6 +199,53 @@ static void set_type(struct i2c_client *c, unsigned int type)
159 } 199 }
160} 200}
161 201
202#ifdef CONFIG_TUNER_MULTI_I2C
203#define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \
204 return 0; } else \
205 tuner_info ("Cmd %s accepted to "tun"\n",cmd);
206#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \
207 CHECK_ADDR(radio_tuner,cmd,"radio") } else \
208 { CHECK_ADDR(tv_tuner,cmd,"TV"); }
209#else
210#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd);
211#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd);
212#endif
213
214#ifdef CONFIG_TUNER_MULTI_I2C
215
216static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
217{
218 /* ADDR_UNSET defaults to first available tuner */
219 if ( tun_addr->addr == ADDR_UNSET ) {
220 if (first_tuner != c->addr)
221 return;
222 switch (tun_addr->v4l2_tuner) {
223 case V4L2_TUNER_RADIO:
224 radio_tuner=c->addr;
225 break;
226 default:
227 tv_tuner=c->addr;
228 break;
229 }
230 } else {
231 /* Sets tuner to its configured value */
232 switch (tun_addr->v4l2_tuner) {
233 case V4L2_TUNER_RADIO:
234 radio_tuner=tun_addr->addr;
235 if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
236 return;
237 default:
238 tv_tuner=tun_addr->addr;
239 if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
240 return;
241 }
242 }
243 set_type(c,tun_addr->type);
244}
245#else
246#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type)
247#endif
248
162static char pal[] = "-"; 249static char pal[] = "-";
163module_param_string(pal, pal, sizeof(pal), 0644); 250module_param_string(pal, pal, sizeof(pal), 0644);
164 251
@@ -197,8 +284,17 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
197{ 284{
198 struct tuner *t; 285 struct tuner *t;
199 286
287#ifndef CONFIG_TUNER_MULTI_I2C
200 if (this_adap > 0) 288 if (this_adap > 0)
201 return -1; 289 return -1;
290#else
291 /* by default, first I2C card is both tv and radio tuner */
292 if (this_adap == 0) {
293 first_tuner = addr;
294 tv_tuner = addr;
295 radio_tuner = addr;
296 }
297#endif
202 this_adap++; 298 this_adap++;
203 299
204 client_template.adapter = adap; 300 client_template.adapter = adap;
@@ -211,11 +307,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
211 memcpy(&t->i2c,&client_template,sizeof(struct i2c_client)); 307 memcpy(&t->i2c,&client_template,sizeof(struct i2c_client));
212 i2c_set_clientdata(&t->i2c, t); 308 i2c_set_clientdata(&t->i2c, t);
213 t->type = UNSET; 309 t->type = UNSET;
214 t->radio_if2 = 10700*1000; // 10.7MHz - FM radio 310 t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */
215 311
216 i2c_attach_client(&t->i2c); 312 i2c_attach_client(&t->i2c);
217 tuner_info("chip found @ 0x%x (%s)\n", 313 tuner_info("chip found @ 0x%x (%s)\n",
218 addr << 1, adap->name); 314 addr << 1, adap->name);
315
219 set_type(&t->i2c, t->type); 316 set_type(&t->i2c, t->type);
220 return 0; 317 return 0;
221} 318}
@@ -228,6 +325,12 @@ static int tuner_probe(struct i2c_adapter *adap)
228 } 325 }
229 this_adap = 0; 326 this_adap = 0;
230 327
328#ifdef CONFIG_TUNER_MULTI_I2C
329 first_tuner = 0;
330 tv_tuner = 0;
331 radio_tuner = 0;
332#endif
333
231 if (adap->class & I2C_CLASS_TV_ANALOG) 334 if (adap->class & I2C_CLASS_TV_ANALOG)
232 return i2c_probe(adap, &addr_data, tuner_attach); 335 return i2c_probe(adap, &addr_data, tuner_attach);
233 return 0; 336 return 0;
@@ -236,8 +339,14 @@ static int tuner_probe(struct i2c_adapter *adap)
236static int tuner_detach(struct i2c_client *client) 339static int tuner_detach(struct i2c_client *client)
237{ 340{
238 struct tuner *t = i2c_get_clientdata(client); 341 struct tuner *t = i2c_get_clientdata(client);
342 int err;
343
344 err=i2c_detach_client(&t->i2c);
345 if (err) {
346 tuner_warn ("Client deregistration failed, client not detached.\n");
347 return err;
348 }
239 349
240 i2c_detach_client(&t->i2c);
241 kfree(t); 350 kfree(t);
242 return 0; 351 return 0;
243} 352}
@@ -256,18 +365,23 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
256 unsigned int *iarg = (int*)arg; 365 unsigned int *iarg = (int*)arg;
257 366
258 switch (cmd) { 367 switch (cmd) {
259
260 /* --- configuration --- */ 368 /* --- configuration --- */
261 case TUNER_SET_TYPE: 369 case TUNER_SET_TYPE:
262 set_type(client,*iarg); 370 set_type(client,*iarg);
263 break; 371 break;
372 case TUNER_SET_TYPE_ADDR:
373 set_addr(client,(struct tuner_addr *)arg);
374 break;
264 case AUDC_SET_RADIO: 375 case AUDC_SET_RADIO:
376 t->mode = V4L2_TUNER_RADIO;
377 CHECK_ADDR(tv_tuner,"AUDC_SET_RADIO","TV");
378
265 if (V4L2_TUNER_RADIO != t->mode) { 379 if (V4L2_TUNER_RADIO != t->mode) {
266 set_tv_freq(client,400 * 16); 380 set_tv_freq(client,400 * 16);
267 t->mode = V4L2_TUNER_RADIO;
268 } 381 }
269 break; 382 break;
270 case AUDC_CONFIG_PINNACLE: 383 case AUDC_CONFIG_PINNACLE:
384 CHECK_ADDR(tv_tuner,"AUDC_CONFIG_PINNACLE","TV");
271 switch (*iarg) { 385 switch (*iarg) {
272 case 2: 386 case 2:
273 tuner_dbg("pinnacle pal\n"); 387 tuner_dbg("pinnacle pal\n");
@@ -297,6 +411,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
297 411
298 CHECK_V4L2; 412 CHECK_V4L2;
299 t->mode = V4L2_TUNER_ANALOG_TV; 413 t->mode = V4L2_TUNER_ANALOG_TV;
414 CHECK_ADDR(tv_tuner,"VIDIOCSCHAN","TV");
415
300 if (vc->norm < ARRAY_SIZE(map)) 416 if (vc->norm < ARRAY_SIZE(map))
301 t->std = map[vc->norm]; 417 t->std = map[vc->norm];
302 tuner_fixup_std(t); 418 tuner_fixup_std(t);
@@ -308,6 +424,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
308 { 424 {
309 unsigned long *v = arg; 425 unsigned long *v = arg;
310 426
427 CHECK_MODE("VIDIOCSFREQ");
311 CHECK_V4L2; 428 CHECK_V4L2;
312 set_freq(client,*v); 429 set_freq(client,*v);
313 return 0; 430 return 0;
@@ -316,15 +433,27 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
316 { 433 {
317 struct video_tuner *vt = arg; 434 struct video_tuner *vt = arg;
318 435
436 CHECK_ADDR(radio_tuner,"VIDIOCGTUNER","radio");
319 CHECK_V4L2; 437 CHECK_V4L2;
320 if (V4L2_TUNER_RADIO == t->mode && t->has_signal) 438 if (V4L2_TUNER_RADIO == t->mode) {
321 vt->signal = t->has_signal(client); 439 if (t->has_signal)
440 vt->signal = t->has_signal(client);
441 if (t->is_stereo) {
442 if (t->is_stereo(client))
443 vt-> flags |= VIDEO_TUNER_STEREO_ON;
444 else
445 vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON;
446 }
447 vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */
448 }
449
322 return 0; 450 return 0;
323 } 451 }
324 case VIDIOCGAUDIO: 452 case VIDIOCGAUDIO:
325 { 453 {
326 struct video_audio *va = arg; 454 struct video_audio *va = arg;
327 455
456 CHECK_ADDR(radio_tuner,"VIDIOCGAUDIO","radio");
328 CHECK_V4L2; 457 CHECK_V4L2;
329 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo) 458 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
330 va->mode = t->is_stereo(client) 459 va->mode = t->is_stereo(client)
@@ -339,6 +468,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
339 468
340 SWITCH_V4L2; 469 SWITCH_V4L2;
341 t->mode = V4L2_TUNER_ANALOG_TV; 470 t->mode = V4L2_TUNER_ANALOG_TV;
471 CHECK_ADDR(tv_tuner,"VIDIOC_S_STD","TV");
472
342 t->std = *id; 473 t->std = *id;
343 tuner_fixup_std(t); 474 tuner_fixup_std(t);
344 if (t->freq) 475 if (t->freq)
@@ -349,6 +480,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
349 { 480 {
350 struct v4l2_frequency *f = arg; 481 struct v4l2_frequency *f = arg;
351 482
483 CHECK_MODE("VIDIOC_S_FREQUENCY");
352 SWITCH_V4L2; 484 SWITCH_V4L2;
353 if (V4L2_TUNER_RADIO == f->type && 485 if (V4L2_TUNER_RADIO == f->type &&
354 V4L2_TUNER_RADIO != t->mode) 486 V4L2_TUNER_RADIO != t->mode)
@@ -361,6 +493,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
361 { 493 {
362 struct v4l2_frequency *f = arg; 494 struct v4l2_frequency *f = arg;
363 495
496 CHECK_MODE("VIDIOC_G_FREQUENCY");
364 SWITCH_V4L2; 497 SWITCH_V4L2;
365 f->type = t->mode; 498 f->type = t->mode;
366 f->frequency = t->freq; 499 f->frequency = t->freq;
@@ -370,14 +503,29 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
370 { 503 {
371 struct v4l2_tuner *tuner = arg; 504 struct v4l2_tuner *tuner = arg;
372 505
506 CHECK_MODE("VIDIOC_G_TUNER");
373 SWITCH_V4L2; 507 SWITCH_V4L2;
374 if (V4L2_TUNER_RADIO == t->mode && t->has_signal) 508 if (V4L2_TUNER_RADIO == t->mode) {
375 tuner->signal = t->has_signal(client); 509 if (t->has_signal)
510 tuner -> signal = t->has_signal(client);
511 if (t->is_stereo) {
512 if (t->is_stereo(client)) {
513 tuner -> capability |= V4L2_TUNER_CAP_STEREO;
514 tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO;
515 } else {
516 tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO;
517 }
518 }
519 }
520 /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */
376 tuner->rangelow = tv_range[0] * 16; 521 tuner->rangelow = tv_range[0] * 16;
377 tuner->rangehigh = tv_range[1] * 16; 522// tuner->rangehigh = tv_range[1] * 16;
523// tuner->rangelow = tv_range[0] * 16384;
524 tuner->rangehigh = tv_range[1] * 16384;
378 break; 525 break;
379 } 526 }
380 default: 527 default:
528 tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
381 /* nothing */ 529 /* nothing */
382 break; 530 break;
383 } 531 }
@@ -385,7 +533,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
385 return 0; 533 return 0;
386} 534}
387 535
388static int tuner_suspend(struct device * dev, pm_message_t state, u32 level) 536static int tuner_suspend(struct device * dev, u32 state, u32 level)
389{ 537{
390 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 538 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
391 struct tuner *t = i2c_get_clientdata(c); 539 struct tuner *t = i2c_get_clientdata(c);
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 48c6ceff1dc2..539f30557317 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: tuner-simple.c,v 1.10 2005/03/08 08:38:00 kraxel Exp $ 2 * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $
3 * 3 *
4 * i2c tv tuner chip device driver 4 * i2c tv tuner chip device driver
5 * controls all those simple 4-control-bytes style tuners. 5 * controls all those simple 4-control-bytes style tuners.
@@ -212,7 +212,25 @@ static struct tunertype tuners[] = {
212 { "Philips FQ1236A MK4", Philips, NTSC, 212 { "Philips FQ1236A MK4", Philips, NTSC,
213 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 213 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
214 214
215 /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
216 { "Ymec TVision TVF-8531MF", Philips, NTSC,
217 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
218 { "Ymec TVision TVF-5533MF", Philips, NTSC,
219 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
220
221 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
222 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
223 { "Tena TNF9533-D/IF", LGINNOTEK, PAL,
224 16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623},
225
226 /*
227 * This entry is for TEA5767 FM radio only chip used on several boards
228 * w/TV tuner
229 */
230 { TEA5767_TUNER_NAME, Philips, RADIO,
231 -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
215}; 232};
233
216unsigned const int tuner_count = ARRAY_SIZE(tuners); 234unsigned const int tuner_count = ARRAY_SIZE(tuners);
217 235
218/* ---------------------------------------------------------------------- */ 236/* ---------------------------------------------------------------------- */
@@ -223,6 +241,7 @@ static int tuner_getstatus(struct i2c_client *c)
223 241
224 if (1 != i2c_master_recv(c,&byte,1)) 242 if (1 != i2c_master_recv(c,&byte,1))
225 return 0; 243 return 0;
244
226 return byte; 245 return byte;
227} 246}
228 247
@@ -231,17 +250,33 @@ static int tuner_getstatus(struct i2c_client *c)
231#define TUNER_MODE 0x38 250#define TUNER_MODE 0x38
232#define TUNER_AFC 0x07 251#define TUNER_AFC 0x07
233 252
234#define TUNER_STEREO 0x10 /* radio mode */ 253#define TUNER_STEREO 0x10 /* radio mode */
235#define TUNER_SIGNAL 0x07 /* radio mode */ 254#define TUNER_STEREO_MK3 0x04 /* radio mode */
255#define TUNER_SIGNAL 0x07 /* radio mode */
236 256
237static int tuner_signal(struct i2c_client *c) 257static int tuner_signal(struct i2c_client *c)
238{ 258{
239 return (tuner_getstatus(c) & TUNER_SIGNAL)<<13; 259 return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
240} 260}
241 261
242static int tuner_stereo(struct i2c_client *c) 262static int tuner_stereo(struct i2c_client *c)
243{ 263{
244 return (tuner_getstatus (c) & TUNER_STEREO); 264 int stereo, status;
265 struct tuner *t = i2c_get_clientdata(c);
266
267 status = tuner_getstatus (c);
268
269 switch (t->type) {
270 case TUNER_PHILIPS_FM1216ME_MK3:
271 case TUNER_PHILIPS_FM1236_MK3:
272 case TUNER_PHILIPS_FM1256_IH3:
273 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
274 break;
275 default:
276 stereo = status & TUNER_STEREO;
277 }
278
279 return stereo;
245} 280}
246 281
247#if 0 /* unused */ 282#if 0 /* unused */
@@ -424,6 +459,14 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
424 buffer[2] = tun->config; 459 buffer[2] = tun->config;
425 460
426 switch (t->type) { 461 switch (t->type) {
462 case TUNER_TENA_9533_DI:
463 case TUNER_YMEC_TVF_5533MF:
464
465 /*These values are empirically determinated */
466 div = (freq*122)/16 - 20;
467 buffer[2] = 0x88; /* could be also 0x80 */
468 buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
469 break;
427 case TUNER_PHILIPS_FM1216ME_MK3: 470 case TUNER_PHILIPS_FM1216ME_MK3:
428 case TUNER_PHILIPS_FM1236_MK3: 471 case TUNER_PHILIPS_FM1236_MK3:
429 buffer[3] = 0x19; 472 buffer[3] = 0x19;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 41b635e0d3c6..9a493bea76d8 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -285,7 +285,6 @@ static int chip_thread(void *data)
285 schedule(); 285 schedule();
286 } 286 }
287 remove_wait_queue(&chip->wq, &wait); 287 remove_wait_queue(&chip->wq, &wait);
288 try_to_freeze(PF_FREEZE);
289 if (chip->done || signal_pending(current)) 288 if (chip->done || signal_pending(current))
290 break; 289 break;
291 dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c)); 290 dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
@@ -1237,17 +1236,17 @@ static int ta8874z_checkit(struct CHIPSTATE *chip)
1237/* audio chip descriptions - struct CHIPDESC */ 1236/* audio chip descriptions - struct CHIPDESC */
1238 1237
1239/* insmod options to enable/disable individual audio chips */ 1238/* insmod options to enable/disable individual audio chips */
1240int tda8425 = 1; 1239static int tda8425 = 1;
1241int tda9840 = 1; 1240static int tda9840 = 1;
1242int tda9850 = 1; 1241static int tda9850 = 1;
1243int tda9855 = 1; 1242static int tda9855 = 1;
1244int tda9873 = 1; 1243static int tda9873 = 1;
1245int tda9874a = 1; 1244static int tda9874a = 1;
1246int tea6300 = 0; // address clash with msp34xx 1245static int tea6300 = 0; // address clash with msp34xx
1247int tea6320 = 0; // address clash with msp34xx 1246static int tea6320 = 0; // address clash with msp34xx
1248int tea6420 = 1; 1247static int tea6420 = 1;
1249int pic16c54 = 1; 1248static int pic16c54 = 1;
1250int ta8874z = 0; // address clash with tda9840 1249static int ta8874z = 0; // address clash with tda9840
1251 1250
1252module_param(tda8425, int, 0444); 1251module_param(tda8425, int, 0444);
1253module_param(tda9840, int, 0444); 1252module_param(tda9840, int, 0444);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3d216973798c..0f03c25489f1 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -75,7 +75,7 @@ hauppauge_tuner_fmt[] =
75 { 0x00000007, "PAL(B/G)" }, 75 { 0x00000007, "PAL(B/G)" },
76 { 0x00001000, "NTSC(M)" }, 76 { 0x00001000, "NTSC(M)" },
77 { 0x00000010, "PAL(I)" }, 77 { 0x00000010, "PAL(I)" },
78 { 0x00400000, "SECAM(L/L�)" }, 78 { 0x00400000, "SECAM(L/L´)" },
79 { 0x00000e00, "PAL(D/K)" }, 79 { 0x00000e00, "PAL(D/K)" },
80 { 0x03000000, "ATSC Digital" }, 80 { 0x03000000, "ATSC Digital" },
81}; 81};
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index eafd7061b310..51b99cdbf29e 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -1,3 +1,7 @@
1/*
2 * $Id: tvmixer.c,v 1.8 2005/06/12 04:19:19 mchehab Exp $
3 */
4
1#include <linux/module.h> 5#include <linux/module.h>
2#include <linux/moduleparam.h> 6#include <linux/moduleparam.h>
3#include <linux/kernel.h> 7#include <linux/kernel.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index b0d4bcb027d0..70ecbdb80277 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -1,4 +1,6 @@
1/* 1/*
2 * $Id: v4l1-compat.c,v 1.9 2005/06/12 04:19:19 mchehab Exp $
3 *
2 * Video for Linux Two 4 * Video for Linux Two
3 * Backward Compatibility Layer 5 * Backward Compatibility Layer
4 * 6 *
@@ -15,14 +17,11 @@
15 * 17 *
16 */ 18 */
17 19
18#ifndef __KERNEL__
19#define __KERNEL__
20#endif
21
22#include <linux/config.h> 20#include <linux/config.h>
23 21
24#include <linux/init.h> 22#include <linux/init.h>
25#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/moduleparam.h>
26#include <linux/types.h> 25#include <linux/types.h>
27#include <linux/kernel.h> 26#include <linux/kernel.h>
28#include <linux/sched.h> 27#include <linux/sched.h>
@@ -787,12 +786,15 @@ v4l_compat_translate_ioctl(struct inode *inode,
787 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) 786 !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
788 aud->step = qctrl2.step; 787 aud->step = qctrl2.step;
789 aud->mode = 0; 788 aud->mode = 0;
789
790 memset(&tun2,0,sizeof(tun2));
790 err = drv(inode, file, VIDIOC_G_TUNER, &tun2); 791 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
791 if (err < 0) { 792 if (err < 0) {
792 dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err); 793 dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
793 err = 0; 794 err = 0;
794 break; 795 break;
795 } 796 }
797
796 if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2) 798 if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
797 aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 799 aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
798 else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) 800 else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
index 8d132b0d6b12..06e8eb19a05c 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/message/i2o/Kconfig
@@ -24,10 +24,28 @@ config I2O
24 24
25 If unsure, say N. 25 If unsure, say N.
26 26
27config I2O_EXT_ADAPTEC
28 bool "Enable Adaptec extensions"
29 depends on I2O
30 default y
31 ---help---
32 Say Y for support of raidutils for Adaptec I2O controllers. You also
33 have to say Y to "I2O Configuration support", "I2O SCSI OSM" below
34 and to "SCSI generic support" under "SCSI device configuration".
35
36config I2O_EXT_ADAPTEC_DMA64
37 bool "Enable 64-bit DMA"
38 depends on I2O_EXT_ADAPTEC && ( 64BIT || HIGHMEM64G )
39 default y
40 ---help---
41 Say Y for support of 64-bit DMA transfer mode on Adaptec I2O
42 controllers.
43 Note: You need at least firmware version 3709.
44
27config I2O_CONFIG 45config I2O_CONFIG
28 tristate "I2O Configuration support" 46 tristate "I2O Configuration support"
29 depends on PCI && I2O 47 depends on I2O
30 help 48 ---help---
31 Say Y for support of the configuration interface for the I2O adapters. 49 Say Y for support of the configuration interface for the I2O adapters.
32 If you have a RAID controller from Adaptec and you want to use the 50 If you have a RAID controller from Adaptec and you want to use the
33 raidutils to manage your RAID array, you have to say Y here. 51 raidutils to manage your RAID array, you have to say Y here.
@@ -35,10 +53,28 @@ config I2O_CONFIG
35 To compile this support as a module, choose M here: the 53 To compile this support as a module, choose M here: the
36 module will be called i2o_config. 54 module will be called i2o_config.
37 55
56config I2O_CONFIG_OLD_IOCTL
57 bool "Enable ioctls (OBSOLETE)"
58 depends on I2O_CONFIG
59 default y
60 ---help---
61 Enables old ioctls.
62
63config I2O_BUS
64 tristate "I2O Bus Adapter OSM"
65 depends on I2O
66 ---help---
67 Include support for the I2O Bus Adapter OSM. The Bus Adapter OSM
68 provides access to the busses on the I2O controller. The main purpose
69 is to rescan the bus to find new devices.
70
71 To compile this support as a module, choose M here: the
72 module will be called i2o_bus.
73
38config I2O_BLOCK 74config I2O_BLOCK
39 tristate "I2O Block OSM" 75 tristate "I2O Block OSM"
40 depends on I2O 76 depends on I2O
41 help 77 ---help---
42 Include support for the I2O Block OSM. The Block OSM presents disk 78 Include support for the I2O Block OSM. The Block OSM presents disk
43 and other structured block devices to the operating system. If you 79 and other structured block devices to the operating system. If you
44 are using an RAID controller, you could access the array only by 80 are using an RAID controller, you could access the array only by
@@ -51,7 +87,7 @@ config I2O_BLOCK
51config I2O_SCSI 87config I2O_SCSI
52 tristate "I2O SCSI OSM" 88 tristate "I2O SCSI OSM"
53 depends on I2O && SCSI 89 depends on I2O && SCSI
54 help 90 ---help---
55 Allows direct SCSI access to SCSI devices on a SCSI or FibreChannel 91 Allows direct SCSI access to SCSI devices on a SCSI or FibreChannel
56 I2O controller. You can use both the SCSI and Block OSM together if 92 I2O controller. You can use both the SCSI and Block OSM together if
57 you wish. To access a RAID array, you must use the Block OSM driver. 93 you wish. To access a RAID array, you must use the Block OSM driver.
@@ -63,7 +99,7 @@ config I2O_SCSI
63config I2O_PROC 99config I2O_PROC
64 tristate "I2O /proc support" 100 tristate "I2O /proc support"
65 depends on I2O 101 depends on I2O
66 help 102 ---help---
67 If you say Y here and to "/proc file system support", you will be 103 If you say Y here and to "/proc file system support", you will be
68 able to read I2O related information from the virtual directory 104 able to read I2O related information from the virtual directory
69 /proc/i2o. 105 /proc/i2o.
diff --git a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
index aabc6cdc3fce..2c2e39aa1efa 100644
--- a/drivers/message/i2o/Makefile
+++ b/drivers/message/i2o/Makefile
@@ -6,8 +6,11 @@
6# 6#
7 7
8i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o 8i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o
9i2o_bus-y += bus-osm.o
10i2o_config-y += config-osm.o
9obj-$(CONFIG_I2O) += i2o_core.o 11obj-$(CONFIG_I2O) += i2o_core.o
10obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o 12obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o
13obj-$(CONFIG_I2O_BUS) += i2o_bus.o
11obj-$(CONFIG_I2O_BLOCK) += i2o_block.o 14obj-$(CONFIG_I2O_BLOCK) += i2o_block.o
12obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o 15obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o
13obj-$(CONFIG_I2O_PROC) += i2o_proc.o 16obj-$(CONFIG_I2O_PROC) += i2o_proc.o
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c
new file mode 100644
index 000000000000..151b228e1cb3
--- /dev/null
+++ b/drivers/message/i2o/bus-osm.c
@@ -0,0 +1,164 @@
1/*
2 * Bus Adapter OSM
3 *
4 * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Fixes/additions:
12 * Markus Lidel <Markus.Lidel@shadowconnect.com>
13 * initial version.
14 */
15
16#include <linux/module.h>
17#include <linux/i2o.h>
18
19#define OSM_NAME "bus-osm"
20#define OSM_VERSION "$Rev$"
21#define OSM_DESCRIPTION "I2O Bus Adapter OSM"
22
23static struct i2o_driver i2o_bus_driver;
24
25/* Bus OSM class handling definition */
26static struct i2o_class_id i2o_bus_class_id[] = {
27 {I2O_CLASS_BUS_ADAPTER},
28 {I2O_CLASS_END}
29};
30
31/**
32 * i2o_bus_scan - Scan the bus for new devices
33 * @dev: I2O device of the bus, which should be scanned
34 *
35 * Scans the bus dev for new / removed devices. After the scan a new LCT
36 * will be fetched automatically.
37 *
38 * Returns 0 on success or negative error code on failure.
39 */
40static int i2o_bus_scan(struct i2o_device *dev)
41{
42 struct i2o_message __iomem *msg;
43 u32 m;
44
45 m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
46 if (m == I2O_QUEUE_EMPTY)
47 return -ETIMEDOUT;
48
49 writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
50 writel(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.tid,
51 &msg->u.head[1]);
52
53 return i2o_msg_post_wait(dev->iop, m, 60);
54};
55
56/**
57 * i2o_bus_store_scan - Scan the I2O Bus Adapter
58 * @d: device which should be scanned
59 *
60 * Returns count.
61 */
62static ssize_t i2o_bus_store_scan(struct device *d, struct device_attribute *attr, const char *buf,
63 size_t count)
64{
65 struct i2o_device *i2o_dev = to_i2o_device(d);
66 int rc;
67
68 if ((rc = i2o_bus_scan(i2o_dev)))
69 osm_warn("bus scan failed %d\n", rc);
70
71 return count;
72}
73
74/* Bus Adapter OSM device attributes */
75static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan);
76
77/**
78 * i2o_bus_probe - verify if dev is a I2O Bus Adapter device and install it
79 * @dev: device to verify if it is a I2O Bus Adapter device
80 *
81 * Because we want all Bus Adapters always return 0.
82 *
83 * Returns 0.
84 */
85static int i2o_bus_probe(struct device *dev)
86{
87 struct i2o_device *i2o_dev = to_i2o_device(get_device(dev));
88
89 device_create_file(dev, &dev_attr_scan);
90
91 osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid);
92
93 return 0;
94};
95
96/**
97 * i2o_bus_remove - remove the I2O Bus Adapter device from the system again
98 * @dev: I2O Bus Adapter device which should be removed
99 *
100 * Always returns 0.
101 */
102static int i2o_bus_remove(struct device *dev)
103{
104 struct i2o_device *i2o_dev = to_i2o_device(dev);
105
106 device_remove_file(dev, &dev_attr_scan);
107
108 put_device(dev);
109
110 osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
111
112 return 0;
113};
114
115/* Bus Adapter OSM driver struct */
116static struct i2o_driver i2o_bus_driver = {
117 .name = OSM_NAME,
118 .classes = i2o_bus_class_id,
119 .driver = {
120 .probe = i2o_bus_probe,
121 .remove = i2o_bus_remove,
122 },
123};
124
125/**
126 * i2o_bus_init - Bus Adapter OSM initialization function
127 *
128 * Only register the Bus Adapter OSM in the I2O core.
129 *
130 * Returns 0 on success or negative error code on failure.
131 */
132static int __init i2o_bus_init(void)
133{
134 int rc;
135
136 printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
137
138 /* Register Bus Adapter OSM into I2O core */
139 rc = i2o_driver_register(&i2o_bus_driver);
140 if (rc) {
141 osm_err("Could not register Bus Adapter OSM\n");
142 return rc;
143 }
144
145 return 0;
146};
147
148/**
149 * i2o_bus_exit - Bus Adapter OSM exit function
150 *
151 * Unregisters Bus Adapter OSM from I2O core.
152 */
153static void __exit i2o_bus_exit(void)
154{
155 i2o_driver_unregister(&i2o_bus_driver);
156};
157
158MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
159MODULE_LICENSE("GPL");
160MODULE_DESCRIPTION(OSM_DESCRIPTION);
161MODULE_VERSION(OSM_VERSION);
162
163module_init(i2o_bus_init);
164module_exit(i2o_bus_exit);
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
new file mode 100644
index 000000000000..d0267609a949
--- /dev/null
+++ b/drivers/message/i2o/config-osm.c
@@ -0,0 +1,579 @@
1/*
2 * Configuration OSM
3 *
4 * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Fixes/additions:
12 * Markus Lidel <Markus.Lidel@shadowconnect.com>
13 * initial version.
14 */
15
16#include <linux/module.h>
17#include <linux/i2o.h>
18#include <linux/namei.h>
19
20#include <asm/uaccess.h>
21
22#define OSM_NAME "config-osm"
23#define OSM_VERSION "1.248"
24#define OSM_DESCRIPTION "I2O Configuration OSM"
25
26/* access mode user rw */
27#define S_IWRSR (S_IRUSR | S_IWUSR)
28
29static struct i2o_driver i2o_config_driver;
30
31/* Special file operations for sysfs */
32struct fops_attribute {
33 struct bin_attribute bin;
34 struct file_operations fops;
35};
36
37/**
38 * sysfs_read_dummy
39 */
40static ssize_t sysfs_read_dummy(struct kobject *kobj, char *buf, loff_t offset,
41 size_t count)
42{
43 return 0;
44};
45
46/**
47 * sysfs_write_dummy
48 */
49static ssize_t sysfs_write_dummy(struct kobject *kobj, char *buf, loff_t offset,
50 size_t count)
51{
52 return 0;
53};
54
55/**
56 * sysfs_create_fops_file - Creates attribute with special file operations
57 * @kobj: kobject which should contains the attribute
58 * @attr: attributes which should be used to create file
59 *
60 * First creates attribute @attr in kobject @kobj. If it is the first time
61 * this function is called, merge old fops from sysfs with new one and
62 * write it back. Afterwords the new fops will be set for the created
63 * attribute.
64 *
65 * Returns 0 on success or negative error code on failure.
66 */
67static int sysfs_create_fops_file(struct kobject *kobj,
68 struct fops_attribute *attr)
69{
70 struct file_operations tmp, *fops;
71 struct dentry *d;
72 struct qstr qstr;
73 int rc;
74
75 fops = &attr->fops;
76
77 if (fops->read)
78 attr->bin.read = sysfs_read_dummy;
79
80 if (fops->write)
81 attr->bin.write = sysfs_write_dummy;
82
83 if ((rc = sysfs_create_bin_file(kobj, &attr->bin)))
84 return rc;
85
86 qstr.name = attr->bin.attr.name;
87 qstr.len = strlen(qstr.name);
88 qstr.hash = full_name_hash(qstr.name, qstr.len);
89
90 if ((d = lookup_hash(&qstr, kobj->dentry))) {
91 if (!fops->owner) {
92 memcpy(&tmp, d->d_inode->i_fop, sizeof(tmp));
93 if (fops->read)
94 tmp.read = fops->read;
95 if (fops->write)
96 tmp.write = fops->write;
97 memcpy(fops, &tmp, sizeof(tmp));
98 }
99
100 d->d_inode->i_fop = fops;
101 } else
102 sysfs_remove_bin_file(kobj, &attr->bin);
103
104 return -ENOENT;
105};
106
107/**
108 * sysfs_remove_fops_file - Remove attribute with special file operations
109 * @kobj: kobject which contains the attribute
110 * @attr: attributes which are used to create file
111 *
112 * Only wrapper arround sysfs_remove_bin_file()
113 *
114 * Returns 0 on success or negative error code on failure.
115 */
116static inline int sysfs_remove_fops_file(struct kobject *kobj,
117 struct fops_attribute *attr)
118{
119 return sysfs_remove_bin_file(kobj, &attr->bin);
120};
121
122/**
123 * i2o_config_read_hrt - Returns the HRT of the controller
124 * @kob: kernel object handle
125 * @buf: buffer into which the HRT should be copied
126 * @off: file offset
127 * @count: number of bytes to read
128 *
129 * Put @count bytes starting at @off into @buf from the HRT of the I2O
130 * controller corresponding to @kobj.
131 *
132 * Returns number of bytes copied into buffer.
133 */
134static ssize_t i2o_config_read_hrt(struct kobject *kobj, char *buf,
135 loff_t offset, size_t count)
136{
137 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
138 i2o_hrt *hrt = c->hrt.virt;
139
140 u32 size = (hrt->num_entries * hrt->entry_len + 2) * 4;
141
142 if (offset > size)
143 return 0;
144
145 if (offset + count > size)
146 count = size - offset;
147
148 memcpy(buf, (u8 *) hrt + offset, count);
149
150 return count;
151};
152
153/**
154 * i2o_config_read_lct - Returns the LCT of the controller
155 * @kob: kernel object handle
156 * @buf: buffer into which the LCT should be copied
157 * @off: file offset
158 * @count: number of bytes to read
159 *
160 * Put @count bytes starting at @off into @buf from the LCT of the I2O
161 * controller corresponding to @kobj.
162 *
163 * Returns number of bytes copied into buffer.
164 */
165static ssize_t i2o_config_read_lct(struct kobject *kobj, char *buf,
166 loff_t offset, size_t count)
167{
168 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
169 u32 size = c->lct->table_size * 4;
170
171 if (offset > size)
172 return 0;
173
174 if (offset + count > size)
175 count = size - offset;
176
177 memcpy(buf, (u8 *) c->lct + offset, count);
178
179 return count;
180};
181
182#define I2O_CONFIG_SW_ATTR(_name,_mode,_type,_swid) \
183static ssize_t i2o_config_##_name##_read(struct file *file, char __user *buf, size_t count, loff_t * offset) { \
184 return i2o_config_sw_read(file, buf, count, offset, _type, _swid); \
185};\
186\
187static ssize_t i2o_config_##_name##_write(struct file *file, const char __user *buf, size_t count, loff_t * offset) { \
188 return i2o_config_sw_write(file, buf, count, offset, _type, _swid); \
189}; \
190\
191static struct fops_attribute i2o_config_attr_##_name = { \
192 .bin = { .attr = { .name = __stringify(_name), .mode = _mode, \
193 .owner = THIS_MODULE }, \
194 .size = 0, }, \
195 .fops = { .write = i2o_config_##_name##_write, \
196 .read = i2o_config_##_name##_read} \
197};
198
199#ifdef CONFIG_I2O_EXT_ADAPTEC
200
201/**
202 * i2o_config_dpt_reagion - Converts type and id to flash region
203 * @swtype: type of software module reading
204 * @swid: id of software which should be read
205 *
206 * Converts type and id from I2O spec to the matching region for DPT /
207 * Adaptec controllers.
208 *
209 * Returns region which match type and id or -1 on error.
210 */
211static u32 i2o_config_dpt_region(u8 swtype, u8 swid)
212{
213 switch (swtype) {
214 case I2O_SOFTWARE_MODULE_IRTOS:
215 /*
216 * content: operation firmware
217 * region size:
218 * 0xbc000 for 2554, 3754, 2564, 3757
219 * 0x170000 for 2865
220 * 0x17c000 for 3966
221 */
222 if (!swid)
223 return 0;
224
225 break;
226
227 case I2O_SOFTWARE_MODULE_IOP_PRIVATE:
228 /*
229 * content: BIOS and SMOR
230 * BIOS size: first 0x8000 bytes
231 * region size:
232 * 0x40000 for 2554, 3754, 2564, 3757
233 * 0x80000 for 2865, 3966
234 */
235 if (!swid)
236 return 1;
237
238 break;
239
240 case I2O_SOFTWARE_MODULE_IOP_CONFIG:
241 switch (swid) {
242 case 0:
243 /*
244 * content: NVRAM defaults
245 * region size: 0x2000 bytes
246 */
247 return 2;
248 case 1:
249 /*
250 * content: serial number
251 * region size: 0x2000 bytes
252 */
253 return 3;
254 }
255 break;
256 }
257
258 return -1;
259};
260
261#endif
262
263/**
264 * i2o_config_sw_read - Read a software module from controller
265 * @file: file pointer
266 * @buf: buffer into which the data should be copied
267 * @count: number of bytes to read
268 * @off: file offset
269 * @swtype: type of software module reading
270 * @swid: id of software which should be read
271 *
272 * Transfers @count bytes at offset @offset from IOP into buffer using
273 * type @swtype and id @swid as described in I2O spec.
274 *
275 * Returns number of bytes copied into buffer or error code on failure.
276 */
277static ssize_t i2o_config_sw_read(struct file *file, char __user * buf,
278 size_t count, loff_t * offset, u8 swtype,
279 u32 swid)
280{
281 struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata;
282 struct kobject *kobj = sd->s_element;
283 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
284 u32 m, function = I2O_CMD_SW_UPLOAD;
285 struct i2o_dma buffer;
286 struct i2o_message __iomem *msg;
287 u32 __iomem *mptr;
288 int rc, status;
289
290 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
291 if (m == I2O_QUEUE_EMPTY)
292 return -EBUSY;
293
294 mptr = &msg->body[3];
295
296 if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL))) {
297 i2o_msg_nop(c, m);
298 return rc;
299 }
300#ifdef CONFIG_I2O_EXT_ADAPTEC
301 if (c->adaptec) {
302 mptr = &msg->body[4];
303 function = I2O_CMD_PRIVATE;
304
305 writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]);
306
307 writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_READ,
308 &msg->body[0]);
309 writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]);
310 writel(*offset, &msg->body[2]);
311 writel(count, &msg->body[3]);
312 } else
313#endif
314 writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
315
316 writel(0xD0000000 | count, mptr++);
317 writel(buffer.phys, mptr);
318
319 writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]);
320 writel(i2o_config_driver.context, &msg->u.head[2]);
321 writel(0, &msg->u.head[3]);
322
323#ifdef CONFIG_I2O_EXT_ADAPTEC
324 if (!c->adaptec)
325#endif
326 {
327 writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]);
328 writel(0, &msg->body[1]);
329 writel(swid, &msg->body[2]);
330 }
331
332 status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
333
334 if (status == I2O_POST_WAIT_OK) {
335 if (!(rc = copy_to_user(buf, buffer.virt, count))) {
336 rc = count;
337 *offset += count;
338 }
339 } else
340 rc = -EIO;
341
342 if (status != -ETIMEDOUT)
343 i2o_dma_free(&c->pdev->dev, &buffer);
344
345 return rc;
346};
347
348/**
349 * i2o_config_sw_write - Write a software module to controller
350 * @file: file pointer
351 * @buf: buffer into which the data should be copied
352 * @count: number of bytes to read
353 * @off: file offset
354 * @swtype: type of software module writing
355 * @swid: id of software which should be written
356 *
357 * Transfers @count bytes at offset @offset from buffer to IOP using
358 * type @swtype and id @swid as described in I2O spec.
359 *
360 * Returns number of bytes copied from buffer or error code on failure.
361 */
362static ssize_t i2o_config_sw_write(struct file *file, const char __user * buf,
363 size_t count, loff_t * offset, u8 swtype,
364 u32 swid)
365{
366 struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata;
367 struct kobject *kobj = sd->s_element;
368 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
369 u32 m, function = I2O_CMD_SW_DOWNLOAD;
370 struct i2o_dma buffer;
371 struct i2o_message __iomem *msg;
372 u32 __iomem *mptr;
373 int rc, status;
374
375 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
376 if (m == I2O_QUEUE_EMPTY)
377 return -EBUSY;
378
379 mptr = &msg->body[3];
380
381 if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL)))
382 goto nop_msg;
383
384 if ((rc = copy_from_user(buffer.virt, buf, count)))
385 goto free_buffer;
386
387#ifdef CONFIG_I2O_EXT_ADAPTEC
388 if (c->adaptec) {
389 mptr = &msg->body[4];
390 function = I2O_CMD_PRIVATE;
391
392 writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]);
393
394 writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_WRITE,
395 &msg->body[0]);
396 writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]);
397 writel(*offset, &msg->body[2]);
398 writel(count, &msg->body[3]);
399 } else
400#endif
401 writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
402
403 writel(0xD4000000 | count, mptr++);
404 writel(buffer.phys, mptr);
405
406 writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]);
407 writel(i2o_config_driver.context, &msg->u.head[2]);
408 writel(0, &msg->u.head[3]);
409
410#ifdef CONFIG_I2O_EXT_ADAPTEC
411 if (!c->adaptec)
412#endif
413 {
414 writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]);
415 writel(0, &msg->body[1]);
416 writel(swid, &msg->body[2]);
417 }
418
419 status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
420
421 if (status != -ETIMEDOUT)
422 i2o_dma_free(&c->pdev->dev, &buffer);
423
424 if (status != I2O_POST_WAIT_OK)
425 return -EIO;
426
427 *offset += count;
428
429 return count;
430
431 free_buffer:
432 i2o_dma_free(&c->pdev->dev, &buffer);
433
434 nop_msg:
435 i2o_msg_nop(c, m);
436
437 return rc;
438};
439
440/* attribute for HRT in sysfs */
441static struct bin_attribute i2o_config_hrt_attr = {
442 .attr = {
443 .name = "hrt",
444 .mode = S_IRUGO,
445 .owner = THIS_MODULE},
446 .size = 0,
447 .read = i2o_config_read_hrt
448};
449
450/* attribute for LCT in sysfs */
451static struct bin_attribute i2o_config_lct_attr = {
452 .attr = {
453 .name = "lct",
454 .mode = S_IRUGO,
455 .owner = THIS_MODULE},
456 .size = 0,
457 .read = i2o_config_read_lct
458};
459
460/* IRTOS firmware access */
461I2O_CONFIG_SW_ATTR(irtos, S_IWRSR, I2O_SOFTWARE_MODULE_IRTOS, 0);
462
463#ifdef CONFIG_I2O_EXT_ADAPTEC
464
465/*
466 * attribute for BIOS / SMOR, nvram and serial number access on DPT / Adaptec
467 * controllers
468 */
469I2O_CONFIG_SW_ATTR(bios, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_PRIVATE, 0);
470I2O_CONFIG_SW_ATTR(nvram, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 0);
471I2O_CONFIG_SW_ATTR(serial, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 1);
472
473#endif
474
475/**
476 * i2o_config_notify_controller_add - Notify of added controller
477 * @c: the controller which was added
478 *
479 * If a I2O controller is added, we catch the notification to add sysfs
480 * entries.
481 */
482static void i2o_config_notify_controller_add(struct i2o_controller *c)
483{
484 struct kobject *kobj = &c->exec->device.kobj;
485
486 sysfs_create_bin_file(kobj, &i2o_config_hrt_attr);
487 sysfs_create_bin_file(kobj, &i2o_config_lct_attr);
488
489 sysfs_create_fops_file(kobj, &i2o_config_attr_irtos);
490#ifdef CONFIG_I2O_EXT_ADAPTEC
491 if (c->adaptec) {
492 sysfs_create_fops_file(kobj, &i2o_config_attr_bios);
493 sysfs_create_fops_file(kobj, &i2o_config_attr_nvram);
494 sysfs_create_fops_file(kobj, &i2o_config_attr_serial);
495 }
496#endif
497};
498
499/**
500 * i2o_config_notify_controller_remove - Notify of removed controller
501 * @c: the controller which was removed
502 *
503 * If a I2O controller is removed, we catch the notification to remove the
504 * sysfs entries.
505 */
506static void i2o_config_notify_controller_remove(struct i2o_controller *c)
507{
508 struct kobject *kobj = &c->exec->device.kobj;
509
510#ifdef CONFIG_I2O_EXT_ADAPTEC
511 if (c->adaptec) {
512 sysfs_remove_fops_file(kobj, &i2o_config_attr_serial);
513 sysfs_remove_fops_file(kobj, &i2o_config_attr_nvram);
514 sysfs_remove_fops_file(kobj, &i2o_config_attr_bios);
515 }
516#endif
517 sysfs_remove_fops_file(kobj, &i2o_config_attr_irtos);
518
519 sysfs_remove_bin_file(kobj, &i2o_config_lct_attr);
520 sysfs_remove_bin_file(kobj, &i2o_config_hrt_attr);
521};
522
523/* Config OSM driver struct */
524static struct i2o_driver i2o_config_driver = {
525 .name = OSM_NAME,
526 .notify_controller_add = i2o_config_notify_controller_add,
527 .notify_controller_remove = i2o_config_notify_controller_remove
528};
529
530#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
531#include "i2o_config.c"
532#endif
533
534/**
535 * i2o_config_init - Configuration OSM initialization function
536 *
537 * Registers Configuration OSM in the I2O core and if old ioctl's are
538 * compiled in initialize them.
539 *
540 * Returns 0 on success or negative error code on failure.
541 */
542static int __init i2o_config_init(void)
543{
544 printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
545
546 if (i2o_driver_register(&i2o_config_driver)) {
547 osm_err("handler register failed.\n");
548 return -EBUSY;
549 }
550#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
551 if (i2o_config_old_init())
552 i2o_driver_unregister(&i2o_config_driver);
553#endif
554
555 return 0;
556}
557
558/**
559 * i2o_config_exit - Configuration OSM exit function
560 *
561 * If old ioctl's are compiled in exit remove them and unregisters
562 * Configuration OSM from I2O core.
563 */
564static void i2o_config_exit(void)
565{
566#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
567 i2o_config_old_exit();
568#endif
569
570 i2o_driver_unregister(&i2o_config_driver);
571}
572
573MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
574MODULE_LICENSE("GPL");
575MODULE_DESCRIPTION(OSM_DESCRIPTION);
576MODULE_VERSION(OSM_VERSION);
577
578module_init(i2o_config_init);
579module_exit(i2o_config_exit);
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
new file mode 100644
index 000000000000..c5bcfd70f711
--- /dev/null
+++ b/drivers/message/i2o/core.h
@@ -0,0 +1,58 @@
1/*
2 * I2O core internal declarations
3 *
4 * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * Fixes/additions:
12 * Markus Lidel <Markus.Lidel@shadowconnect.com>
13 * initial version.
14 */
15
16/* Exec-OSM */
17extern struct bus_type i2o_bus_type;
18
19extern struct i2o_driver i2o_exec_driver;
20extern int i2o_exec_lct_get(struct i2o_controller *);
21
22extern int __init i2o_exec_init(void);
23extern void __exit i2o_exec_exit(void);
24
25/* driver */
26extern int i2o_driver_dispatch(struct i2o_controller *, u32);
27
28extern int __init i2o_driver_init(void);
29extern void __exit i2o_driver_exit(void);
30
31/* PCI */
32extern int __init i2o_pci_init(void);
33extern void __exit i2o_pci_exit(void);
34
35/* device */
36extern void i2o_device_remove(struct i2o_device *);
37extern int i2o_device_parse_lct(struct i2o_controller *);
38
39extern int i2o_device_init(void);
40extern void i2o_device_exit(void);
41
42/* IOP */
43extern struct i2o_controller *i2o_iop_alloc(void);
44extern void i2o_iop_free(struct i2o_controller *);
45
46extern int i2o_iop_add(struct i2o_controller *);
47extern void i2o_iop_remove(struct i2o_controller *);
48
49/* config */
50extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
51
52/* control registers relative to c->base */
53#define I2O_IRQ_STATUS 0x30
54#define I2O_IRQ_MASK 0x34
55#define I2O_IN_PORT 0x40
56#define I2O_OUT_PORT 0x44
57
58#define I2O_IRQ_OUTBOUND_POST 0x00000008
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
index 2a5d478fc60e..018ca887ca85 100644
--- a/drivers/message/i2o/debug.c
+++ b/drivers/message/i2o/debug.c
@@ -4,8 +4,6 @@
4#include <linux/pci.h> 4#include <linux/pci.h>
5#include <linux/i2o.h> 5#include <linux/i2o.h>
6 6
7extern struct i2o_driver **i2o_drivers;
8extern unsigned int i2o_max_drivers;
9static void i2o_report_util_cmd(u8 cmd); 7static void i2o_report_util_cmd(u8 cmd);
10static void i2o_report_exec_cmd(u8 cmd); 8static void i2o_report_exec_cmd(u8 cmd);
11static void i2o_report_fail_status(u8 req_status, u32 * msg); 9static void i2o_report_fail_status(u8 req_status, u32 * msg);
@@ -23,7 +21,6 @@ void i2o_report_status(const char *severity, const char *str,
23 u8 cmd = (msg[1] >> 24) & 0xFF; 21 u8 cmd = (msg[1] >> 24) & 0xFF;
24 u8 req_status = (msg[4] >> 24) & 0xFF; 22 u8 req_status = (msg[4] >> 24) & 0xFF;
25 u16 detailed_status = msg[4] & 0xFFFF; 23 u16 detailed_status = msg[4] & 0xFFFF;
26 //struct i2o_driver *h = i2o_drivers[msg[2] & (i2o_max_drivers-1)];
27 24
28 if (cmd == I2O_CMD_UTIL_EVT_REGISTER) 25 if (cmd == I2O_CMD_UTIL_EVT_REGISTER)
29 return; // No status in this reply 26 return; // No status in this reply
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index eb907e87bc7b..21f16ba3ac38 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -16,9 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/i2o.h> 17#include <linux/i2o.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19 19#include "core.h"
20/* Exec OSM functions */
21extern struct bus_type i2o_bus_type;
22 20
23/** 21/**
24 * i2o_device_issue_claim - claim or release a device 22 * i2o_device_issue_claim - claim or release a device
@@ -282,8 +280,7 @@ int i2o_device_parse_lct(struct i2o_controller *c)
282 280
283 down(&c->lct_lock); 281 down(&c->lct_lock);
284 282
285 if (c->lct) 283 kfree(c->lct);
286 kfree(c->lct);
287 284
288 lct = c->dlct.virt; 285 lct = c->dlct.virt;
289 286
@@ -294,12 +291,12 @@ int i2o_device_parse_lct(struct i2o_controller *c)
294 } 291 }
295 292
296 if (lct->table_size * 4 > c->dlct.len) { 293 if (lct->table_size * 4 > c->dlct.len) {
297 memcpy_fromio(c->lct, c->dlct.virt, c->dlct.len); 294 memcpy(c->lct, c->dlct.virt, c->dlct.len);
298 up(&c->lct_lock); 295 up(&c->lct_lock);
299 return -EAGAIN; 296 return -EAGAIN;
300 } 297 }
301 298
302 memcpy_fromio(c->lct, c->dlct.virt, lct->table_size * 4); 299 memcpy(c->lct, c->dlct.virt, lct->table_size * 4);
303 300
304 lct = c->lct; 301 lct = c->lct;
305 302
@@ -354,7 +351,7 @@ static ssize_t i2o_device_class_show_class_id(struct class_device *cd,
354{ 351{
355 struct i2o_device *dev = to_i2o_device(cd->dev); 352 struct i2o_device *dev = to_i2o_device(cd->dev);
356 353
357 sprintf(buf, "%03x\n", dev->lct_data.class_id); 354 sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
358 return strlen(buf) + 1; 355 return strlen(buf) + 1;
359}; 356};
360 357
@@ -369,7 +366,7 @@ static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf)
369{ 366{
370 struct i2o_device *dev = to_i2o_device(cd->dev); 367 struct i2o_device *dev = to_i2o_device(cd->dev);
371 368
372 sprintf(buf, "%03x\n", dev->lct_data.tid); 369 sprintf(buf, "0x%03x\n", dev->lct_data.tid);
373 return strlen(buf) + 1; 370 return strlen(buf) + 1;
374}; 371};
375 372
@@ -401,25 +398,27 @@ static int i2o_device_class_add(struct class_device *cd)
401 398
402 /* create user entries for this device */ 399 /* create user entries for this device */
403 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid); 400 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
404 if (tmp) 401 if (tmp && (tmp != i2o_dev))
405 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, 402 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
406 "user"); 403 "user");
407 404
408 /* create user entries refering to this device */ 405 /* create user entries refering to this device */
409 list_for_each_entry(tmp, &c->devices, list) 406 list_for_each_entry(tmp, &c->devices, list)
410 if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid) 407 if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
408 && (tmp != i2o_dev))
411 sysfs_create_link(&tmp->device.kobj, 409 sysfs_create_link(&tmp->device.kobj,
412 &i2o_dev->device.kobj, "user"); 410 &i2o_dev->device.kobj, "user");
413 411
414 /* create parent entries for this device */ 412 /* create parent entries for this device */
415 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid); 413 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
416 if (tmp) 414 if (tmp && (tmp != i2o_dev))
417 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, 415 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
418 "parent"); 416 "parent");
419 417
420 /* create parent entries refering to this device */ 418 /* create parent entries refering to this device */
421 list_for_each_entry(tmp, &c->devices, list) 419 list_for_each_entry(tmp, &c->devices, list)
422 if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) 420 if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
421 && (tmp != i2o_dev))
423 sysfs_create_link(&tmp->device.kobj, 422 sysfs_create_link(&tmp->device.kobj,
424 &i2o_dev->device.kobj, "parent"); 423 &i2o_dev->device.kobj, "parent");
425 424
@@ -444,9 +443,8 @@ static struct class_interface i2o_device_class_interface = {
444 * Note that the minimum sized reslist is 8 bytes and contains 443 * Note that the minimum sized reslist is 8 bytes and contains
445 * ResultCount, ErrorInfoSize, BlockStatus and BlockSize. 444 * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
446 */ 445 */
447
448int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist, 446int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
449 int oplen, void *reslist, int reslen) 447 int oplen, void *reslist, int reslen)
450{ 448{
451 struct i2o_message __iomem *msg; 449 struct i2o_message __iomem *msg;
452 u32 m; 450 u32 m;
@@ -489,7 +487,7 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
489 if (rc == -ETIMEDOUT) 487 if (rc == -ETIMEDOUT)
490 return rc; 488 return rc;
491 489
492 memcpy_fromio(reslist, res.virt, res.len); 490 memcpy(reslist, res.virt, res.len);
493 i2o_dma_free(dev, &res); 491 i2o_dma_free(dev, &res);
494 492
495 /* Query failed */ 493 /* Query failed */
@@ -531,17 +529,23 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
531 void *buf, int buflen) 529 void *buf, int buflen)
532{ 530{
533 u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; 531 u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
534 u8 resblk[8 + buflen]; /* 8 bytes for header */ 532 u8 *resblk; /* 8 bytes for header */
535 int size; 533 int size;
536 534
537 if (field == -1) /* whole group */ 535 if (field == -1) /* whole group */
538 opblk[4] = -1; 536 opblk[4] = -1;
539 537
538 resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC);
539 if (!resblk)
540 return -ENOMEM;
541
540 size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk, 542 size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
541 sizeof(opblk), resblk, sizeof(resblk)); 543 sizeof(opblk), resblk, buflen + 8);
542 544
543 memcpy(buf, resblk + 8, buflen); /* cut off header */ 545 memcpy(buf, resblk + 8, buflen); /* cut off header */
544 546
547 kfree(resblk);
548
545 if (size > buflen) 549 if (size > buflen)
546 return buflen; 550 return buflen;
547 551
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 91f4edbb2a27..739bfdef0c6d 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -17,9 +17,12 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/rwsem.h> 18#include <linux/rwsem.h>
19#include <linux/i2o.h> 19#include <linux/i2o.h>
20#include "core.h"
21
22#define OSM_NAME "i2o"
20 23
21/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */ 24/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
22unsigned int i2o_max_drivers = I2O_MAX_DRIVERS; 25static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
23module_param_named(max_drivers, i2o_max_drivers, uint, 0); 26module_param_named(max_drivers, i2o_max_drivers, uint, 0);
24MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support"); 27MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support");
25 28
@@ -76,17 +79,16 @@ int i2o_driver_register(struct i2o_driver *drv)
76 int rc = 0; 79 int rc = 0;
77 unsigned long flags; 80 unsigned long flags;
78 81
79 pr_debug("i2o: Register driver %s\n", drv->name); 82 osm_debug("Register driver %s\n", drv->name);
80 83
81 if (drv->event) { 84 if (drv->event) {
82 drv->event_queue = create_workqueue(drv->name); 85 drv->event_queue = create_workqueue(drv->name);
83 if (!drv->event_queue) { 86 if (!drv->event_queue) {
84 printk(KERN_ERR "i2o: Could not initialize event queue " 87 osm_err("Could not initialize event queue for driver "
85 "for driver %s\n", drv->name); 88 "%s\n", drv->name);
86 return -EFAULT; 89 return -EFAULT;
87 } 90 }
88 pr_debug("i2o: Event queue initialized for driver %s\n", 91 osm_debug("Event queue initialized for driver %s\n", drv->name);
89 drv->name);
90 } else 92 } else
91 drv->event_queue = NULL; 93 drv->event_queue = NULL;
92 94
@@ -97,8 +99,8 @@ int i2o_driver_register(struct i2o_driver *drv)
97 99
98 for (i = 0; i2o_drivers[i]; i++) 100 for (i = 0; i2o_drivers[i]; i++)
99 if (i >= i2o_max_drivers) { 101 if (i >= i2o_max_drivers) {
100 printk(KERN_ERR "i2o: too many drivers registered, " 102 osm_err("too many drivers registered, increase "
101 "increase max_drivers\n"); 103 "max_drivers\n");
102 spin_unlock_irqrestore(&i2o_drivers_lock, flags); 104 spin_unlock_irqrestore(&i2o_drivers_lock, flags);
103 return -EFAULT; 105 return -EFAULT;
104 } 106 }
@@ -108,18 +110,16 @@ int i2o_driver_register(struct i2o_driver *drv)
108 110
109 spin_unlock_irqrestore(&i2o_drivers_lock, flags); 111 spin_unlock_irqrestore(&i2o_drivers_lock, flags);
110 112
111 pr_debug("i2o: driver %s gets context id %d\n", drv->name, 113 osm_debug("driver %s gets context id %d\n", drv->name, drv->context);
112 drv->context);
113 114
114 list_for_each_entry(c, &i2o_controllers, list) { 115 list_for_each_entry(c, &i2o_controllers, list) {
115 struct i2o_device *i2o_dev; 116 struct i2o_device *i2o_dev;
116 117
117 i2o_driver_notify_controller_add(drv, c); 118 i2o_driver_notify_controller_add(drv, c);
118 list_for_each_entry(i2o_dev, &c->devices, list) 119 list_for_each_entry(i2o_dev, &c->devices, list)
119 i2o_driver_notify_device_add(drv, i2o_dev); 120 i2o_driver_notify_device_add(drv, i2o_dev);
120 } 121 }
121 122
122
123 rc = driver_register(&drv->driver); 123 rc = driver_register(&drv->driver);
124 if (rc) 124 if (rc)
125 destroy_workqueue(drv->event_queue); 125 destroy_workqueue(drv->event_queue);
@@ -139,7 +139,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
139 struct i2o_controller *c; 139 struct i2o_controller *c;
140 unsigned long flags; 140 unsigned long flags;
141 141
142 pr_debug("i2o: unregister driver %s\n", drv->name); 142 osm_debug("unregister driver %s\n", drv->name);
143 143
144 driver_unregister(&drv->driver); 144 driver_unregister(&drv->driver);
145 145
@@ -159,7 +159,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
159 if (drv->event_queue) { 159 if (drv->event_queue) {
160 destroy_workqueue(drv->event_queue); 160 destroy_workqueue(drv->event_queue);
161 drv->event_queue = NULL; 161 drv->event_queue = NULL;
162 pr_debug("i2o: event queue removed for %s\n", drv->name); 162 osm_debug("event queue removed for %s\n", drv->name);
163 } 163 }
164}; 164};
165 165
@@ -176,68 +176,70 @@ void i2o_driver_unregister(struct i2o_driver *drv)
176 * on success and if the message should be flushed afterwords. Returns 176 * on success and if the message should be flushed afterwords. Returns
177 * negative error code on failure (the message will be flushed too). 177 * negative error code on failure (the message will be flushed too).
178 */ 178 */
179int i2o_driver_dispatch(struct i2o_controller *c, u32 m, 179int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
180 struct i2o_message __iomem *msg)
181{ 180{
182 struct i2o_driver *drv; 181 struct i2o_driver *drv;
183 u32 context = readl(&msg->u.s.icntxt); 182 struct i2o_message *msg = i2o_msg_out_to_virt(c, m);
183 u32 context = le32_to_cpu(msg->u.s.icntxt);
184 unsigned long flags;
184 185
185 if (likely(context < i2o_max_drivers)) { 186 if (unlikely(context >= i2o_max_drivers)) {
186 spin_lock(&i2o_drivers_lock); 187 osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
187 drv = i2o_drivers[context]; 188 context);
188 spin_unlock(&i2o_drivers_lock); 189 return -EIO;
190 }
189 191
190 if (unlikely(!drv)) { 192 spin_lock_irqsave(&i2o_drivers_lock, flags);
191 printk(KERN_WARNING "%s: Spurious reply to unknown " 193 drv = i2o_drivers[context];
192 "driver %d\n", c->name, context); 194 spin_unlock_irqrestore(&i2o_drivers_lock, flags);
193 return -EIO;
194 }
195 195
196 if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) { 196 if (unlikely(!drv)) {
197 struct i2o_device *dev, *tmp; 197 osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
198 struct i2o_event *evt; 198 context);
199 u16 size; 199 return -EIO;
200 u16 tid; 200 }
201 201
202 tid = readl(&msg->u.head[1]) & 0x1fff; 202 if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
203 struct i2o_device *dev, *tmp;
204 struct i2o_event *evt;
205 u16 size;
206 u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff;
203 207
204 pr_debug("%s: event received from device %d\n", c->name, 208 osm_debug("event received from device %d\n", tid);
205 tid);
206 209
207 /* cut of header from message size (in 32-bit words) */ 210 if (!drv->event)
208 size = (readl(&msg->u.head[0]) >> 16) - 5; 211 return -EIO;
209 212
210 evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC); 213 /* cut of header from message size (in 32-bit words) */
211 if (!evt) 214 size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5;
212 return -ENOMEM;
213 memset(evt, 0, size * 4 + sizeof(*evt));
214 215
215 evt->size = size; 216 evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO);
216 memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt, 217 if (!evt)
217 (size + 2) * 4); 218 return -ENOMEM;
218 219
219 list_for_each_entry_safe(dev, tmp, &c->devices, list) 220 evt->size = size;
220 if (dev->lct_data.tid == tid) { 221 evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt);
221 evt->i2o_dev = dev; 222 evt->event_indicator = le32_to_cpu(msg->body[0]);
222 break; 223 memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
223 }
224 224
225 INIT_WORK(&evt->work, (void (*)(void *))drv->event, 225 list_for_each_entry_safe(dev, tmp, &c->devices, list)
226 evt); 226 if (dev->lct_data.tid == tid) {
227 queue_work(drv->event_queue, &evt->work); 227 evt->i2o_dev = dev;
228 return 1; 228 break;
229 } 229 }
230 230
231 if (likely(drv->reply)) 231 INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt);
232 return drv->reply(c, m, msg); 232 queue_work(drv->event_queue, &evt->work);
233 else 233 return 1;
234 pr_debug("%s: Reply to driver %s, but no reply function" 234 }
235 " defined!\n", c->name, drv->name); 235
236 if (unlikely(!drv->reply)) {
237 osm_debug("%s: Reply to driver %s, but no reply function"
238 " defined!\n", c->name, drv->name);
236 return -EIO; 239 return -EIO;
237 } else 240 }
238 printk(KERN_WARNING "%s: Spurious reply to unknown driver " 241
239 "%d\n", c->name, readl(&msg->u.s.icntxt)); 242 return drv->reply(c, m, msg);
240 return -EIO;
241} 243}
242 244
243/** 245/**
@@ -334,11 +336,11 @@ int __init i2o_driver_init(void)
334 if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) || 336 if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
335 ((i2o_max_drivers ^ (i2o_max_drivers - 1)) != 337 ((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
336 (2 * i2o_max_drivers - 1))) { 338 (2 * i2o_max_drivers - 1))) {
337 printk(KERN_WARNING "i2o: max_drivers set to %d, but must be " 339 osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
338 ">=2 and <= 64 and a power of 2\n", i2o_max_drivers); 340 "a power of 2\n", i2o_max_drivers);
339 i2o_max_drivers = I2O_MAX_DRIVERS; 341 i2o_max_drivers = I2O_MAX_DRIVERS;
340 } 342 }
341 printk(KERN_INFO "i2o: max drivers = %d\n", i2o_max_drivers); 343 osm_info("max drivers = %d\n", i2o_max_drivers);
342 344
343 i2o_drivers = 345 i2o_drivers =
344 kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL); 346 kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 79c1cbfb8f44..bda2c62648ba 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -30,6 +30,7 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/i2o.h> 31#include <linux/i2o.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include "core.h"
33 34
34#define OSM_NAME "exec-osm" 35#define OSM_NAME "exec-osm"
35 36
@@ -37,9 +38,6 @@ struct i2o_driver i2o_exec_driver;
37 38
38static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind); 39static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
39 40
40/* Module internal functions from other sources */
41extern int i2o_device_parse_lct(struct i2o_controller *);
42
43/* global wait list for POST WAIT */ 41/* global wait list for POST WAIT */
44static LIST_HEAD(i2o_exec_wait_list); 42static LIST_HEAD(i2o_exec_wait_list);
45 43
@@ -50,7 +48,7 @@ struct i2o_exec_wait {
50 u32 tcntxt; /* transaction context from reply */ 48 u32 tcntxt; /* transaction context from reply */
51 int complete; /* 1 if reply received otherwise 0 */ 49 int complete; /* 1 if reply received otherwise 0 */
52 u32 m; /* message id */ 50 u32 m; /* message id */
53 struct i2o_message __iomem *msg; /* pointer to the reply message */ 51 struct i2o_message *msg; /* pointer to the reply message */
54 struct list_head list; /* node in global wait list */ 52 struct list_head list; /* node in global wait list */
55}; 53};
56 54
@@ -108,7 +106,8 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
108 * buffer must not be freed. Instead the event completion will free them 106 * buffer must not be freed. Instead the event completion will free them
109 * for you. In all other cases the buffer are your problem. 107 * for you. In all other cases the buffer are your problem.
110 * 108 *
111 * Returns 0 on success or negative error code on failure. 109 * Returns 0 on success, negative error code on timeout or positive error
110 * code from reply.
112 */ 111 */
113int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long 112int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
114 timeout, struct i2o_dma *dma) 113 timeout, struct i2o_dma *dma)
@@ -116,7 +115,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
116 DECLARE_WAIT_QUEUE_HEAD(wq); 115 DECLARE_WAIT_QUEUE_HEAD(wq);
117 struct i2o_exec_wait *wait; 116 struct i2o_exec_wait *wait;
118 static u32 tcntxt = 0x80000000; 117 static u32 tcntxt = 0x80000000;
119 struct i2o_message __iomem *msg = c->in_queue.virt + m; 118 struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
120 int rc = 0; 119 int rc = 0;
121 120
122 wait = i2o_exec_wait_alloc(); 121 wait = i2o_exec_wait_alloc();
@@ -153,7 +152,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
153 list_add(&wait->list, &i2o_exec_wait_list); 152 list_add(&wait->list, &i2o_exec_wait_list);
154 153
155 wait_event_interruptible_timeout(wq, wait->complete, 154 wait_event_interruptible_timeout(wq, wait->complete,
156 timeout * HZ); 155 timeout * HZ);
157 156
158 wait->wq = NULL; 157 wait->wq = NULL;
159 } 158 }
@@ -161,8 +160,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
161 barrier(); 160 barrier();
162 161
163 if (wait->complete) { 162 if (wait->complete) {
164 if (readl(&wait->msg->body[0]) >> 24) 163 rc = le32_to_cpu(wait->msg->body[0]) >> 24;
165 rc = readl(&wait->msg->body[0]) & 0xff;
166 i2o_flush_reply(c, wait->m); 164 i2o_flush_reply(c, wait->m);
167 i2o_exec_wait_free(wait); 165 i2o_exec_wait_free(wait);
168 } else { 166 } else {
@@ -187,6 +185,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
187 * @c: I2O controller which answers 185 * @c: I2O controller which answers
188 * @m: message id 186 * @m: message id
189 * @msg: pointer to the I2O reply message 187 * @msg: pointer to the I2O reply message
188 * @context: transaction context of request
190 * 189 *
191 * This function is called in interrupt context only. If the reply reached 190 * This function is called in interrupt context only. If the reply reached
192 * before the timeout, the i2o_exec_wait struct is filled with the message 191 * before the timeout, the i2o_exec_wait struct is filled with the message
@@ -201,16 +200,12 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
201 * message must also be given back to the controller. 200 * message must also be given back to the controller.
202 */ 201 */
203static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, 202static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
204 struct i2o_message __iomem *msg) 203 struct i2o_message *msg, u32 context)
205{ 204{
206 struct i2o_exec_wait *wait, *tmp; 205 struct i2o_exec_wait *wait, *tmp;
207 static spinlock_t lock; 206 unsigned long flags;
207 static spinlock_t lock = SPIN_LOCK_UNLOCKED;
208 int rc = 1; 208 int rc = 1;
209 u32 context;
210
211 spin_lock_init(&lock);
212
213 context = readl(&msg->u.s.tcntxt);
214 209
215 /* 210 /*
216 * We need to search through the i2o_exec_wait_list to see if the given 211 * We need to search through the i2o_exec_wait_list to see if the given
@@ -219,11 +214,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
219 * already expired. Not much we can do about that except log it for 214 * already expired. Not much we can do about that except log it for
220 * debug purposes, increase timeout, and recompile. 215 * debug purposes, increase timeout, and recompile.
221 */ 216 */
222 spin_lock(&lock); 217 spin_lock_irqsave(&lock, flags);
223 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { 218 list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) {
224 if (wait->tcntxt == context) { 219 if (wait->tcntxt == context) {
225 list_del(&wait->list); 220 list_del(&wait->list);
226 221
222 spin_unlock_irqrestore(&lock, flags);
223
227 wait->m = m; 224 wait->m = m;
228 wait->msg = msg; 225 wait->msg = msg;
229 wait->complete = 1; 226 wait->complete = 1;
@@ -245,21 +242,63 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
245 rc = -1; 242 rc = -1;
246 } 243 }
247 244
248 spin_unlock(&lock);
249
250 return rc; 245 return rc;
251 } 246 }
252 } 247 }
253 248
254 spin_unlock(&lock); 249 spin_unlock_irqrestore(&lock, flags);
255 250
256 pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, 251 osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
257 context); 252 context);
258 253
259 return -1; 254 return -1;
260}; 255};
261 256
262/** 257/**
258 * i2o_exec_show_vendor_id - Displays Vendor ID of controller
259 * @d: device of which the Vendor ID should be displayed
260 * @buf: buffer into which the Vendor ID should be printed
261 *
262 * Returns number of bytes printed into buffer.
263 */
264static ssize_t i2o_exec_show_vendor_id(struct device *d, struct device_attribute *attr, char *buf)
265{
266 struct i2o_device *dev = to_i2o_device(d);
267 u16 id;
268
269 if (i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) {
270 sprintf(buf, "0x%04x", id);
271 return strlen(buf) + 1;
272 }
273
274 return 0;
275};
276
277/**
278 * i2o_exec_show_product_id - Displays Product ID of controller
279 * @d: device of which the Product ID should be displayed
280 * @buf: buffer into which the Product ID should be printed
281 *
282 * Returns number of bytes printed into buffer.
283 */
284static ssize_t i2o_exec_show_product_id(struct device *d, struct device_attribute *attr, char *buf)
285{
286 struct i2o_device *dev = to_i2o_device(d);
287 u16 id;
288
289 if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {
290 sprintf(buf, "0x%04x", id);
291 return strlen(buf) + 1;
292 }
293
294 return 0;
295};
296
297/* Exec-OSM device attributes */
298static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL);
299static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
300
301/**
263 * i2o_exec_probe - Called if a new I2O device (executive class) appears 302 * i2o_exec_probe - Called if a new I2O device (executive class) appears
264 * @dev: I2O device which should be probed 303 * @dev: I2O device which should be probed
265 * 304 *
@@ -271,10 +310,16 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
271static int i2o_exec_probe(struct device *dev) 310static int i2o_exec_probe(struct device *dev)
272{ 311{
273 struct i2o_device *i2o_dev = to_i2o_device(dev); 312 struct i2o_device *i2o_dev = to_i2o_device(dev);
313 struct i2o_controller *c = i2o_dev->iop;
274 314
275 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); 315 i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
276 316
277 i2o_dev->iop->exec = i2o_dev; 317 c->exec = i2o_dev;
318
319 i2o_exec_lct_notify(c, c->lct->change_ind + 1);
320
321 device_create_file(dev, &dev_attr_vendor_id);
322 device_create_file(dev, &dev_attr_product_id);
278 323
279 return 0; 324 return 0;
280}; 325};
@@ -289,6 +334,9 @@ static int i2o_exec_probe(struct device *dev)
289 */ 334 */
290static int i2o_exec_remove(struct device *dev) 335static int i2o_exec_remove(struct device *dev)
291{ 336{
337 device_remove_file(dev, &dev_attr_product_id);
338 device_remove_file(dev, &dev_attr_vendor_id);
339
292 i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); 340 i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);
293 341
294 return 0; 342 return 0;
@@ -300,12 +348,16 @@ static int i2o_exec_remove(struct device *dev)
300 * 348 *
301 * This function handles asynchronus LCT NOTIFY replies. It parses the 349 * This function handles asynchronus LCT NOTIFY replies. It parses the
302 * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY 350 * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
303 * again. 351 * again, otherwise send LCT NOTIFY to get informed on next LCT change.
304 */ 352 */
305static void i2o_exec_lct_modified(struct i2o_controller *c) 353static void i2o_exec_lct_modified(struct i2o_controller *c)
306{ 354{
307 if (i2o_device_parse_lct(c) == -EAGAIN) 355 u32 change_ind = 0;
308 i2o_exec_lct_notify(c, 0); 356
357 if (i2o_device_parse_lct(c) != -EAGAIN)
358 change_ind = c->lct->change_ind + 1;
359
360 i2o_exec_lct_notify(c, change_ind);
309}; 361};
310 362
311/** 363/**
@@ -325,8 +377,14 @@ static void i2o_exec_lct_modified(struct i2o_controller *c)
325static int i2o_exec_reply(struct i2o_controller *c, u32 m, 377static int i2o_exec_reply(struct i2o_controller *c, u32 m,
326 struct i2o_message *msg) 378 struct i2o_message *msg)
327{ 379{
328 if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { // Fail bit is set 380 u32 context;
329 struct i2o_message __iomem *pmsg; /* preserved message */ 381
382 if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {
383 /*
384 * If Fail bit is set we must take the transaction context of
385 * the preserved message to find the right request again.
386 */
387 struct i2o_message __iomem *pmsg;
330 u32 pm; 388 u32 pm;
331 389
332 pm = le32_to_cpu(msg->body[3]); 390 pm = le32_to_cpu(msg->body[3]);
@@ -335,15 +393,15 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
335 393
336 i2o_report_status(KERN_INFO, "i2o_core", msg); 394 i2o_report_status(KERN_INFO, "i2o_core", msg);
337 395
338 /* Release the preserved msg by resubmitting it as a NOP */ 396 context = readl(&pmsg->u.s.tcntxt);
339 i2o_msg_nop(c, pm);
340 397
341 /* If reply to i2o_post_wait failed, return causes a timeout */ 398 /* Release the preserved msg */
342 return -1; 399 i2o_msg_nop(c, pm);
343 } 400 } else
401 context = le32_to_cpu(msg->u.s.tcntxt);
344 402
345 if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000) 403 if (context & 0x80000000)
346 return i2o_msg_post_wait_complete(c, m, msg); 404 return i2o_msg_post_wait_complete(c, m, msg, context);
347 405
348 if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) { 406 if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
349 struct work_struct *work; 407 struct work_struct *work;
@@ -381,8 +439,9 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
381 */ 439 */
382static void i2o_exec_event(struct i2o_event *evt) 440static void i2o_exec_event(struct i2o_event *evt)
383{ 441{
384 osm_info("Event received from device: %d\n", 442 if (likely(evt->i2o_dev))
385 evt->i2o_dev->lct_data.tid); 443 osm_debug("Event received from device: %d\n",
444 evt->i2o_dev->lct_data.tid);
386 kfree(evt); 445 kfree(evt);
387}; 446};
388 447
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 4830b7759061..f283b5bafdd3 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -62,7 +62,7 @@
62#include "i2o_block.h" 62#include "i2o_block.h"
63 63
64#define OSM_NAME "block-osm" 64#define OSM_NAME "block-osm"
65#define OSM_VERSION "$Rev$" 65#define OSM_VERSION "1.287"
66#define OSM_DESCRIPTION "I2O Block Device OSM" 66#define OSM_DESCRIPTION "I2O Block Device OSM"
67 67
68static struct i2o_driver i2o_block_driver; 68static struct i2o_driver i2o_block_driver;
@@ -104,7 +104,8 @@ static int i2o_block_remove(struct device *dev)
104 struct i2o_device *i2o_dev = to_i2o_device(dev); 104 struct i2o_device *i2o_dev = to_i2o_device(dev);
105 struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev); 105 struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev);
106 106
107 osm_info("Device removed %s\n", i2o_blk_dev->gd->disk_name); 107 osm_info("device removed (TID: %03x): %s\n", i2o_dev->lct_data.tid,
108 i2o_blk_dev->gd->disk_name);
108 109
109 i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0); 110 i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0);
110 111
@@ -146,6 +147,29 @@ static int i2o_block_device_flush(struct i2o_device *dev)
146}; 147};
147 148
148/** 149/**
150 * i2o_block_issue_flush - device-flush interface for block-layer
151 * @queue: the request queue of the device which should be flushed
152 * @disk: gendisk
153 * @error_sector: error offset
154 *
155 * Helper function to provide flush functionality to block-layer.
156 *
157 * Returns 0 on success or negative error code on failure.
158 */
159
160static int i2o_block_issue_flush(request_queue_t * queue, struct gendisk *disk,
161 sector_t * error_sector)
162{
163 struct i2o_block_device *i2o_blk_dev = queue->queuedata;
164 int rc = -ENODEV;
165
166 if (likely(i2o_blk_dev))
167 rc = i2o_block_device_flush(i2o_blk_dev->i2o_dev);
168
169 return rc;
170}
171
172/**
149 * i2o_block_device_mount - Mount (load) the media of device dev 173 * i2o_block_device_mount - Mount (load) the media of device dev
150 * @dev: I2O device which should receive the mount request 174 * @dev: I2O device which should receive the mount request
151 * @media_id: Media Identifier 175 * @media_id: Media Identifier
@@ -298,28 +322,31 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq)
298 322
299/** 323/**
300 * i2o_block_sglist_alloc - Allocate the SG list and map it 324 * i2o_block_sglist_alloc - Allocate the SG list and map it
325 * @c: I2O controller to which the request belongs
301 * @ireq: I2O block request 326 * @ireq: I2O block request
302 * 327 *
303 * Builds the SG list and map it into to be accessable by the controller. 328 * Builds the SG list and map it to be accessable by the controller.
304 * 329 *
305 * Returns the number of elements in the SG list or 0 on failure. 330 * Returns 0 on failure or 1 on success.
306 */ 331 */
307static inline int i2o_block_sglist_alloc(struct i2o_block_request *ireq) 332static inline int i2o_block_sglist_alloc(struct i2o_controller *c,
333 struct i2o_block_request *ireq,
334 u32 __iomem ** mptr)
308{ 335{
309 struct device *dev = &ireq->i2o_blk_dev->i2o_dev->iop->pdev->dev;
310 int nents; 336 int nents;
337 enum dma_data_direction direction;
311 338
339 ireq->dev = &c->pdev->dev;
312 nents = blk_rq_map_sg(ireq->req->q, ireq->req, ireq->sg_table); 340 nents = blk_rq_map_sg(ireq->req->q, ireq->req, ireq->sg_table);
313 341
314 if (rq_data_dir(ireq->req) == READ) 342 if (rq_data_dir(ireq->req) == READ)
315 ireq->sg_dma_direction = PCI_DMA_FROMDEVICE; 343 direction = PCI_DMA_FROMDEVICE;
316 else 344 else
317 ireq->sg_dma_direction = PCI_DMA_TODEVICE; 345 direction = PCI_DMA_TODEVICE;
318 346
319 ireq->sg_nents = dma_map_sg(dev, ireq->sg_table, nents, 347 ireq->sg_nents = nents;
320 ireq->sg_dma_direction);
321 348
322 return ireq->sg_nents; 349 return i2o_dma_map_sg(c, ireq->sg_table, nents, direction, mptr);
323}; 350};
324 351
325/** 352/**
@@ -330,10 +357,14 @@ static inline int i2o_block_sglist_alloc(struct i2o_block_request *ireq)
330 */ 357 */
331static inline void i2o_block_sglist_free(struct i2o_block_request *ireq) 358static inline void i2o_block_sglist_free(struct i2o_block_request *ireq)
332{ 359{
333 struct device *dev = &ireq->i2o_blk_dev->i2o_dev->iop->pdev->dev; 360 enum dma_data_direction direction;
334 361
335 dma_unmap_sg(dev, ireq->sg_table, ireq->sg_nents, 362 if (rq_data_dir(ireq->req) == READ)
336 ireq->sg_dma_direction); 363 direction = PCI_DMA_FROMDEVICE;
364 else
365 direction = PCI_DMA_TODEVICE;
366
367 dma_unmap_sg(ireq->dev, ireq->sg_table, ireq->sg_nents, direction);
337}; 368};
338 369
339/** 370/**
@@ -351,6 +382,11 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
351 struct i2o_block_device *i2o_blk_dev = q->queuedata; 382 struct i2o_block_device *i2o_blk_dev = q->queuedata;
352 struct i2o_block_request *ireq; 383 struct i2o_block_request *ireq;
353 384
385 if (unlikely(!i2o_blk_dev)) {
386 osm_err("block device already removed\n");
387 return BLKPREP_KILL;
388 }
389
354 /* request is already processed by us, so return */ 390 /* request is already processed by us, so return */
355 if (req->flags & REQ_SPECIAL) { 391 if (req->flags & REQ_SPECIAL) {
356 osm_debug("REQ_SPECIAL already set!\n"); 392 osm_debug("REQ_SPECIAL already set!\n");
@@ -400,71 +436,65 @@ static void i2o_block_delayed_request_fn(void *delayed_request)
400}; 436};
401 437
402/** 438/**
403 * i2o_block_reply - Block OSM reply handler. 439 * i2o_block_end_request - Post-processing of completed commands
404 * @c: I2O controller from which the message arrives 440 * @req: request which should be completed
405 * @m: message id of reply 441 * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
406 * qmsg: the actuall I2O message reply 442 * @nr_bytes: number of bytes to complete
407 * 443 *
408 * This function gets all the message replies. 444 * Mark the request as complete. The lock must not be held when entering.
409 * 445 *
410 */ 446 */
411static int i2o_block_reply(struct i2o_controller *c, u32 m, 447static void i2o_block_end_request(struct request *req, int uptodate,
412 struct i2o_message *msg) 448 int nr_bytes)
413{ 449{
414 struct i2o_block_request *ireq; 450 struct i2o_block_request *ireq = req->special;
415 struct request *req; 451 struct i2o_block_device *dev = ireq->i2o_blk_dev;
416 struct i2o_block_device *dev; 452 request_queue_t *q = req->q;
417 struct request_queue *q;
418 u8 st;
419 unsigned long flags; 453 unsigned long flags;
420 454
421 /* FAILed message */ 455 if (end_that_request_chunk(req, uptodate, nr_bytes)) {
422 if (unlikely(le32_to_cpu(msg->u.head[0]) & (1 << 13))) { 456 int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT);
423 struct i2o_message *pmsg;
424 u32 pm;
425 457
426 /* 458 if (blk_pc_request(req))
427 * FAILed message from controller 459 leftover = req->data_len;
428 * We increment the error count and abort it
429 *
430 * In theory this will never happen. The I2O block class
431 * specification states that block devices never return
432 * FAILs but instead use the REQ status field...but
433 * better be on the safe side since no one really follows
434 * the spec to the book :)
435 */
436 pm = le32_to_cpu(msg->body[3]);
437 pmsg = i2o_msg_in_to_virt(c, pm);
438 460
439 req = i2o_cntxt_list_get(c, le32_to_cpu(pmsg->u.s.tcntxt)); 461 if (end_io_error(uptodate))
440 if (unlikely(!req)) { 462 end_that_request_chunk(req, 0, leftover);
441 osm_err("NULL reply received!\n"); 463 }
442 return -1;
443 }
444 464
445 ireq = req->special; 465 add_disk_randomness(req->rq_disk);
446 dev = ireq->i2o_blk_dev;
447 q = dev->gd->queue;
448 466
449 req->errors++; 467 spin_lock_irqsave(q->queue_lock, flags);
450
451 spin_lock_irqsave(q->queue_lock, flags);
452 468
453 while (end_that_request_chunk(req, !req->errors, 469 end_that_request_last(req);
454 le32_to_cpu(pmsg->body[1]))) ;
455 end_that_request_last(req);
456 470
471 if (likely(dev)) {
457 dev->open_queue_depth--; 472 dev->open_queue_depth--;
458 list_del(&ireq->queue); 473 list_del(&ireq->queue);
459 blk_start_queue(q); 474 }
460 475
461 spin_unlock_irqrestore(q->queue_lock, flags); 476 blk_start_queue(q);
462 477
463 /* Now flush the message by making it a NOP */ 478 spin_unlock_irqrestore(q->queue_lock, flags);
464 i2o_msg_nop(c, pm);
465 479
466 return -1; 480 i2o_block_sglist_free(ireq);
467 } 481 i2o_block_request_free(ireq);
482};
483
484/**
485 * i2o_block_reply - Block OSM reply handler.
486 * @c: I2O controller from which the message arrives
487 * @m: message id of reply
488 * qmsg: the actuall I2O message reply
489 *
490 * This function gets all the message replies.
491 *
492 */
493static int i2o_block_reply(struct i2o_controller *c, u32 m,
494 struct i2o_message *msg)
495{
496 struct request *req;
497 int uptodate = 1;
468 498
469 req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); 499 req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
470 if (unlikely(!req)) { 500 if (unlikely(!req)) {
@@ -472,61 +502,13 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
472 return -1; 502 return -1;
473 } 503 }
474 504
475 ireq = req->special;
476 dev = ireq->i2o_blk_dev;
477 q = dev->gd->queue;
478
479 if (unlikely(!dev->i2o_dev)) {
480 /*
481 * This is HACK, but Intel Integrated RAID allows user
482 * to delete a volume that is claimed, locked, and in use
483 * by the OS. We have to check for a reply from a
484 * non-existent device and flag it as an error or the system
485 * goes kaput...
486 */
487 req->errors++;
488 osm_warn("Data transfer to deleted device!\n");
489 spin_lock_irqsave(q->queue_lock, flags);
490 while (end_that_request_chunk
491 (req, !req->errors, le32_to_cpu(msg->body[1]))) ;
492 end_that_request_last(req);
493
494 dev->open_queue_depth--;
495 list_del(&ireq->queue);
496 blk_start_queue(q);
497
498 spin_unlock_irqrestore(q->queue_lock, flags);
499 return -1;
500 }
501
502 /* 505 /*
503 * Lets see what is cooking. We stuffed the 506 * Lets see what is cooking. We stuffed the
504 * request in the context. 507 * request in the context.
505 */ 508 */
506 509
507 st = le32_to_cpu(msg->body[0]) >> 24; 510 if ((le32_to_cpu(msg->body[0]) >> 24) != 0) {
508 511 u32 status = le32_to_cpu(msg->body[0]);
509 if (st != 0) {
510 int err;
511 char *bsa_errors[] = {
512 "Success",
513 "Media Error",
514 "Failure communicating to device",
515 "Device Failure",
516 "Device is not ready",
517 "Media not present",
518 "Media is locked by another user",
519 "Media has failed",
520 "Failure communicating to device",
521 "Device bus failure",
522 "Device is locked by another user",
523 "Device is write protected",
524 "Device has reset",
525 "Volume has changed, waiting for acknowledgement"
526 };
527
528 err = le32_to_cpu(msg->body[0]) & 0xffff;
529
530 /* 512 /*
531 * Device not ready means two things. One is that the 513 * Device not ready means two things. One is that the
532 * the thing went offline (but not a removal media) 514 * the thing went offline (but not a removal media)
@@ -539,40 +521,23 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
539 * Don't stick a supertrak100 into cache aggressive modes 521 * Don't stick a supertrak100 into cache aggressive modes
540 */ 522 */
541 523
542 osm_err("block-osm: /dev/%s error: %s", dev->gd->disk_name, 524 osm_err("TID %03x error status: 0x%02x, detailed status: "
543 bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]); 525 "0x%04x\n", (le32_to_cpu(msg->u.head[1]) >> 12 & 0xfff),
544 if (le32_to_cpu(msg->body[0]) & 0x00ff0000) 526 status >> 24, status & 0xffff);
545 printk(KERN_ERR " - DDM attempted %d retries",
546 (le32_to_cpu(msg->body[0]) >> 16) & 0x00ff);
547 printk(KERN_ERR ".\n");
548 req->errors++;
549 } else
550 req->errors = 0;
551 527
552 if (!end_that_request_chunk 528 req->errors++;
553 (req, !req->errors, le32_to_cpu(msg->body[1]))) {
554 add_disk_randomness(req->rq_disk);
555 spin_lock_irqsave(q->queue_lock, flags);
556
557 end_that_request_last(req);
558 529
559 dev->open_queue_depth--; 530 uptodate = 0;
560 list_del(&ireq->queue); 531 }
561 blk_start_queue(q);
562 532
563 spin_unlock_irqrestore(q->queue_lock, flags); 533 i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1]));
564
565 i2o_block_sglist_free(ireq);
566 i2o_block_request_free(ireq);
567 } else
568 osm_err("still remaining chunks\n");
569 534
570 return 1; 535 return 1;
571}; 536};
572 537
573static void i2o_block_event(struct i2o_event *evt) 538static void i2o_block_event(struct i2o_event *evt)
574{ 539{
575 osm_info("block-osm: event received\n"); 540 osm_debug("event received\n");
576 kfree(evt); 541 kfree(evt);
577}; 542};
578 543
@@ -778,18 +743,25 @@ static int i2o_block_media_changed(struct gendisk *disk)
778static int i2o_block_transfer(struct request *req) 743static int i2o_block_transfer(struct request *req)
779{ 744{
780 struct i2o_block_device *dev = req->rq_disk->private_data; 745 struct i2o_block_device *dev = req->rq_disk->private_data;
781 struct i2o_controller *c = dev->i2o_dev->iop; 746 struct i2o_controller *c;
782 int tid = dev->i2o_dev->lct_data.tid; 747 int tid = dev->i2o_dev->lct_data.tid;
783 struct i2o_message __iomem *msg; 748 struct i2o_message __iomem *msg;
784 void __iomem *mptr; 749 u32 __iomem *mptr;
785 struct i2o_block_request *ireq = req->special; 750 struct i2o_block_request *ireq = req->special;
786 struct scatterlist *sg;
787 int sgnum;
788 int i;
789 u32 m; 751 u32 m;
790 u32 tcntxt; 752 u32 tcntxt;
791 u32 sg_flags; 753 u32 sgl_offset = SGL_OFFSET_8;
754 u32 ctl_flags = 0x00000000;
792 int rc; 755 int rc;
756 u32 cmd;
757
758 if (unlikely(!dev->i2o_dev)) {
759 osm_err("transfer to removed drive\n");
760 rc = -ENODEV;
761 goto exit;
762 }
763
764 c = dev->i2o_dev->iop;
793 765
794 m = i2o_msg_get(c, &msg); 766 m = i2o_msg_get(c, &msg);
795 if (m == I2O_QUEUE_EMPTY) { 767 if (m == I2O_QUEUE_EMPTY) {
@@ -803,82 +775,109 @@ static int i2o_block_transfer(struct request *req)
803 goto nop_msg; 775 goto nop_msg;
804 } 776 }
805 777
806 if ((sgnum = i2o_block_sglist_alloc(ireq)) <= 0) {
807 rc = -ENOMEM;
808 goto context_remove;
809 }
810
811 /* Build the message based on the request. */
812 writel(i2o_block_driver.context, &msg->u.s.icntxt); 778 writel(i2o_block_driver.context, &msg->u.s.icntxt);
813 writel(tcntxt, &msg->u.s.tcntxt); 779 writel(tcntxt, &msg->u.s.tcntxt);
814 writel(req->nr_sectors << 9, &msg->body[1]);
815
816 writel((((u64) req->sector) << 9) & 0xffffffff, &msg->body[2]);
817 writel(req->sector >> 23, &msg->body[3]);
818 780
819 mptr = &msg->body[4]; 781 mptr = &msg->body[0];
820
821 sg = ireq->sg_table;
822 782
823 if (rq_data_dir(req) == READ) { 783 if (rq_data_dir(req) == READ) {
824 writel(I2O_CMD_BLOCK_READ << 24 | HOST_TID << 12 | tid, 784 cmd = I2O_CMD_BLOCK_READ << 24;
825 &msg->u.head[1]); 785
826 sg_flags = 0x10000000;
827 switch (dev->rcache) { 786 switch (dev->rcache) {
828 case CACHE_NULL:
829 writel(0, &msg->body[0]);
830 break;
831 case CACHE_PREFETCH: 787 case CACHE_PREFETCH:
832 writel(0x201F0008, &msg->body[0]); 788 ctl_flags = 0x201F0008;
833 break; 789 break;
790
834 case CACHE_SMARTFETCH: 791 case CACHE_SMARTFETCH:
835 if (req->nr_sectors > 16) 792 if (req->nr_sectors > 16)
836 writel(0x201F0008, &msg->body[0]); 793 ctl_flags = 0x201F0008;
837 else 794 else
838 writel(0x001F0000, &msg->body[0]); 795 ctl_flags = 0x001F0000;
796 break;
797
798 default:
839 break; 799 break;
840 } 800 }
841 } else { 801 } else {
842 writel(I2O_CMD_BLOCK_WRITE << 24 | HOST_TID << 12 | tid, 802 cmd = I2O_CMD_BLOCK_WRITE << 24;
843 &msg->u.head[1]); 803
844 sg_flags = 0x14000000;
845 switch (dev->wcache) { 804 switch (dev->wcache) {
846 case CACHE_NULL:
847 writel(0, &msg->body[0]);
848 break;
849 case CACHE_WRITETHROUGH: 805 case CACHE_WRITETHROUGH:
850 writel(0x001F0008, &msg->body[0]); 806 ctl_flags = 0x001F0008;
851 break; 807 break;
852 case CACHE_WRITEBACK: 808 case CACHE_WRITEBACK:
853 writel(0x001F0010, &msg->body[0]); 809 ctl_flags = 0x001F0010;
854 break; 810 break;
855 case CACHE_SMARTBACK: 811 case CACHE_SMARTBACK:
856 if (req->nr_sectors > 16) 812 if (req->nr_sectors > 16)
857 writel(0x001F0004, &msg->body[0]); 813 ctl_flags = 0x001F0004;
858 else 814 else
859 writel(0x001F0010, &msg->body[0]); 815 ctl_flags = 0x001F0010;
860 break; 816 break;
861 case CACHE_SMARTTHROUGH: 817 case CACHE_SMARTTHROUGH:
862 if (req->nr_sectors > 16) 818 if (req->nr_sectors > 16)
863 writel(0x001F0004, &msg->body[0]); 819 ctl_flags = 0x001F0004;
864 else 820 else
865 writel(0x001F0010, &msg->body[0]); 821 ctl_flags = 0x001F0010;
822 default:
823 break;
824 }
825 }
826
827#ifdef CONFIG_I2O_EXT_ADAPTEC
828 if (c->adaptec) {
829 u8 cmd[10];
830 u32 scsi_flags;
831 u16 hwsec = queue_hardsect_size(req->q) >> KERNEL_SECTOR_SHIFT;
832
833 memset(cmd, 0, 10);
834
835 sgl_offset = SGL_OFFSET_12;
836
837 writel(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid,
838 &msg->u.head[1]);
839
840 writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
841 writel(tid, mptr++);
842
843 /*
844 * ENABLE_DISCONNECT
845 * SIMPLE_TAG
846 * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
847 */
848 if (rq_data_dir(req) == READ) {
849 cmd[0] = 0x28;
850 scsi_flags = 0x60a0000a;
851 } else {
852 cmd[0] = 0x2A;
853 scsi_flags = 0xa0a0000a;
866 } 854 }
855
856 writel(scsi_flags, mptr++);
857
858 *((u32 *) & cmd[2]) = cpu_to_be32(req->sector * hwsec);
859 *((u16 *) & cmd[7]) = cpu_to_be16(req->nr_sectors * hwsec);
860
861 memcpy_toio(mptr, cmd, 10);
862 mptr += 4;
863 writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
864 } else
865#endif
866 {
867 writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
868 writel(ctl_flags, mptr++);
869 writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
870 writel((u32) (req->sector << KERNEL_SECTOR_SHIFT), mptr++);
871 writel(req->sector >> (32 - KERNEL_SECTOR_SHIFT), mptr++);
867 } 872 }
868 873
869 for (i = sgnum; i > 0; i--) { 874 if (!i2o_block_sglist_alloc(c, ireq, &mptr)) {
870 if (i == 1) 875 rc = -ENOMEM;
871 sg_flags |= 0x80000000; 876 goto context_remove;
872 writel(sg_flags | sg_dma_len(sg), mptr);
873 writel(sg_dma_address(sg), mptr + 4);
874 mptr += 8;
875 sg++;
876 } 877 }
877 878
878 writel(I2O_MESSAGE_SIZE 879 writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) |
879 (((unsigned long)mptr - 880 sgl_offset, &msg->u.head[0]);
880 (unsigned long)&msg->u.head[0]) >> 2) | SGL_OFFSET_8,
881 &msg->u.head[0]);
882 881
883 list_add_tail(&ireq->queue, &dev->open_queue); 882 list_add_tail(&ireq->queue, &dev->open_queue);
884 dev->open_queue_depth++; 883 dev->open_queue_depth++;
@@ -921,11 +920,13 @@ static void i2o_block_request_fn(struct request_queue *q)
921 920
922 queue_depth = ireq->i2o_blk_dev->open_queue_depth; 921 queue_depth = ireq->i2o_blk_dev->open_queue_depth;
923 922
924 if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS) 923 if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS) {
925 if (!i2o_block_transfer(req)) { 924 if (!i2o_block_transfer(req)) {
926 blkdev_dequeue_request(req); 925 blkdev_dequeue_request(req);
927 continue; 926 continue;
928 } 927 } else
928 osm_info("transfer error\n");
929 }
929 930
930 if (queue_depth) 931 if (queue_depth)
931 break; 932 break;
@@ -939,7 +940,6 @@ static void i2o_block_request_fn(struct request_queue *q)
939 INIT_WORK(&dreq->work, i2o_block_delayed_request_fn, 940 INIT_WORK(&dreq->work, i2o_block_delayed_request_fn,
940 dreq); 941 dreq);
941 942
942 osm_info("transfer error\n");
943 if (!queue_delayed_work(i2o_block_driver.event_queue, 943 if (!queue_delayed_work(i2o_block_driver.event_queue,
944 &dreq->work, 944 &dreq->work,
945 I2O_BLOCK_RETRY_TIME)) 945 I2O_BLOCK_RETRY_TIME))
@@ -1008,6 +1008,7 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
1008 } 1008 }
1009 1009
1010 blk_queue_prep_rq(queue, i2o_block_prep_req_fn); 1010 blk_queue_prep_rq(queue, i2o_block_prep_req_fn);
1011 blk_queue_issue_flush_fn(queue, i2o_block_issue_flush);
1011 1012
1012 gd->major = I2O_MAJOR; 1013 gd->major = I2O_MAJOR;
1013 gd->queue = queue; 1014 gd->queue = queue;
@@ -1040,17 +1041,27 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
1040static int i2o_block_probe(struct device *dev) 1041static int i2o_block_probe(struct device *dev)
1041{ 1042{
1042 struct i2o_device *i2o_dev = to_i2o_device(dev); 1043 struct i2o_device *i2o_dev = to_i2o_device(dev);
1043 struct i2o_block_device *i2o_blk_dev;
1044 struct i2o_controller *c = i2o_dev->iop; 1044 struct i2o_controller *c = i2o_dev->iop;
1045 struct i2o_block_device *i2o_blk_dev;
1045 struct gendisk *gd; 1046 struct gendisk *gd;
1046 struct request_queue *queue; 1047 struct request_queue *queue;
1047 static int unit = 0; 1048 static int unit = 0;
1048 int rc; 1049 int rc;
1049 u64 size; 1050 u64 size;
1050 u32 blocksize; 1051 u32 blocksize;
1051 u16 power;
1052 u32 flags, status; 1052 u32 flags, status;
1053 int segments; 1053 u16 body_size = 4;
1054 unsigned short max_sectors;
1055
1056#ifdef CONFIG_I2O_EXT_ADAPTEC
1057 if (c->adaptec)
1058 body_size = 8;
1059#endif
1060
1061 if (c->limit_sectors)
1062 max_sectors = I2O_MAX_SECTORS_LIMITED;
1063 else
1064 max_sectors = I2O_MAX_SECTORS;
1054 1065
1055 /* skip devices which are used by IOP */ 1066 /* skip devices which are used by IOP */
1056 if (i2o_dev->lct_data.user_tid != 0xfff) { 1067 if (i2o_dev->lct_data.user_tid != 0xfff) {
@@ -1058,8 +1069,6 @@ static int i2o_block_probe(struct device *dev)
1058 return -ENODEV; 1069 return -ENODEV;
1059 } 1070 }
1060 1071
1061 osm_info("New device detected (TID: %03x)\n", i2o_dev->lct_data.tid);
1062
1063 if (i2o_device_claim(i2o_dev)) { 1072 if (i2o_device_claim(i2o_dev)) {
1064 osm_warn("Unable to claim device. Installation aborted\n"); 1073 osm_warn("Unable to claim device. Installation aborted\n");
1065 rc = -EFAULT; 1074 rc = -EFAULT;
@@ -1087,50 +1096,44 @@ static int i2o_block_probe(struct device *dev)
1087 queue = gd->queue; 1096 queue = gd->queue;
1088 queue->queuedata = i2o_blk_dev; 1097 queue->queuedata = i2o_blk_dev;
1089 1098
1090 blk_queue_max_phys_segments(queue, I2O_MAX_SEGMENTS); 1099 blk_queue_max_phys_segments(queue, I2O_MAX_PHYS_SEGMENTS);
1091 blk_queue_max_sectors(queue, I2O_MAX_SECTORS); 1100 blk_queue_max_sectors(queue, max_sectors);
1092 1101 blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size));
1093 if (c->short_req)
1094 segments = 8;
1095 else {
1096 i2o_status_block *sb;
1097 1102
1098 sb = c->status_block.virt; 1103 osm_debug("max sectors = %d\n", queue->max_phys_segments);
1099 1104 osm_debug("phys segments = %d\n", queue->max_sectors);
1100 segments = (sb->inbound_frame_size - 1105 osm_debug("max hw segments = %d\n", queue->max_hw_segments);
1101 sizeof(struct i2o_message) / 4 - 4) / 2;
1102 }
1103
1104 blk_queue_max_hw_segments(queue, segments);
1105
1106 osm_debug("max sectors = %d\n", I2O_MAX_SECTORS);
1107 osm_debug("phys segments = %d\n", I2O_MAX_SEGMENTS);
1108 osm_debug("hw segments = %d\n", segments);
1109 1106
1110 /* 1107 /*
1111 * Ask for the current media data. If that isn't supported 1108 * Ask for the current media data. If that isn't supported
1112 * then we ask for the device capacity data 1109 * then we ask for the device capacity data
1113 */ 1110 */
1114 if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) != 0 1111 if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) ||
1115 || i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) != 0) { 1112 i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
1116 i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4); 1113 blk_queue_hardsect_size(queue, blocksize);
1117 i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8); 1114 } else
1118 } 1115 osm_warn("unable to get blocksize of %s\n", gd->disk_name);
1119 osm_debug("blocksize = %d\n", blocksize);
1120 1116
1121 if (i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2)) 1117 if (i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) ||
1122 power = 0; 1118 i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
1119 set_capacity(gd, size >> KERNEL_SECTOR_SHIFT);
1120 } else
1121 osm_warn("could not get size of %s\n", gd->disk_name);
1122
1123 if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &i2o_blk_dev->power, 2))
1124 i2o_blk_dev->power = 0;
1123 i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4); 1125 i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4);
1124 i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4); 1126 i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4);
1125 1127
1126 set_capacity(gd, size >> 9);
1127
1128 i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0xffffffff); 1128 i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0xffffffff);
1129 1129
1130 add_disk(gd); 1130 add_disk(gd);
1131 1131
1132 unit++; 1132 unit++;
1133 1133
1134 osm_info("device added (TID: %03x): %s\n", i2o_dev->lct_data.tid,
1135 i2o_blk_dev->gd->disk_name);
1136
1134 return 0; 1137 return 0;
1135 1138
1136 claim_release: 1139 claim_release:
@@ -1178,7 +1181,7 @@ static int __init i2o_block_init(void)
1178 goto exit; 1181 goto exit;
1179 } 1182 }
1180 1183
1181 i2o_blk_req_pool.pool = mempool_create(I2O_REQ_MEMPOOL_SIZE, 1184 i2o_blk_req_pool.pool = mempool_create(I2O_BLOCK_REQ_MEMPOOL_SIZE,
1182 mempool_alloc_slab, 1185 mempool_alloc_slab,
1183 mempool_free_slab, 1186 mempool_free_slab,
1184 i2o_blk_req_pool.slab); 1187 i2o_blk_req_pool.slab);
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h
index ddd9a15679c0..4fdaa5bda412 100644
--- a/drivers/message/i2o/i2o_block.h
+++ b/drivers/message/i2o/i2o_block.h
@@ -56,42 +56,46 @@
56#define I2O_BLOCK_RETRY_TIME HZ/4 56#define I2O_BLOCK_RETRY_TIME HZ/4
57#define I2O_BLOCK_MAX_OPEN_REQUESTS 50 57#define I2O_BLOCK_MAX_OPEN_REQUESTS 50
58 58
59/* request queue sizes */
60#define I2O_BLOCK_REQ_MEMPOOL_SIZE 32
61
62#define KERNEL_SECTOR_SHIFT 9
63#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT)
64
59/* I2O Block OSM mempool struct */ 65/* I2O Block OSM mempool struct */
60struct i2o_block_mempool { 66struct i2o_block_mempool {
61 kmem_cache_t *slab; 67 kmem_cache_t *slab;
62 mempool_t *pool; 68 mempool_t *pool;
63}; 69};
64 70
65/* I2O Block device descriptor */ 71/* I2O Block device descriptor */
66struct i2o_block_device { 72struct i2o_block_device {
67 struct i2o_device *i2o_dev; /* pointer to I2O device */ 73 struct i2o_device *i2o_dev; /* pointer to I2O device */
68 struct gendisk *gd; 74 struct gendisk *gd;
69 spinlock_t lock; /* queue lock */ 75 spinlock_t lock; /* queue lock */
70 struct list_head open_queue; /* list of transfered, but unfinished 76 struct list_head open_queue; /* list of transfered, but unfinished
71 requests */ 77 requests */
72 unsigned int open_queue_depth; /* number of requests in the queue */ 78 unsigned int open_queue_depth; /* number of requests in the queue */
73 79
74 int rcache; /* read cache flags */ 80 int rcache; /* read cache flags */
75 int wcache; /* write cache flags */ 81 int wcache; /* write cache flags */
76 int flags; 82 int flags;
77 int power; /* power state */ 83 u16 power; /* power state */
78 int media_change_flag; /* media changed flag */ 84 int media_change_flag; /* media changed flag */
79}; 85};
80 86
81/* I2O Block device request */ 87/* I2O Block device request */
82struct i2o_block_request 88struct i2o_block_request {
83{
84 struct list_head queue; 89 struct list_head queue;
85 struct request *req; /* corresponding request */ 90 struct request *req; /* corresponding request */
86 struct i2o_block_device *i2o_blk_dev; /* I2O block device */ 91 struct i2o_block_device *i2o_blk_dev; /* I2O block device */
87 int sg_dma_direction; /* direction of DMA buffer read/write */ 92 struct device *dev; /* device used for DMA */
88 int sg_nents; /* number of SG elements */ 93 int sg_nents; /* number of SG elements */
89 struct scatterlist sg_table[I2O_MAX_SEGMENTS]; /* SG table */ 94 struct scatterlist sg_table[I2O_MAX_PHYS_SEGMENTS]; /* SG table */
90}; 95};
91 96
92/* I2O Block device delayed request */ 97/* I2O Block device delayed request */
93struct i2o_block_delayed_request 98struct i2o_block_delayed_request {
94{
95 struct work_struct work; 99 struct work_struct work;
96 struct request_queue *queue; 100 struct request_queue *queue;
97}; 101};
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 1fb5cdf67f8f..3c3a7abebb1b 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -30,29 +30,15 @@
30 * 2 of the License, or (at your option) any later version. 30 * 2 of the License, or (at your option) any later version.
31 */ 31 */
32 32
33#include <linux/module.h>
34#include <linux/kernel.h>
35#include <linux/pci.h>
36#include <linux/i2o.h>
37#include <linux/errno.h>
38#include <linux/init.h>
39#include <linux/slab.h>
40#include <linux/miscdevice.h> 33#include <linux/miscdevice.h>
41#include <linux/mm.h>
42#include <linux/spinlock.h>
43#include <linux/smp_lock.h> 34#include <linux/smp_lock.h>
44#include <linux/ioctl32.h>
45#include <linux/compat.h> 35#include <linux/compat.h>
46#include <linux/syscalls.h>
47 36
48#include <asm/uaccess.h> 37#include <asm/uaccess.h>
49#include <asm/io.h>
50 38
51#define OSM_NAME "config-osm" 39#include "core.h"
52#define OSM_VERSION "$Rev$"
53#define OSM_DESCRIPTION "I2O Configuration OSM"
54 40
55extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int); 41#define SG_TABLESIZE 30
56 42
57static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd, 43static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
58 unsigned long arg); 44 unsigned long arg);
@@ -80,15 +66,6 @@ struct i2o_cfg_info {
80static struct i2o_cfg_info *open_files = NULL; 66static struct i2o_cfg_info *open_files = NULL;
81static ulong i2o_cfg_info_id = 0; 67static ulong i2o_cfg_info_id = 0;
82 68
83/*
84 * Each of these describes an i2o message handler. They are
85 * multiplexed by the i2o_core code
86 */
87
88static struct i2o_driver i2o_config_driver = {
89 .name = OSM_NAME
90};
91
92static int i2o_cfg_getiops(unsigned long arg) 69static int i2o_cfg_getiops(unsigned long arg)
93{ 70{
94 struct i2o_controller *c; 71 struct i2o_controller *c;
@@ -391,9 +368,9 @@ static int i2o_cfg_swul(unsigned long arg)
391 368
392 i2o_dma_free(&c->pdev->dev, &buffer); 369 i2o_dma_free(&c->pdev->dev, &buffer);
393 370
394return_ret: 371 return_ret:
395 return ret; 372 return ret;
396return_fault: 373 return_fault:
397 ret = -EFAULT; 374 ret = -EFAULT;
398 goto return_ret; 375 goto return_ret;
399}; 376};
@@ -540,8 +517,10 @@ static int i2o_cfg_evt_get(unsigned long arg, struct file *fp)
540 return 0; 517 return 0;
541} 518}
542 519
520#ifdef CONFIG_I2O_EXT_ADAPTEC
543#ifdef CONFIG_COMPAT 521#ifdef CONFIG_COMPAT
544static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long arg) 522static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
523 unsigned long arg)
545{ 524{
546 struct i2o_cmd_passthru32 __user *cmd; 525 struct i2o_cmd_passthru32 __user *cmd;
547 struct i2o_controller *c; 526 struct i2o_controller *c;
@@ -555,6 +534,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
555 u32 sg_offset = 0; 534 u32 sg_offset = 0;
556 u32 sg_count = 0; 535 u32 sg_count = 0;
557 u32 i = 0; 536 u32 i = 0;
537 u32 sg_index = 0;
558 i2o_status_block *sb; 538 i2o_status_block *sb;
559 struct i2o_message *msg; 539 struct i2o_message *msg;
560 u32 m; 540 u32 m;
@@ -634,8 +614,8 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
634 if (sg_count > SG_TABLESIZE) { 614 if (sg_count > SG_TABLESIZE) {
635 printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n", 615 printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
636 c->name, sg_count); 616 c->name, sg_count);
637 kfree(reply); 617 rcode = -EINVAL;
638 return -EINVAL; 618 goto cleanup;
639 } 619 }
640 620
641 for (i = 0; i < sg_count; i++) { 621 for (i = 0; i < sg_count; i++) {
@@ -651,7 +631,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
651 goto cleanup; 631 goto cleanup;
652 } 632 }
653 sg_size = sg[i].flag_count & 0xffffff; 633 sg_size = sg[i].flag_count & 0xffffff;
654 p = &(sg_list[i]); 634 p = &(sg_list[sg_index++]);
655 /* Allocate memory for the transfer */ 635 /* Allocate memory for the transfer */
656 if (i2o_dma_alloc 636 if (i2o_dma_alloc
657 (&c->pdev->dev, p, sg_size, 637 (&c->pdev->dev, p, sg_size,
@@ -660,20 +640,21 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
660 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 640 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
661 c->name, sg_size, i, sg_count); 641 c->name, sg_size, i, sg_count);
662 rcode = -ENOMEM; 642 rcode = -ENOMEM;
663 goto cleanup; 643 goto sg_list_cleanup;
664 } 644 }
665 /* Copy in the user's SG buffer if necessary */ 645 /* Copy in the user's SG buffer if necessary */
666 if (sg[i]. 646 if (sg[i].
667 flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) { 647 flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
668 // TODO 64bit fix 648 // TODO 64bit fix
669 if (copy_from_user 649 if (copy_from_user
670 (p->virt, (void __user *)(unsigned long)sg[i].addr_bus, 650 (p->virt,
671 sg_size)) { 651 (void __user *)(unsigned long)sg[i].
652 addr_bus, sg_size)) {
672 printk(KERN_DEBUG 653 printk(KERN_DEBUG
673 "%s: Could not copy SG buf %d FROM user\n", 654 "%s: Could not copy SG buf %d FROM user\n",
674 c->name, i); 655 c->name, i);
675 rcode = -EFAULT; 656 rcode = -EFAULT;
676 goto cleanup; 657 goto sg_list_cleanup;
677 } 658 }
678 } 659 }
679 //TODO 64bit fix 660 //TODO 64bit fix
@@ -683,10 +664,10 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
683 664
684 rcode = i2o_msg_post_wait(c, m, 60); 665 rcode = i2o_msg_post_wait(c, m, 60);
685 if (rcode) 666 if (rcode)
686 goto cleanup; 667 goto sg_list_cleanup;
687 668
688 if (sg_offset) { 669 if (sg_offset) {
689 u32 msg[128]; 670 u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE];
690 /* Copy back the Scatter Gather buffers back to user space */ 671 /* Copy back the Scatter Gather buffers back to user space */
691 u32 j; 672 u32 j;
692 // TODO 64bit fix 673 // TODO 64bit fix
@@ -694,18 +675,18 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
694 int sg_size; 675 int sg_size;
695 676
696 // re-acquire the original message to handle correctly the sg copy operation 677 // re-acquire the original message to handle correctly the sg copy operation
697 memset(&msg, 0, MSG_FRAME_SIZE * 4); 678 memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
698 // get user msg size in u32s 679 // get user msg size in u32s
699 if (get_user(size, &user_msg[0])) { 680 if (get_user(size, &user_msg[0])) {
700 rcode = -EFAULT; 681 rcode = -EFAULT;
701 goto cleanup; 682 goto sg_list_cleanup;
702 } 683 }
703 size = size >> 16; 684 size = size >> 16;
704 size *= 4; 685 size *= 4;
705 /* Copy in the user's I2O command */ 686 /* Copy in the user's I2O command */
706 if (copy_from_user(msg, user_msg, size)) { 687 if (copy_from_user(msg, user_msg, size)) {
707 rcode = -EFAULT; 688 rcode = -EFAULT;
708 goto cleanup; 689 goto sg_list_cleanup;
709 } 690 }
710 sg_count = 691 sg_count =
711 (size - sg_offset * 4) / sizeof(struct sg_simple_element); 692 (size - sg_offset * 4) / sizeof(struct sg_simple_element);
@@ -727,7 +708,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
727 c->name, sg_list[j].virt, 708 c->name, sg_list[j].virt,
728 sg[j].addr_bus); 709 sg[j].addr_bus);
729 rcode = -EFAULT; 710 rcode = -EFAULT;
730 goto cleanup; 711 goto sg_list_cleanup;
731 } 712 }
732 } 713 }
733 } 714 }
@@ -741,6 +722,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
741 "%s: Could not copy message context FROM user\n", 722 "%s: Could not copy message context FROM user\n",
742 c->name); 723 c->name);
743 rcode = -EFAULT; 724 rcode = -EFAULT;
725 goto sg_list_cleanup;
744 } 726 }
745 if (copy_to_user(user_reply, reply, reply_size)) { 727 if (copy_to_user(user_reply, reply, reply_size)) {
746 printk(KERN_WARNING 728 printk(KERN_WARNING
@@ -749,16 +731,21 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
749 } 731 }
750 } 732 }
751 733
734 sg_list_cleanup:
735 for (i = 0; i < sg_index; i++)
736 i2o_dma_free(&c->pdev->dev, &sg_list[i]);
737
752 cleanup: 738 cleanup:
753 kfree(reply); 739 kfree(reply);
754 return rcode; 740 return rcode;
755} 741}
756 742
757static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) 743static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
744 unsigned long arg)
758{ 745{
759 int ret; 746 int ret;
760 lock_kernel(); 747 lock_kernel();
761 switch (cmd) { 748 switch (cmd) {
762 case I2OGETIOPS: 749 case I2OGETIOPS:
763 ret = i2o_cfg_ioctl(NULL, file, cmd, arg); 750 ret = i2o_cfg_ioctl(NULL, file, cmd, arg);
764 break; 751 break;
@@ -862,8 +849,8 @@ static int i2o_cfg_passthru(unsigned long arg)
862 if (sg_count > SG_TABLESIZE) { 849 if (sg_count > SG_TABLESIZE) {
863 printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n", 850 printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
864 c->name, sg_count); 851 c->name, sg_count);
865 kfree(reply); 852 rcode = -EINVAL;
866 return -EINVAL; 853 goto cleanup;
867 } 854 }
868 855
869 for (i = 0; i < sg_count; i++) { 856 for (i = 0; i < sg_count; i++) {
@@ -875,7 +862,7 @@ static int i2o_cfg_passthru(unsigned long arg)
875 "%s:Bad SG element %d - not simple (%x)\n", 862 "%s:Bad SG element %d - not simple (%x)\n",
876 c->name, i, sg[i].flag_count); 863 c->name, i, sg[i].flag_count);
877 rcode = -EINVAL; 864 rcode = -EINVAL;
878 goto cleanup; 865 goto sg_list_cleanup;
879 } 866 }
880 sg_size = sg[i].flag_count & 0xffffff; 867 sg_size = sg[i].flag_count & 0xffffff;
881 /* Allocate memory for the transfer */ 868 /* Allocate memory for the transfer */
@@ -885,7 +872,7 @@ static int i2o_cfg_passthru(unsigned long arg)
885 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", 872 "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
886 c->name, sg_size, i, sg_count); 873 c->name, sg_size, i, sg_count);
887 rcode = -ENOMEM; 874 rcode = -ENOMEM;
888 goto cleanup; 875 goto sg_list_cleanup;
889 } 876 }
890 sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. 877 sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
891 /* Copy in the user's SG buffer if necessary */ 878 /* Copy in the user's SG buffer if necessary */
@@ -899,7 +886,7 @@ static int i2o_cfg_passthru(unsigned long arg)
899 "%s: Could not copy SG buf %d FROM user\n", 886 "%s: Could not copy SG buf %d FROM user\n",
900 c->name, i); 887 c->name, i);
901 rcode = -EFAULT; 888 rcode = -EFAULT;
902 goto cleanup; 889 goto sg_list_cleanup;
903 } 890 }
904 } 891 }
905 //TODO 64bit fix 892 //TODO 64bit fix
@@ -909,7 +896,7 @@ static int i2o_cfg_passthru(unsigned long arg)
909 896
910 rcode = i2o_msg_post_wait(c, m, 60); 897 rcode = i2o_msg_post_wait(c, m, 60);
911 if (rcode) 898 if (rcode)
912 goto cleanup; 899 goto sg_list_cleanup;
913 900
914 if (sg_offset) { 901 if (sg_offset) {
915 u32 msg[128]; 902 u32 msg[128];
@@ -920,18 +907,18 @@ static int i2o_cfg_passthru(unsigned long arg)
920 int sg_size; 907 int sg_size;
921 908
922 // re-acquire the original message to handle correctly the sg copy operation 909 // re-acquire the original message to handle correctly the sg copy operation
923 memset(&msg, 0, MSG_FRAME_SIZE * 4); 910 memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
924 // get user msg size in u32s 911 // get user msg size in u32s
925 if (get_user(size, &user_msg[0])) { 912 if (get_user(size, &user_msg[0])) {
926 rcode = -EFAULT; 913 rcode = -EFAULT;
927 goto cleanup; 914 goto sg_list_cleanup;
928 } 915 }
929 size = size >> 16; 916 size = size >> 16;
930 size *= 4; 917 size *= 4;
931 /* Copy in the user's I2O command */ 918 /* Copy in the user's I2O command */
932 if (copy_from_user(msg, user_msg, size)) { 919 if (copy_from_user(msg, user_msg, size)) {
933 rcode = -EFAULT; 920 rcode = -EFAULT;
934 goto cleanup; 921 goto sg_list_cleanup;
935 } 922 }
936 sg_count = 923 sg_count =
937 (size - sg_offset * 4) / sizeof(struct sg_simple_element); 924 (size - sg_offset * 4) / sizeof(struct sg_simple_element);
@@ -953,7 +940,7 @@ static int i2o_cfg_passthru(unsigned long arg)
953 c->name, sg_list[j], 940 c->name, sg_list[j],
954 sg[j].addr_bus); 941 sg[j].addr_bus);
955 rcode = -EFAULT; 942 rcode = -EFAULT;
956 goto cleanup; 943 goto sg_list_cleanup;
957 } 944 }
958 } 945 }
959 } 946 }
@@ -975,10 +962,15 @@ static int i2o_cfg_passthru(unsigned long arg)
975 } 962 }
976 } 963 }
977 964
965 sg_list_cleanup:
966 for (i = 0; i < sg_index; i++)
967 kfree(sg_list[i]);
968
978 cleanup: 969 cleanup:
979 kfree(reply); 970 kfree(reply);
980 return rcode; 971 return rcode;
981} 972}
973#endif
982 974
983/* 975/*
984 * IOCTL Handler 976 * IOCTL Handler
@@ -1033,9 +1025,11 @@ static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
1033 ret = i2o_cfg_evt_get(arg, fp); 1025 ret = i2o_cfg_evt_get(arg, fp);
1034 break; 1026 break;
1035 1027
1028#ifdef CONFIG_I2O_EXT_ADAPTEC
1036 case I2OPASSTHRU: 1029 case I2OPASSTHRU:
1037 ret = i2o_cfg_passthru(arg); 1030 ret = i2o_cfg_passthru(arg);
1038 break; 1031 break;
1032#endif
1039 1033
1040 default: 1034 default:
1041 osm_debug("unknown ioctl called!\n"); 1035 osm_debug("unknown ioctl called!\n");
@@ -1137,37 +1131,21 @@ static struct miscdevice i2o_miscdev = {
1137 &config_fops 1131 &config_fops
1138}; 1132};
1139 1133
1140static int __init i2o_config_init(void) 1134static int __init i2o_config_old_init(void)
1141{ 1135{
1142 printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
1143
1144 spin_lock_init(&i2o_config_lock); 1136 spin_lock_init(&i2o_config_lock);
1145 1137
1146 if (misc_register(&i2o_miscdev) < 0) { 1138 if (misc_register(&i2o_miscdev) < 0) {
1147 osm_err("can't register device.\n"); 1139 osm_err("can't register device.\n");
1148 return -EBUSY; 1140 return -EBUSY;
1149 } 1141 }
1150 /* 1142
1151 * Install our handler
1152 */
1153 if (i2o_driver_register(&i2o_config_driver)) {
1154 osm_err("handler register failed.\n");
1155 misc_deregister(&i2o_miscdev);
1156 return -EBUSY;
1157 }
1158 return 0; 1143 return 0;
1159} 1144}
1160 1145
1161static void i2o_config_exit(void) 1146static void i2o_config_old_exit(void)
1162{ 1147{
1163 misc_deregister(&i2o_miscdev); 1148 misc_deregister(&i2o_miscdev);
1164 i2o_driver_unregister(&i2o_config_driver);
1165} 1149}
1166 1150
1167MODULE_AUTHOR("Red Hat Software"); 1151MODULE_AUTHOR("Red Hat Software");
1168MODULE_LICENSE("GPL");
1169MODULE_DESCRIPTION(OSM_DESCRIPTION);
1170MODULE_VERSION(OSM_VERSION);
1171
1172module_init(i2o_config_init);
1173module_exit(i2o_config_exit);
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index b176d0eeff7f..d559a1758363 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#define OSM_NAME "proc-osm" 30#define OSM_NAME "proc-osm"
31#define OSM_VERSION "$Rev$" 31#define OSM_VERSION "1.145"
32#define OSM_DESCRIPTION "I2O ProcFS OSM" 32#define OSM_DESCRIPTION "I2O ProcFS OSM"
33 33
34#define I2O_MAX_MODULES 4 34#define I2O_MAX_MODULES 4
@@ -228,7 +228,7 @@ static const char *i2o_get_class_name(int class)
228 case I2O_CLASS_FLOPPY_DEVICE: 228 case I2O_CLASS_FLOPPY_DEVICE:
229 idx = 12; 229 idx = 12;
230 break; 230 break;
231 case I2O_CLASS_BUS_ADAPTER_PORT: 231 case I2O_CLASS_BUS_ADAPTER:
232 idx = 13; 232 idx = 13;
233 break; 233 break;
234 case I2O_CLASS_PEER_TRANSPORT_AGENT: 234 case I2O_CLASS_PEER_TRANSPORT_AGENT:
@@ -490,7 +490,7 @@ static int i2o_seq_show_lct(struct seq_file *seq, void *v)
490 seq_printf(seq, ", Unknown Device Type"); 490 seq_printf(seq, ", Unknown Device Type");
491 break; 491 break;
492 492
493 case I2O_CLASS_BUS_ADAPTER_PORT: 493 case I2O_CLASS_BUS_ADAPTER:
494 if (lct->lct_entry[i].sub_class < BUS_TABLE_SIZE) 494 if (lct->lct_entry[i].sub_class < BUS_TABLE_SIZE)
495 seq_printf(seq, ", %s", 495 seq_printf(seq, ", %s",
496 bus_ports[lct->lct_entry[i]. 496 bus_ports[lct->lct_entry[i].
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index 43f5875e0be5..9f1744c3933b 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -54,6 +54,7 @@
54#include <linux/pci.h> 54#include <linux/pci.h>
55#include <linux/blkdev.h> 55#include <linux/blkdev.h>
56#include <linux/i2o.h> 56#include <linux/i2o.h>
57#include <linux/scatterlist.h>
57 58
58#include <asm/dma.h> 59#include <asm/dma.h>
59#include <asm/system.h> 60#include <asm/system.h>
@@ -64,19 +65,23 @@
64#include <scsi/scsi_host.h> 65#include <scsi/scsi_host.h>
65#include <scsi/scsi_device.h> 66#include <scsi/scsi_device.h>
66#include <scsi/scsi_cmnd.h> 67#include <scsi/scsi_cmnd.h>
68#include <scsi/scsi_request.h>
69#include <scsi/sg.h>
70#include <scsi/sg_request.h>
67 71
68#define OSM_NAME "scsi-osm" 72#define OSM_NAME "scsi-osm"
69#define OSM_VERSION "$Rev$" 73#define OSM_VERSION "1.282"
70#define OSM_DESCRIPTION "I2O SCSI Peripheral OSM" 74#define OSM_DESCRIPTION "I2O SCSI Peripheral OSM"
71 75
72static struct i2o_driver i2o_scsi_driver; 76static struct i2o_driver i2o_scsi_driver;
73 77
74static int i2o_scsi_max_id = 16; 78static unsigned int i2o_scsi_max_id = 16;
75static int i2o_scsi_max_lun = 8; 79static unsigned int i2o_scsi_max_lun = 255;
76 80
77struct i2o_scsi_host { 81struct i2o_scsi_host {
78 struct Scsi_Host *scsi_host; /* pointer to the SCSI host */ 82 struct Scsi_Host *scsi_host; /* pointer to the SCSI host */
79 struct i2o_controller *iop; /* pointer to the I2O controller */ 83 struct i2o_controller *iop; /* pointer to the I2O controller */
84 unsigned int lun; /* lun's used for block devices */
80 struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */ 85 struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */
81}; 86};
82 87
@@ -99,11 +104,17 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c)
99 u8 type; 104 u8 type;
100 int i; 105 int i;
101 size_t size; 106 size_t size;
102 i2o_status_block *sb; 107 u16 body_size = 6;
108
109#ifdef CONFIG_I2O_EXT_ADAPTEC
110 if (c->adaptec)
111 body_size = 8;
112#endif
103 113
104 list_for_each_entry(i2o_dev, &c->devices, list) 114 list_for_each_entry(i2o_dev, &c->devices, list)
105 if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) { 115 if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
106 if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1)) /* SCSI bus */ 116 if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
117 && (type == 0x01)) /* SCSI bus */
107 max_channel++; 118 max_channel++;
108 } 119 }
109 120
@@ -125,20 +136,18 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c)
125 scsi_host->max_id = i2o_scsi_max_id; 136 scsi_host->max_id = i2o_scsi_max_id;
126 scsi_host->max_lun = i2o_scsi_max_lun; 137 scsi_host->max_lun = i2o_scsi_max_lun;
127 scsi_host->this_id = c->unit; 138 scsi_host->this_id = c->unit;
128 139 scsi_host->sg_tablesize = i2o_sg_tablesize(c, body_size);
129 sb = c->status_block.virt;
130
131 scsi_host->sg_tablesize = (sb->inbound_frame_size -
132 sizeof(struct i2o_message) / 4 - 6) / 2;
133 140
134 i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata; 141 i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata;
135 i2o_shost->scsi_host = scsi_host; 142 i2o_shost->scsi_host = scsi_host;
136 i2o_shost->iop = c; 143 i2o_shost->iop = c;
144 i2o_shost->lun = 1;
137 145
138 i = 0; 146 i = 0;
139 list_for_each_entry(i2o_dev, &c->devices, list) 147 list_for_each_entry(i2o_dev, &c->devices, list)
140 if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) { 148 if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
141 if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1)) /* only SCSI bus */ 149 if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
150 && (type == 0x01)) /* only SCSI bus */
142 i2o_shost->channel[i++] = i2o_dev; 151 i2o_shost->channel[i++] = i2o_dev;
143 152
144 if (i >= max_channel) 153 if (i >= max_channel)
@@ -178,10 +187,13 @@ static int i2o_scsi_remove(struct device *dev)
178 struct i2o_scsi_host *i2o_shost; 187 struct i2o_scsi_host *i2o_shost;
179 struct scsi_device *scsi_dev; 188 struct scsi_device *scsi_dev;
180 189
190 osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
191
181 i2o_shost = i2o_scsi_get_host(c); 192 i2o_shost = i2o_scsi_get_host(c);
182 193
183 shost_for_each_device(scsi_dev, i2o_shost->scsi_host) 194 shost_for_each_device(scsi_dev, i2o_shost->scsi_host)
184 if (scsi_dev->hostdata == i2o_dev) { 195 if (scsi_dev->hostdata == i2o_dev) {
196 sysfs_remove_link(&i2o_dev->device.kobj, "scsi");
185 scsi_remove_device(scsi_dev); 197 scsi_remove_device(scsi_dev);
186 scsi_device_put(scsi_dev); 198 scsi_device_put(scsi_dev);
187 break; 199 break;
@@ -207,8 +219,8 @@ static int i2o_scsi_probe(struct device *dev)
207 struct Scsi_Host *scsi_host; 219 struct Scsi_Host *scsi_host;
208 struct i2o_device *parent; 220 struct i2o_device *parent;
209 struct scsi_device *scsi_dev; 221 struct scsi_device *scsi_dev;
210 u32 id; 222 u32 id = -1;
211 u64 lun; 223 u64 lun = -1;
212 int channel = -1; 224 int channel = -1;
213 int i; 225 int i;
214 226
@@ -218,8 +230,56 @@ static int i2o_scsi_probe(struct device *dev)
218 230
219 scsi_host = i2o_shost->scsi_host; 231 scsi_host = i2o_shost->scsi_host;
220 232
221 if (i2o_parm_field_get(i2o_dev, 0, 3, &id, 4) < 0) 233 switch (i2o_dev->lct_data.class_id) {
234 case I2O_CLASS_RANDOM_BLOCK_STORAGE:
235 case I2O_CLASS_EXECUTIVE:
236#ifdef CONFIG_I2O_EXT_ADAPTEC
237 if (c->adaptec) {
238 u8 type;
239 struct i2o_device *d = i2o_shost->channel[0];
240
241 if (i2o_parm_field_get(d, 0x0000, 0, &type, 1)
242 && (type == 0x01)) /* SCSI bus */
243 if (i2o_parm_field_get(d, 0x0200, 4, &id, 4)) {
244 channel = 0;
245 if (i2o_dev->lct_data.class_id ==
246 I2O_CLASS_RANDOM_BLOCK_STORAGE)
247 lun = i2o_shost->lun++;
248 else
249 lun = 0;
250 }
251 }
252#endif
253 break;
254
255 case I2O_CLASS_SCSI_PERIPHERAL:
256 if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4) < 0)
257 return -EFAULT;
258
259 if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8) < 0)
260 return -EFAULT;
261
262 parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
263 if (!parent) {
264 osm_warn("can not find parent of device %03x\n",
265 i2o_dev->lct_data.tid);
266 return -EFAULT;
267 }
268
269 for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++)
270 if (i2o_shost->channel[i] == parent)
271 channel = i;
272 break;
273
274 default:
222 return -EFAULT; 275 return -EFAULT;
276 }
277
278 if (channel == -1) {
279 osm_warn("can not find channel of device %03x\n",
280 i2o_dev->lct_data.tid);
281 return -EFAULT;
282 }
223 283
224 if (id >= scsi_host->max_id) { 284 if (id >= scsi_host->max_id) {
225 osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id, 285 osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id,
@@ -227,42 +287,26 @@ static int i2o_scsi_probe(struct device *dev)
227 return -EFAULT; 287 return -EFAULT;
228 } 288 }
229 289
230 if (i2o_parm_field_get(i2o_dev, 0, 4, &lun, 8) < 0)
231 return -EFAULT;
232 if (lun >= scsi_host->max_lun) { 290 if (lun >= scsi_host->max_lun) {
233 osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)", 291 osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)",
234 (unsigned int)lun, scsi_host->max_lun); 292 (unsigned int)lun, scsi_host->max_lun);
235 return -EFAULT; 293 return -EFAULT;
236 } 294 }
237 295
238 parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
239 if (!parent) {
240 osm_warn("can not find parent of device %03x\n",
241 i2o_dev->lct_data.tid);
242 return -EFAULT;
243 }
244
245 for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++)
246 if (i2o_shost->channel[i] == parent)
247 channel = i;
248
249 if (channel == -1) {
250 osm_warn("can not find channel of device %03x\n",
251 i2o_dev->lct_data.tid);
252 return -EFAULT;
253 }
254
255 scsi_dev = 296 scsi_dev =
256 __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev); 297 __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev);
257 298
258 if (!scsi_dev) { 299 if (IS_ERR(scsi_dev)) {
259 osm_warn("can not add SCSI device %03x\n", 300 osm_warn("can not add SCSI device %03x\n",
260 i2o_dev->lct_data.tid); 301 i2o_dev->lct_data.tid);
261 return -EFAULT; 302 return PTR_ERR(scsi_dev);
262 } 303 }
263 304
264 osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n", 305 sysfs_create_link(&i2o_dev->device.kobj, &scsi_dev->sdev_gendev.kobj,
265 i2o_dev->lct_data.tid, channel, id, (unsigned int)lun); 306 "scsi");
307
308 osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %d\n",
309 i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
266 310
267 return 0; 311 return 0;
268}; 312};
@@ -293,162 +337,89 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
293 struct i2o_message *msg) 337 struct i2o_message *msg)
294{ 338{
295 struct scsi_cmnd *cmd; 339 struct scsi_cmnd *cmd;
340 u32 error;
296 struct device *dev; 341 struct device *dev;
297 u8 as, ds, st;
298 342
299 cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt)); 343 cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
300 344 if (unlikely(!cmd)) {
301 if (msg->u.head[0] & (1 << 13)) { 345 osm_err("NULL reply received!\n");
302 struct i2o_message __iomem *pmsg; /* preserved message */ 346 return -1;
303 u32 pm;
304 int err = DID_ERROR;
305
306 pm = le32_to_cpu(msg->body[3]);
307
308 pmsg = i2o_msg_in_to_virt(c, pm);
309
310 osm_err("IOP fail.\n");
311 osm_err("From %d To %d Cmd %d.\n",
312 (msg->u.head[1] >> 12) & 0xFFF,
313 msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
314 osm_err("Failure Code %d.\n", msg->body[0] >> 24);
315 if (msg->body[0] & (1 << 16))
316 osm_err("Format error.\n");
317 if (msg->body[0] & (1 << 17))
318 osm_err("Path error.\n");
319 if (msg->body[0] & (1 << 18))
320 osm_err("Path State.\n");
321 if (msg->body[0] & (1 << 18))
322 {
323 osm_err("Congestion.\n");
324 err = DID_BUS_BUSY;
325 }
326
327 osm_debug("Failing message is %p.\n", pmsg);
328
329 cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt));
330 if (!cmd)
331 return 1;
332
333 cmd->result = err << 16;
334 cmd->scsi_done(cmd);
335
336 /* Now flush the message by making it a NOP */
337 i2o_msg_nop(c, pm);
338
339 return 1;
340 } 347 }
341 348
342 /* 349 /*
343 * Low byte is device status, next is adapter status, 350 * Low byte is device status, next is adapter status,
344 * (then one byte reserved), then request status. 351 * (then one byte reserved), then request status.
345 */ 352 */
346 ds = (u8) le32_to_cpu(msg->body[0]); 353 error = le32_to_cpu(msg->body[0]);
347 as = (u8) (le32_to_cpu(msg->body[0]) >> 8); 354
348 st = (u8) (le32_to_cpu(msg->body[0]) >> 24); 355 osm_debug("Completed %ld\n", cmd->serial_number);
349 356
357 cmd->result = error & 0xff;
350 /* 358 /*
351 * Is this a control request coming back - eg an abort ? 359 * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let
360 * the SCSI layer handle the error
352 */ 361 */
362 if (cmd->result)
363 memcpy(cmd->sense_buffer, &msg->body[3],
364 min(sizeof(cmd->sense_buffer), (size_t) 40));
353 365
354 if (!cmd) { 366 /* only output error code if AdapterStatus is not HBA_SUCCESS */
355 if (st) 367 if ((error >> 8) & 0xff)
356 osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0])); 368 osm_err("SCSI error %08x\n", error);
357 osm_info("SCSI abort completed.\n");
358 return -EFAULT;
359 }
360 369
361 osm_debug("Completed %ld\n", cmd->serial_number); 370 dev = &c->pdev->dev;
371 if (cmd->use_sg)
372 dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg,
373 cmd->sc_data_direction);
374 else if (cmd->SCp.dma_handle)
375 dma_unmap_single(dev, cmd->SCp.dma_handle, cmd->request_bufflen,
376 cmd->sc_data_direction);
362 377
363 if (st) { 378 cmd->scsi_done(cmd);
364 u32 count, error;
365 /* An error has occurred */
366
367 switch (st) {
368 case 0x06:
369 count = le32_to_cpu(msg->body[1]);
370 if (count < cmd->underflow) {
371 int i;
372
373 osm_err("SCSI underflow 0x%08X 0x%08X\n", count,
374 cmd->underflow);
375 osm_debug("Cmd: ");
376 for (i = 0; i < 15; i++)
377 pr_debug("%02X ", cmd->cmnd[i]);
378 pr_debug(".\n");
379 cmd->result = (DID_ERROR << 16);
380 }
381 break;
382 379
383 default: 380 return 1;
384 error = le32_to_cpu(msg->body[0]); 381};
385
386 osm_err("SCSI error %08x\n", error);
387
388 if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) {
389 int i;
390 u32 len = sizeof(cmd->sense_buffer);
391 len = (len > 40) ? 40 : len;
392 // Copy over the sense data
393 memcpy(cmd->sense_buffer, (void *)&msg->body[3],
394 len);
395 for (i = 0; i <= len; i++)
396 osm_info("%02x\n",
397 cmd->sense_buffer[i]);
398 if (cmd->sense_buffer[0] == 0x70
399 && cmd->sense_buffer[2] == DATA_PROTECT) {
400 /* This is to handle an array failed */
401 cmd->result = (DID_TIME_OUT << 16);
402 printk(KERN_WARNING "%s: SCSI Data "
403 "Protect-Device (%d,%d,%d) "
404 "hba_status=0x%x, dev_status="
405 "0x%x, cmd=0x%x\n", c->name,
406 (u32) cmd->device->channel,
407 (u32) cmd->device->id,
408 (u32) cmd->device->lun,
409 (error >> 8) & 0xff,
410 error & 0xff, cmd->cmnd[0]);
411 } else
412 cmd->result = (DID_ERROR << 16);
413
414 break;
415 }
416
417 switch (as) {
418 case 0x0E:
419 /* SCSI Reset */
420 cmd->result = DID_RESET << 16;
421 break;
422
423 case 0x0F:
424 cmd->result = DID_PARITY << 16;
425 break;
426
427 default:
428 cmd->result = DID_ERROR << 16;
429 break;
430 }
431 382
432 break; 383/**
433 } 384 * i2o_scsi_notify_device_add - Retrieve notifications of added devices
385 * @i2o_dev: the I2O device which was added
386 *
387 * If a I2O device is added we catch the notification, because I2O classes
388 * other then SCSI peripheral will not be received through
389 * i2o_scsi_probe().
390 */
391static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev)
392{
393 switch (i2o_dev->lct_data.class_id) {
394 case I2O_CLASS_EXECUTIVE:
395 case I2O_CLASS_RANDOM_BLOCK_STORAGE:
396 i2o_scsi_probe(&i2o_dev->device);
397 break;
434 398
435 cmd->scsi_done(cmd); 399 default:
436 return 1; 400 break;
437 } 401 }
402};
438 403
439 cmd->result = DID_OK << 16 | ds; 404/**
440 405 * i2o_scsi_notify_device_remove - Retrieve notifications of removed
441 cmd->scsi_done(cmd); 406 * devices
442 407 * @i2o_dev: the I2O device which was removed
443 dev = &c->pdev->dev; 408 *
444 if (cmd->use_sg) 409 * If a I2O device is removed, we catch the notification to remove the
445 dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer, 410 * corresponding SCSI device.
446 cmd->use_sg, cmd->sc_data_direction); 411 */
447 else if (cmd->request_bufflen) 412static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev)
448 dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr), 413{
449 cmd->request_bufflen, cmd->sc_data_direction); 414 switch (i2o_dev->lct_data.class_id) {
415 case I2O_CLASS_EXECUTIVE:
416 case I2O_CLASS_RANDOM_BLOCK_STORAGE:
417 i2o_scsi_remove(&i2o_dev->device);
418 break;
450 419
451 return 1; 420 default:
421 break;
422 }
452}; 423};
453 424
454/** 425/**
@@ -501,7 +472,7 @@ static void i2o_scsi_notify_controller_remove(struct i2o_controller *c)
501 472
502 scsi_remove_host(i2o_shost->scsi_host); 473 scsi_remove_host(i2o_shost->scsi_host);
503 scsi_host_put(i2o_shost->scsi_host); 474 scsi_host_put(i2o_shost->scsi_host);
504 pr_info("I2O SCSI host removed\n"); 475 osm_debug("I2O SCSI host removed\n");
505}; 476};
506 477
507/* SCSI OSM driver struct */ 478/* SCSI OSM driver struct */
@@ -509,6 +480,8 @@ static struct i2o_driver i2o_scsi_driver = {
509 .name = OSM_NAME, 480 .name = OSM_NAME,
510 .reply = i2o_scsi_reply, 481 .reply = i2o_scsi_reply,
511 .classes = i2o_scsi_class_id, 482 .classes = i2o_scsi_class_id,
483 .notify_device_add = i2o_scsi_notify_device_add,
484 .notify_device_remove = i2o_scsi_notify_device_remove,
512 .notify_controller_add = i2o_scsi_notify_controller_add, 485 .notify_controller_add = i2o_scsi_notify_controller_add,
513 .notify_controller_remove = i2o_scsi_notify_controller_remove, 486 .notify_controller_remove = i2o_scsi_notify_controller_remove,
514 .driver = { 487 .driver = {
@@ -535,26 +508,26 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
535 void (*done) (struct scsi_cmnd *)) 508 void (*done) (struct scsi_cmnd *))
536{ 509{
537 struct i2o_controller *c; 510 struct i2o_controller *c;
538 struct Scsi_Host *host;
539 struct i2o_device *i2o_dev; 511 struct i2o_device *i2o_dev;
540 struct device *dev;
541 int tid; 512 int tid;
542 struct i2o_message __iomem *msg; 513 struct i2o_message __iomem *msg;
543 u32 m; 514 u32 m;
544 u32 scsi_flags, sg_flags; 515 /*
516 * ENABLE_DISCONNECT
517 * SIMPLE_TAG
518 * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
519 */
520 u32 scsi_flags = 0x20a00000;
521 u32 sgl_offset;
545 u32 __iomem *mptr; 522 u32 __iomem *mptr;
546 u32 __iomem *lenptr; 523 u32 cmd = I2O_CMD_SCSI_EXEC << 24;
547 u32 len, reqlen; 524 int rc = 0;
548 int i;
549 525
550 /* 526 /*
551 * Do the incoming paperwork 527 * Do the incoming paperwork
552 */ 528 */
553
554 i2o_dev = SCpnt->device->hostdata; 529 i2o_dev = SCpnt->device->hostdata;
555 host = SCpnt->device->host;
556 c = i2o_dev->iop; 530 c = i2o_dev->iop;
557 dev = &c->pdev->dev;
558 531
559 SCpnt->scsi_done = done; 532 SCpnt->scsi_done = done;
560 533
@@ -562,7 +535,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
562 osm_warn("no I2O device in request\n"); 535 osm_warn("no I2O device in request\n");
563 SCpnt->result = DID_NO_CONNECT << 16; 536 SCpnt->result = DID_NO_CONNECT << 16;
564 done(SCpnt); 537 done(SCpnt);
565 return 0; 538 goto exit;
566 } 539 }
567 540
568 tid = i2o_dev->lct_data.tid; 541 tid = i2o_dev->lct_data.tid;
@@ -571,44 +544,85 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
571 osm_debug("Real scsi messages.\n"); 544 osm_debug("Real scsi messages.\n");
572 545
573 /* 546 /*
574 * Obtain an I2O message. If there are none free then
575 * throw it back to the scsi layer
576 */
577
578 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
579 if (m == I2O_QUEUE_EMPTY)
580 return SCSI_MLQUEUE_HOST_BUSY;
581
582 /*
583 * Put together a scsi execscb message 547 * Put together a scsi execscb message
584 */ 548 */
585
586 len = SCpnt->request_bufflen;
587
588 switch (SCpnt->sc_data_direction) { 549 switch (SCpnt->sc_data_direction) {
589 case PCI_DMA_NONE: 550 case PCI_DMA_NONE:
590 scsi_flags = 0x00000000; // DATA NO XFER 551 /* DATA NO XFER */
591 sg_flags = 0x00000000; 552 sgl_offset = SGL_OFFSET_0;
592 break; 553 break;
593 554
594 case PCI_DMA_TODEVICE: 555 case PCI_DMA_TODEVICE:
595 scsi_flags = 0x80000000; // DATA OUT (iop-->dev) 556 /* DATA OUT (iop-->dev) */
596 sg_flags = 0x14000000; 557 scsi_flags |= 0x80000000;
558 sgl_offset = SGL_OFFSET_10;
597 break; 559 break;
598 560
599 case PCI_DMA_FROMDEVICE: 561 case PCI_DMA_FROMDEVICE:
600 scsi_flags = 0x40000000; // DATA IN (iop<--dev) 562 /* DATA IN (iop<--dev) */
601 sg_flags = 0x10000000; 563 scsi_flags |= 0x40000000;
564 sgl_offset = SGL_OFFSET_10;
602 break; 565 break;
603 566
604 default: 567 default:
605 /* Unknown - kill the command */ 568 /* Unknown - kill the command */
606 SCpnt->result = DID_NO_CONNECT << 16; 569 SCpnt->result = DID_NO_CONNECT << 16;
607 done(SCpnt); 570 done(SCpnt);
608 return 0; 571 goto exit;
609 } 572 }
610 573
611 writel(I2O_CMD_SCSI_EXEC << 24 | HOST_TID << 12 | tid, &msg->u.head[1]); 574 /*
575 * Obtain an I2O message. If there are none free then
576 * throw it back to the scsi layer
577 */
578
579 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
580 if (m == I2O_QUEUE_EMPTY) {
581 rc = SCSI_MLQUEUE_HOST_BUSY;
582 goto exit;
583 }
584
585 mptr = &msg->body[0];
586
587#ifdef CONFIG_I2O_EXT_ADAPTEC
588 if (c->adaptec) {
589 u32 adpt_flags = 0;
590
591 if (SCpnt->sc_request && SCpnt->sc_request->upper_private_data) {
592 i2o_sg_io_hdr_t __user *usr_ptr =
593 ((Sg_request *) (SCpnt->sc_request->
594 upper_private_data))->header.
595 usr_ptr;
596
597 if (usr_ptr)
598 get_user(adpt_flags, &usr_ptr->flags);
599 }
600
601 switch (i2o_dev->lct_data.class_id) {
602 case I2O_CLASS_EXECUTIVE:
603 case I2O_CLASS_RANDOM_BLOCK_STORAGE:
604 /* interpret flag has to be set for executive */
605 adpt_flags ^= I2O_DPT_SG_FLAG_INTERPRET;
606 break;
607
608 default:
609 break;
610 }
611
612 /*
613 * for Adaptec controllers we use the PRIVATE command, because
614 * the normal SCSI EXEC doesn't support all SCSI commands on
615 * all controllers (for example READ CAPACITY).
616 */
617 if (sgl_offset == SGL_OFFSET_10)
618 sgl_offset = SGL_OFFSET_12;
619 cmd = I2O_CMD_PRIVATE << 24;
620 writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
621 writel(adpt_flags | tid, mptr++);
622 }
623#endif
624
625 writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
612 writel(i2o_scsi_driver.context, &msg->u.s.icntxt); 626 writel(i2o_scsi_driver.context, &msg->u.s.icntxt);
613 627
614 /* We want the SCSI control block back */ 628 /* We want the SCSI control block back */
@@ -626,7 +640,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
626 */ 640 */
627 641
628 /* Attach tags to the devices */ 642 /* Attach tags to the devices */
629 /* 643 /* FIXME: implement
630 if(SCpnt->device->tagged_supported) { 644 if(SCpnt->device->tagged_supported) {
631 if(SCpnt->tag == HEAD_OF_QUEUE_TAG) 645 if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
632 scsi_flags |= 0x01000000; 646 scsi_flags |= 0x01000000;
@@ -635,67 +649,35 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
635 } 649 }
636 */ 650 */
637 651
638 /* Direction, disconnect ok, tag, CDBLen */ 652 writel(scsi_flags | SCpnt->cmd_len, mptr++);
639 writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, &msg->body[0]);
640
641 mptr = &msg->body[1];
642 653
643 /* Write SCSI command into the message - always 16 byte block */ 654 /* Write SCSI command into the message - always 16 byte block */
644 memcpy_toio(mptr, SCpnt->cmnd, 16); 655 memcpy_toio(mptr, SCpnt->cmnd, 16);
645 mptr += 4; 656 mptr += 4;
646 lenptr = mptr++; /* Remember me - fill in when we know */
647
648 reqlen = 12; // SINGLE SGE
649
650 /* Now fill in the SGList and command */
651 if (SCpnt->use_sg) {
652 struct scatterlist *sg;
653 int sg_count;
654
655 sg = SCpnt->request_buffer;
656 len = 0;
657
658 sg_count = dma_map_sg(dev, sg, SCpnt->use_sg,
659 SCpnt->sc_data_direction);
660 657
661 if (unlikely(sg_count <= 0)) 658 if (sgl_offset != SGL_OFFSET_0) {
662 return -ENOMEM; 659 /* write size of data addressed by SGL */
663 660 writel(SCpnt->request_bufflen, mptr++);
664 for (i = SCpnt->use_sg; i > 0; i--) { 661
665 if (i == 1) 662 /* Now fill in the SGList and command */
666 sg_flags |= 0xC0000000; 663 if (SCpnt->use_sg) {
667 writel(sg_flags | sg_dma_len(sg), mptr++); 664 if (!i2o_dma_map_sg(c, SCpnt->request_buffer,
668 writel(sg_dma_address(sg), mptr++); 665 SCpnt->use_sg,
669 len += sg_dma_len(sg); 666 SCpnt->sc_data_direction, &mptr))
670 sg++; 667 goto nomem;
668 } else {
669 SCpnt->SCp.dma_handle =
670 i2o_dma_map_single(c, SCpnt->request_buffer,
671 SCpnt->request_bufflen,
672 SCpnt->sc_data_direction, &mptr);
673 if (dma_mapping_error(SCpnt->SCp.dma_handle))
674 goto nomem;
671 } 675 }
672
673 reqlen = mptr - &msg->u.head[0];
674 writel(len, lenptr);
675 } else {
676 len = SCpnt->request_bufflen;
677
678 writel(len, lenptr);
679
680 if (len > 0) {
681 dma_addr_t dma_addr;
682
683 dma_addr = dma_map_single(dev, SCpnt->request_buffer,
684 SCpnt->request_bufflen,
685 SCpnt->sc_data_direction);
686 if (!dma_addr)
687 return -ENOMEM;
688
689 SCpnt->SCp.ptr = (void *)(unsigned long)dma_addr;
690 sg_flags |= 0xC0000000;
691 writel(sg_flags | SCpnt->request_bufflen, mptr++);
692 writel(dma_addr, mptr++);
693 } else
694 reqlen = 9;
695 } 676 }
696 677
697 /* Stick the headers on */ 678 /* Stick the headers on */
698 writel(reqlen << 16 | SGL_OFFSET_10, &msg->u.head[0]); 679 writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset,
680 &msg->u.head[0]);
699 681
700 /* Queue the message */ 682 /* Queue the message */
701 i2o_msg_post(c, m); 683 i2o_msg_post(c, m);
@@ -703,6 +685,13 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
703 osm_debug("Issued %ld\n", SCpnt->serial_number); 685 osm_debug("Issued %ld\n", SCpnt->serial_number);
704 686
705 return 0; 687 return 0;
688
689 nomem:
690 rc = -ENOMEM;
691 i2o_msg_nop(c, m);
692
693 exit:
694 return rc;
706}; 695};
707 696
708/** 697/**
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 50c8cedf7a2d..42f8b810d6e5 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -28,8 +28,10 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/i2o.h> 29#include <linux/i2o.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include "core.h"
31 32
32#define OSM_VERSION "$Rev$" 33#define OSM_NAME "i2o"
34#define OSM_VERSION "1.288"
33#define OSM_DESCRIPTION "I2O subsystem" 35#define OSM_DESCRIPTION "I2O subsystem"
34 36
35/* global I2O controller list */ 37/* global I2O controller list */
@@ -43,20 +45,6 @@ static struct i2o_dma i2o_systab;
43 45
44static int i2o_hrt_get(struct i2o_controller *c); 46static int i2o_hrt_get(struct i2o_controller *c);
45 47
46/* Module internal functions from other sources */
47extern struct i2o_driver i2o_exec_driver;
48extern int i2o_exec_lct_get(struct i2o_controller *);
49extern void i2o_device_remove(struct i2o_device *);
50
51extern int __init i2o_driver_init(void);
52extern void __exit i2o_driver_exit(void);
53extern int __init i2o_exec_init(void);
54extern void __exit i2o_exec_exit(void);
55extern int __init i2o_pci_init(void);
56extern void __exit i2o_pci_exit(void);
57extern int i2o_device_init(void);
58extern void i2o_device_exit(void);
59
60/** 48/**
61 * i2o_msg_nop - Returns a message which is not used 49 * i2o_msg_nop - Returns a message which is not used
62 * @c: I2O controller from which the message was created 50 * @c: I2O controller from which the message was created
@@ -68,7 +56,7 @@ extern void i2o_device_exit(void);
68 */ 56 */
69void i2o_msg_nop(struct i2o_controller *c, u32 m) 57void i2o_msg_nop(struct i2o_controller *c, u32 m)
70{ 58{
71 struct i2o_message __iomem *msg = c->in_queue.virt + m; 59 struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
72 60
73 writel(THREE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]); 61 writel(THREE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
74 writel(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID, 62 writel(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID,
@@ -92,16 +80,16 @@ void i2o_msg_nop(struct i2o_controller *c, u32 m)
92 * address from the read port (see the i2o spec). If no message is 80 * address from the read port (see the i2o spec). If no message is
93 * available returns I2O_QUEUE_EMPTY and msg is leaved untouched. 81 * available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
94 */ 82 */
95u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message __iomem **msg, 83u32 i2o_msg_get_wait(struct i2o_controller *c,
96 int wait) 84 struct i2o_message __iomem ** msg, int wait)
97{ 85{
98 unsigned long timeout = jiffies + wait * HZ; 86 unsigned long timeout = jiffies + wait * HZ;
99 u32 m; 87 u32 m;
100 88
101 while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) { 89 while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) {
102 if (time_after(jiffies, timeout)) { 90 if (time_after(jiffies, timeout)) {
103 pr_debug("%s: Timeout waiting for message frame.\n", 91 osm_debug("%s: Timeout waiting for message frame.\n",
104 c->name); 92 c->name);
105 return I2O_QUEUE_EMPTY; 93 return I2O_QUEUE_EMPTY;
106 } 94 }
107 set_current_state(TASK_UNINTERRUPTIBLE); 95 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -129,13 +117,13 @@ u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr)
129 unsigned long flags; 117 unsigned long flags;
130 118
131 if (!ptr) 119 if (!ptr)
132 printk(KERN_ERR "%s: couldn't add NULL pointer to context list!" 120 osm_err("%s: couldn't add NULL pointer to context list!\n",
133 "\n", c->name); 121 c->name);
134 122
135 entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 123 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
136 if (!entry) { 124 if (!entry) {
137 printk(KERN_ERR "%s: Could not allocate memory for context " 125 osm_err("%s: Could not allocate memory for context list element"
138 "list element\n", c->name); 126 "\n", c->name);
139 return 0; 127 return 0;
140 } 128 }
141 129
@@ -154,7 +142,7 @@ u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr)
154 142
155 spin_unlock_irqrestore(&c->context_list_lock, flags); 143 spin_unlock_irqrestore(&c->context_list_lock, flags);
156 144
157 pr_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context); 145 osm_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
158 146
159 return entry->context; 147 return entry->context;
160}; 148};
@@ -186,11 +174,11 @@ u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr)
186 spin_unlock_irqrestore(&c->context_list_lock, flags); 174 spin_unlock_irqrestore(&c->context_list_lock, flags);
187 175
188 if (!context) 176 if (!context)
189 printk(KERN_WARNING "%s: Could not remove nonexistent ptr " 177 osm_warn("%s: Could not remove nonexistent ptr %p\n", c->name,
190 "%p\n", c->name, ptr); 178 ptr);
191 179
192 pr_debug("%s: remove ptr from context list %d -> %p\n", c->name, 180 osm_debug("%s: remove ptr from context list %d -> %p\n", c->name,
193 context, ptr); 181 context, ptr);
194 182
195 return context; 183 return context;
196}; 184};
@@ -220,11 +208,10 @@ void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
220 spin_unlock_irqrestore(&c->context_list_lock, flags); 208 spin_unlock_irqrestore(&c->context_list_lock, flags);
221 209
222 if (!ptr) 210 if (!ptr)
223 printk(KERN_WARNING "%s: context id %d not found\n", c->name, 211 osm_warn("%s: context id %d not found\n", c->name, context);
224 context);
225 212
226 pr_debug("%s: get ptr from context list %d -> %p\n", c->name, context, 213 osm_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
227 ptr); 214 ptr);
228 215
229 return ptr; 216 return ptr;
230}; 217};
@@ -252,11 +239,11 @@ u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr)
252 spin_unlock_irqrestore(&c->context_list_lock, flags); 239 spin_unlock_irqrestore(&c->context_list_lock, flags);
253 240
254 if (!context) 241 if (!context)
255 printk(KERN_WARNING "%s: Could not find nonexistent ptr " 242 osm_warn("%s: Could not find nonexistent ptr %p\n", c->name,
256 "%p\n", c->name, ptr); 243 ptr);
257 244
258 pr_debug("%s: get context id from context list %p -> %d\n", c->name, 245 osm_debug("%s: get context id from context list %p -> %d\n", c->name,
259 ptr, context); 246 ptr, context);
260 247
261 return context; 248 return context;
262}; 249};
@@ -336,10 +323,9 @@ static int i2o_iop_quiesce(struct i2o_controller *c)
336 323
337 /* Long timeout needed for quiesce if lots of devices */ 324 /* Long timeout needed for quiesce if lots of devices */
338 if ((rc = i2o_msg_post_wait(c, m, 240))) 325 if ((rc = i2o_msg_post_wait(c, m, 240)))
339 printk(KERN_INFO "%s: Unable to quiesce (status=%#x).\n", 326 osm_info("%s: Unable to quiesce (status=%#x).\n", c->name, -rc);
340 c->name, -rc);
341 else 327 else
342 pr_debug("%s: Quiesced.\n", c->name); 328 osm_debug("%s: Quiesced.\n", c->name);
343 329
344 i2o_status_get(c); // Entered READY state 330 i2o_status_get(c); // Entered READY state
345 331
@@ -377,10 +363,9 @@ static int i2o_iop_enable(struct i2o_controller *c)
377 363
378 /* How long of a timeout do we need? */ 364 /* How long of a timeout do we need? */
379 if ((rc = i2o_msg_post_wait(c, m, 240))) 365 if ((rc = i2o_msg_post_wait(c, m, 240)))
380 printk(KERN_ERR "%s: Could not enable (status=%#x).\n", 366 osm_err("%s: Could not enable (status=%#x).\n", c->name, -rc);
381 c->name, -rc);
382 else 367 else
383 pr_debug("%s: Enabled.\n", c->name); 368 osm_debug("%s: Enabled.\n", c->name);
384 369
385 i2o_status_get(c); // entered OPERATIONAL state 370 i2o_status_get(c); // entered OPERATIONAL state
386 371
@@ -444,20 +429,78 @@ static int i2o_iop_clear(struct i2o_controller *c)
444 &msg->u.head[1]); 429 &msg->u.head[1]);
445 430
446 if ((rc = i2o_msg_post_wait(c, m, 30))) 431 if ((rc = i2o_msg_post_wait(c, m, 30)))
447 printk(KERN_INFO "%s: Unable to clear (status=%#x).\n", 432 osm_info("%s: Unable to clear (status=%#x).\n", c->name, -rc);
448 c->name, -rc);
449 else 433 else
450 pr_debug("%s: Cleared.\n", c->name); 434 osm_debug("%s: Cleared.\n", c->name);
451 435
452 /* Enable all IOPs */ 436 /* Enable all IOPs */
453 i2o_iop_enable_all(); 437 i2o_iop_enable_all();
454 438
455 i2o_status_get(c);
456
457 return rc; 439 return rc;
458} 440}
459 441
460/** 442/**
443 * i2o_iop_init_outbound_queue - setup the outbound message queue
444 * @c: I2O controller
445 *
446 * Clear and (re)initialize IOP's outbound queue and post the message
447 * frames to the IOP.
448 *
449 * Returns 0 on success or a negative errno code on failure.
450 */
451static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
452{
453 volatile u8 *status = c->status.virt;
454 u32 m;
455 struct i2o_message __iomem *msg;
456 ulong timeout;
457 int i;
458
459 osm_debug("%s: Initializing Outbound Queue...\n", c->name);
460
461 memset(c->status.virt, 0, 4);
462
463 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
464 if (m == I2O_QUEUE_EMPTY)
465 return -ETIMEDOUT;
466
467 writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);
468 writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
469 &msg->u.head[1]);
470 writel(i2o_exec_driver.context, &msg->u.s.icntxt);
471 writel(0x00000000, &msg->u.s.tcntxt);
472 writel(PAGE_SIZE, &msg->body[0]);
473 /* Outbound msg frame size in words and Initcode */
474 writel(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]);
475 writel(0xd0000004, &msg->body[2]);
476 writel(i2o_dma_low(c->status.phys), &msg->body[3]);
477 writel(i2o_dma_high(c->status.phys), &msg->body[4]);
478
479 i2o_msg_post(c, m);
480
481 timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
482 while (*status <= I2O_CMD_IN_PROGRESS) {
483 if (time_after(jiffies, timeout)) {
484 osm_warn("%s: Timeout Initializing\n", c->name);
485 return -ETIMEDOUT;
486 }
487 set_current_state(TASK_UNINTERRUPTIBLE);
488 schedule_timeout(1);
489 }
490
491 m = c->out_queue.phys;
492
493 /* Post frames */
494 for (i = 0; i < I2O_MAX_OUTBOUND_MSG_FRAMES; i++) {
495 i2o_flush_reply(c, m);
496 udelay(1); /* Promise */
497 m += I2O_OUTBOUND_MSG_FRAME_SIZE * sizeof(u32);
498 }
499
500 return 0;
501}
502
503/**
461 * i2o_iop_reset - reset an I2O controller 504 * i2o_iop_reset - reset an I2O controller
462 * @c: controller to reset 505 * @c: controller to reset
463 * 506 *
@@ -468,20 +511,20 @@ static int i2o_iop_clear(struct i2o_controller *c)
468 */ 511 */
469static int i2o_iop_reset(struct i2o_controller *c) 512static int i2o_iop_reset(struct i2o_controller *c)
470{ 513{
471 u8 *status = c->status.virt; 514 volatile u8 *status = c->status.virt;
472 struct i2o_message __iomem *msg; 515 struct i2o_message __iomem *msg;
473 u32 m; 516 u32 m;
474 unsigned long timeout; 517 unsigned long timeout;
475 i2o_status_block *sb = c->status_block.virt; 518 i2o_status_block *sb = c->status_block.virt;
476 int rc = 0; 519 int rc = 0;
477 520
478 pr_debug("%s: Resetting controller\n", c->name); 521 osm_debug("%s: Resetting controller\n", c->name);
479 522
480 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); 523 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
481 if (m == I2O_QUEUE_EMPTY) 524 if (m == I2O_QUEUE_EMPTY)
482 return -ETIMEDOUT; 525 return -ETIMEDOUT;
483 526
484 memset(status, 0, 8); 527 memset(c->status_block.virt, 0, 8);
485 528
486 /* Quiesce all IOPs first */ 529 /* Quiesce all IOPs first */
487 i2o_iop_quiesce_all(); 530 i2o_iop_quiesce_all();
@@ -493,49 +536,43 @@ static int i2o_iop_reset(struct i2o_controller *c)
493 writel(0, &msg->u.s.tcntxt); //FIXME: use reasonable transaction context 536 writel(0, &msg->u.s.tcntxt); //FIXME: use reasonable transaction context
494 writel(0, &msg->body[0]); 537 writel(0, &msg->body[0]);
495 writel(0, &msg->body[1]); 538 writel(0, &msg->body[1]);
496 writel(i2o_ptr_low((void *)c->status.phys), &msg->body[2]); 539 writel(i2o_dma_low(c->status.phys), &msg->body[2]);
497 writel(i2o_ptr_high((void *)c->status.phys), &msg->body[3]); 540 writel(i2o_dma_high(c->status.phys), &msg->body[3]);
498 541
499 i2o_msg_post(c, m); 542 i2o_msg_post(c, m);
500 543
501 /* Wait for a reply */ 544 /* Wait for a reply */
502 timeout = jiffies + I2O_TIMEOUT_RESET * HZ; 545 timeout = jiffies + I2O_TIMEOUT_RESET * HZ;
503 while (!*status) { 546 while (!*status) {
504 if (time_after(jiffies, timeout)) { 547 if (time_after(jiffies, timeout))
505 printk(KERN_ERR "%s: IOP reset timeout.\n", c->name);
506 rc = -ETIMEDOUT;
507 goto exit;
508 }
509
510 /* Promise bug */
511 if (status[1] || status[4]) {
512 *status = 0;
513 break; 548 break;
514 }
515 549
516 set_current_state(TASK_UNINTERRUPTIBLE); 550 set_current_state(TASK_UNINTERRUPTIBLE);
517 schedule_timeout(1); 551 schedule_timeout(1);
518
519 rmb();
520 } 552 }
521 553
522 if (*status == I2O_CMD_IN_PROGRESS) { 554 switch (*status) {
555 case I2O_CMD_REJECTED:
556 osm_warn("%s: IOP reset rejected\n", c->name);
557 rc = -EPERM;
558 break;
559
560 case I2O_CMD_IN_PROGRESS:
523 /* 561 /*
524 * Once the reset is sent, the IOP goes into the INIT state 562 * Once the reset is sent, the IOP goes into the INIT state
525 * which is indeterminate. We need to wait until the IOP 563 * which is indeterminate. We need to wait until the IOP has
526 * has rebooted before we can let the system talk to 564 * rebooted before we can let the system talk to it. We read
527 * it. We read the inbound Free_List until a message is 565 * the inbound Free_List until a message is available. If we
528 * available. If we can't read one in the given ammount of 566 * can't read one in the given ammount of time, we assume the
529 * time, we assume the IOP could not reboot properly. 567 * IOP could not reboot properly.
530 */ 568 */
531 pr_debug("%s: Reset in progress, waiting for reboot...\n", 569 osm_debug("%s: Reset in progress, waiting for reboot...\n",
532 c->name); 570 c->name);
533 571
534 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET); 572 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
535 while (m == I2O_QUEUE_EMPTY) { 573 while (m == I2O_QUEUE_EMPTY) {
536 if (time_after(jiffies, timeout)) { 574 if (time_after(jiffies, timeout)) {
537 printk(KERN_ERR "%s: IOP reset timeout.\n", 575 osm_err("%s: IOP reset timeout.\n", c->name);
538 c->name);
539 rc = -ETIMEDOUT; 576 rc = -ETIMEDOUT;
540 goto exit; 577 goto exit;
541 } 578 }
@@ -545,19 +582,26 @@ static int i2o_iop_reset(struct i2o_controller *c)
545 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET); 582 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
546 } 583 }
547 i2o_msg_nop(c, m); 584 i2o_msg_nop(c, m);
548 }
549 585
550 /* from here all quiesce commands are safe */ 586 /* from here all quiesce commands are safe */
551 c->no_quiesce = 0; 587 c->no_quiesce = 0;
552 588
553 /* If IopReset was rejected or didn't perform reset, try IopClear */ 589 /* verify if controller is in state RESET */
554 i2o_status_get(c); 590 i2o_status_get(c);
555 if (*status == I2O_CMD_REJECTED || sb->iop_state != ADAPTER_STATE_RESET) { 591
556 printk(KERN_WARNING "%s: Reset rejected, trying to clear\n", 592 if (!c->promise && (sb->iop_state != ADAPTER_STATE_RESET))
557 c->name); 593 osm_warn("%s: reset completed, but adapter not in RESET"
558 i2o_iop_clear(c); 594 " state.\n", c->name);
559 } else 595 else
560 pr_debug("%s: Reset completed.\n", c->name); 596 osm_debug("%s: reset completed.\n", c->name);
597
598 break;
599
600 default:
601 osm_err("%s: IOP reset timeout.\n", c->name);
602 rc = -ETIMEDOUT;
603 break;
604 }
561 605
562 exit: 606 exit:
563 /* Enable all IOPs */ 607 /* Enable all IOPs */
@@ -567,88 +611,6 @@ static int i2o_iop_reset(struct i2o_controller *c)
567}; 611};
568 612
569/** 613/**
570 * i2o_iop_init_outbound_queue - setup the outbound message queue
571 * @c: I2O controller
572 *
573 * Clear and (re)initialize IOP's outbound queue and post the message
574 * frames to the IOP.
575 *
576 * Returns 0 on success or a negative errno code on failure.
577 */
578static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
579{
580 u8 *status = c->status.virt;
581 u32 m;
582 struct i2o_message __iomem *msg;
583 ulong timeout;
584 int i;
585
586 pr_debug("%s: Initializing Outbound Queue...\n", c->name);
587
588 memset(status, 0, 4);
589
590 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
591 if (m == I2O_QUEUE_EMPTY)
592 return -ETIMEDOUT;
593
594 writel(EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6, &msg->u.head[0]);
595 writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
596 &msg->u.head[1]);
597 writel(i2o_exec_driver.context, &msg->u.s.icntxt);
598 writel(0x0106, &msg->u.s.tcntxt); /* FIXME: why 0x0106, maybe in
599 Spec? */
600 writel(PAGE_SIZE, &msg->body[0]);
601 writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]); /* Outbound msg frame
602 size in words and Initcode */
603 writel(0xd0000004, &msg->body[2]);
604 writel(i2o_ptr_low((void *)c->status.phys), &msg->body[3]);
605 writel(i2o_ptr_high((void *)c->status.phys), &msg->body[4]);
606
607 i2o_msg_post(c, m);
608
609 timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
610 while (*status <= I2O_CMD_IN_PROGRESS) {
611 if (time_after(jiffies, timeout)) {
612 printk(KERN_WARNING "%s: Timeout Initializing\n",
613 c->name);
614 return -ETIMEDOUT;
615 }
616 set_current_state(TASK_UNINTERRUPTIBLE);
617 schedule_timeout(1);
618
619 rmb();
620 }
621
622 m = c->out_queue.phys;
623
624 /* Post frames */
625 for (i = 0; i < NMBR_MSG_FRAMES; i++) {
626 i2o_flush_reply(c, m);
627 udelay(1); /* Promise */
628 m += MSG_FRAME_SIZE * 4;
629 }
630
631 return 0;
632}
633
634/**
635 * i2o_iop_send_nop - send a core NOP message
636 * @c: controller
637 *
638 * Send a no-operation message with a reply set to cause no
639 * action either. Needed for bringing up promise controllers.
640 */
641static int i2o_iop_send_nop(struct i2o_controller *c)
642{
643 struct i2o_message __iomem *msg;
644 u32 m = i2o_msg_get_wait(c, &msg, HZ);
645 if (m == I2O_QUEUE_EMPTY)
646 return -ETIMEDOUT;
647 i2o_msg_nop(c, m);
648 return 0;
649}
650
651/**
652 * i2o_iop_activate - Bring controller up to HOLD 614 * i2o_iop_activate - Bring controller up to HOLD
653 * @c: controller 615 * @c: controller
654 * 616 *
@@ -659,78 +621,62 @@ static int i2o_iop_send_nop(struct i2o_controller *c)
659 */ 621 */
660static int i2o_iop_activate(struct i2o_controller *c) 622static int i2o_iop_activate(struct i2o_controller *c)
661{ 623{
662 struct pci_dev *i960 = NULL;
663 i2o_status_block *sb = c->status_block.virt; 624 i2o_status_block *sb = c->status_block.virt;
664 int rc; 625 int rc;
665 626 int state;
666 if (c->promise) {
667 /* Beat up the hardware first of all */
668 i960 =
669 pci_find_slot(c->pdev->bus->number,
670 PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
671 if (i960)
672 pci_write_config_word(i960, 0x42, 0);
673
674 /* Follow this sequence precisely or the controller
675 ceases to perform useful functions until reboot */
676 if ((rc = i2o_iop_send_nop(c)))
677 return rc;
678
679 if ((rc = i2o_iop_reset(c)))
680 return rc;
681 }
682 627
683 /* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */ 628 /* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */
684 /* In READY state, Get status */ 629 /* In READY state, Get status */
685 630
686 rc = i2o_status_get(c); 631 rc = i2o_status_get(c);
687 if (rc) { 632 if (rc) {
688 printk(KERN_INFO "%s: Unable to obtain status, " 633 osm_info("%s: Unable to obtain status, attempting a reset.\n",
689 "attempting a reset.\n", c->name); 634 c->name);
690 if (i2o_iop_reset(c)) 635 rc = i2o_iop_reset(c);
636 if (rc)
691 return rc; 637 return rc;
692 } 638 }
693 639
694 if (sb->i2o_version > I2OVER15) { 640 if (sb->i2o_version > I2OVER15) {
695 printk(KERN_ERR "%s: Not running version 1.5 of the I2O " 641 osm_err("%s: Not running version 1.5 of the I2O Specification."
696 "Specification.\n", c->name); 642 "\n", c->name);
697 return -ENODEV; 643 return -ENODEV;
698 } 644 }
699 645
700 switch (sb->iop_state) { 646 switch (sb->iop_state) {
701 case ADAPTER_STATE_FAULTED: 647 case ADAPTER_STATE_FAULTED:
702 printk(KERN_CRIT "%s: hardware fault\n", c->name); 648 osm_err("%s: hardware fault\n", c->name);
703 return -ENODEV; 649 return -EFAULT;
704 650
705 case ADAPTER_STATE_READY: 651 case ADAPTER_STATE_READY:
706 case ADAPTER_STATE_OPERATIONAL: 652 case ADAPTER_STATE_OPERATIONAL:
707 case ADAPTER_STATE_HOLD: 653 case ADAPTER_STATE_HOLD:
708 case ADAPTER_STATE_FAILED: 654 case ADAPTER_STATE_FAILED:
709 pr_debug("%s: already running, trying to reset...\n", c->name); 655 osm_debug("%s: already running, trying to reset...\n", c->name);
710 if (i2o_iop_reset(c)) 656 rc = i2o_iop_reset(c);
711 return -ENODEV; 657 if (rc)
658 return rc;
712 } 659 }
713 660
661 /* preserve state */
662 state = sb->iop_state;
663
714 rc = i2o_iop_init_outbound_queue(c); 664 rc = i2o_iop_init_outbound_queue(c);
715 if (rc) 665 if (rc)
716 return rc; 666 return rc;
717 667
718 if (c->promise) { 668 /* if adapter was not in RESET state clear now */
719 if ((rc = i2o_iop_send_nop(c))) 669 if (state != ADAPTER_STATE_RESET)
720 return rc; 670 i2o_iop_clear(c);
721 671
722 if ((rc = i2o_status_get(c))) 672 i2o_status_get(c);
723 return rc;
724 673
725 if (i960) 674 if (sb->iop_state != ADAPTER_STATE_HOLD) {
726 pci_write_config_word(i960, 0x42, 0x3FF); 675 osm_err("%s: failed to bring IOP into HOLD state\n", c->name);
676 return -EIO;
727 } 677 }
728 678
729 /* In HOLD state */ 679 return i2o_hrt_get(c);
730
731 rc = i2o_hrt_get(c);
732
733 return rc;
734}; 680};
735 681
736/** 682/**
@@ -756,20 +702,18 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
756 res->flags = IORESOURCE_MEM; 702 res->flags = IORESOURCE_MEM;
757 res->start = 0; 703 res->start = 0;
758 res->end = 0; 704 res->end = 0;
759 printk(KERN_INFO "%s: requires private memory resources.\n", 705 osm_info("%s: requires private memory resources.\n", c->name);
760 c->name);
761 root = pci_find_parent_resource(c->pdev, res); 706 root = pci_find_parent_resource(c->pdev, res);
762 if (root == NULL) 707 if (root == NULL)
763 printk(KERN_WARNING "%s: Can't find parent resource!\n", 708 osm_warn("%s: Can't find parent resource!\n", c->name);
764 c->name);
765 if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */ 709 if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
766 NULL, NULL) >= 0) { 710 NULL, NULL) >= 0) {
767 c->mem_alloc = 1; 711 c->mem_alloc = 1;
768 sb->current_mem_size = 1 + res->end - res->start; 712 sb->current_mem_size = 1 + res->end - res->start;
769 sb->current_mem_base = res->start; 713 sb->current_mem_base = res->start;
770 printk(KERN_INFO "%s: allocated %ld bytes of PCI memory" 714 osm_info("%s: allocated %ld bytes of PCI memory at "
771 " at 0x%08lX.\n", c->name, 715 "0x%08lX.\n", c->name,
772 1 + res->end - res->start, res->start); 716 1 + res->end - res->start, res->start);
773 } 717 }
774 } 718 }
775 719
@@ -779,20 +723,18 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
779 res->flags = IORESOURCE_IO; 723 res->flags = IORESOURCE_IO;
780 res->start = 0; 724 res->start = 0;
781 res->end = 0; 725 res->end = 0;
782 printk(KERN_INFO "%s: requires private memory resources.\n", 726 osm_info("%s: requires private memory resources.\n", c->name);
783 c->name);
784 root = pci_find_parent_resource(c->pdev, res); 727 root = pci_find_parent_resource(c->pdev, res);
785 if (root == NULL) 728 if (root == NULL)
786 printk(KERN_WARNING "%s: Can't find parent resource!\n", 729 osm_warn("%s: Can't find parent resource!\n", c->name);
787 c->name);
788 if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */ 730 if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
789 NULL, NULL) >= 0) { 731 NULL, NULL) >= 0) {
790 c->io_alloc = 1; 732 c->io_alloc = 1;
791 sb->current_io_size = 1 + res->end - res->start; 733 sb->current_io_size = 1 + res->end - res->start;
792 sb->current_mem_base = res->start; 734 sb->current_mem_base = res->start;
793 printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at" 735 osm_info("%s: allocated %ld bytes of PCI I/O at 0x%08lX"
794 " 0x%08lX.\n", c->name, 736 ".\n", c->name, 1 + res->end - res->start,
795 1 + res->end - res->start, res->start); 737 res->start);
796 } 738 }
797 } 739 }
798 740
@@ -836,10 +778,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
836 PCI_DMA_TODEVICE); 778 PCI_DMA_TODEVICE);
837 779
838 if (rc < 0) 780 if (rc < 0)
839 printk(KERN_ERR "%s: Unable to set SysTab (status=%#x).\n", 781 osm_err("%s: Unable to set SysTab (status=%#x).\n", c->name,
840 c->name, -rc); 782 -rc);
841 else 783 else
842 pr_debug("%s: SysTab set.\n", c->name); 784 osm_debug("%s: SysTab set.\n", c->name);
843 785
844 i2o_status_get(c); // Entered READY state 786 i2o_status_get(c); // Entered READY state
845 787
@@ -863,7 +805,7 @@ static int i2o_iop_online(struct i2o_controller *c)
863 return rc; 805 return rc;
864 806
865 /* In READY state */ 807 /* In READY state */
866 pr_debug("%s: Attempting to enable...\n", c->name); 808 osm_debug("%s: Attempting to enable...\n", c->name);
867 rc = i2o_iop_enable(c); 809 rc = i2o_iop_enable(c);
868 if (rc) 810 if (rc)
869 return rc; 811 return rc;
@@ -882,7 +824,7 @@ void i2o_iop_remove(struct i2o_controller *c)
882{ 824{
883 struct i2o_device *dev, *tmp; 825 struct i2o_device *dev, *tmp;
884 826
885 pr_debug("%s: deleting controller\n", c->name); 827 osm_debug("%s: deleting controller\n", c->name);
886 828
887 i2o_driver_notify_controller_remove_all(c); 829 i2o_driver_notify_controller_remove_all(c);
888 830
@@ -891,8 +833,12 @@ void i2o_iop_remove(struct i2o_controller *c)
891 list_for_each_entry_safe(dev, tmp, &c->devices, list) 833 list_for_each_entry_safe(dev, tmp, &c->devices, list)
892 i2o_device_remove(dev); 834 i2o_device_remove(dev);
893 835
836 device_del(&c->device);
837
894 /* Ask the IOP to switch to RESET state */ 838 /* Ask the IOP to switch to RESET state */
895 i2o_iop_reset(c); 839 i2o_iop_reset(c);
840
841 put_device(&c->device);
896} 842}
897 843
898/** 844/**
@@ -927,8 +873,7 @@ static int i2o_systab_build(void)
927 873
928 systab = i2o_systab.virt = kmalloc(i2o_systab.len, GFP_KERNEL); 874 systab = i2o_systab.virt = kmalloc(i2o_systab.len, GFP_KERNEL);
929 if (!systab) { 875 if (!systab) {
930 printk(KERN_ERR "i2o: unable to allocate memory for System " 876 osm_err("unable to allocate memory for System Table\n");
931 "Table\n");
932 return -ENOMEM; 877 return -ENOMEM;
933 } 878 }
934 memset(systab, 0, i2o_systab.len); 879 memset(systab, 0, i2o_systab.len);
@@ -940,8 +885,8 @@ static int i2o_systab_build(void)
940 i2o_status_block *sb; 885 i2o_status_block *sb;
941 886
942 if (count >= num_controllers) { 887 if (count >= num_controllers) {
943 printk(KERN_ERR "i2o: controller added while building " 888 osm_err("controller added while building system table"
944 "system table\n"); 889 "\n");
945 break; 890 break;
946 } 891 }
947 892
@@ -955,9 +900,8 @@ static int i2o_systab_build(void)
955 * it is techninically not part of the I2O subsystem... 900 * it is techninically not part of the I2O subsystem...
956 */ 901 */
957 if (unlikely(i2o_status_get(c))) { 902 if (unlikely(i2o_status_get(c))) {
958 printk(KERN_ERR "%s: Deleting b/c could not get status" 903 osm_err("%s: Deleting b/c could not get status while "
959 " while attempting to build system table\n", 904 "attempting to build system table\n", c->name);
960 c->name);
961 i2o_iop_remove(c); 905 i2o_iop_remove(c);
962 continue; // try the next one 906 continue; // try the next one
963 } 907 }
@@ -971,8 +915,10 @@ static int i2o_systab_build(void)
971 systab->iops[count].frame_size = sb->inbound_frame_size; 915 systab->iops[count].frame_size = sb->inbound_frame_size;
972 systab->iops[count].last_changed = change_ind; 916 systab->iops[count].last_changed = change_ind;
973 systab->iops[count].iop_capabilities = sb->iop_capabilities; 917 systab->iops[count].iop_capabilities = sb->iop_capabilities;
974 systab->iops[count].inbound_low = i2o_ptr_low(c->post_port); 918 systab->iops[count].inbound_low =
975 systab->iops[count].inbound_high = i2o_ptr_high(c->post_port); 919 i2o_dma_low(c->base.phys + I2O_IN_PORT);
920 systab->iops[count].inbound_high =
921 i2o_dma_high(c->base.phys + I2O_IN_PORT);
976 922
977 count++; 923 count++;
978 } 924 }
@@ -1010,11 +956,11 @@ int i2o_status_get(struct i2o_controller *c)
1010{ 956{
1011 struct i2o_message __iomem *msg; 957 struct i2o_message __iomem *msg;
1012 u32 m; 958 u32 m;
1013 u8 *status_block; 959 volatile u8 *status_block;
1014 unsigned long timeout; 960 unsigned long timeout;
1015 961
1016 status_block = (u8 *) c->status_block.virt; 962 status_block = (u8 *) c->status_block.virt;
1017 memset(status_block, 0, sizeof(i2o_status_block)); 963 memset(c->status_block.virt, 0, sizeof(i2o_status_block));
1018 964
1019 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); 965 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
1020 if (m == I2O_QUEUE_EMPTY) 966 if (m == I2O_QUEUE_EMPTY)
@@ -1027,8 +973,8 @@ int i2o_status_get(struct i2o_controller *c)
1027 writel(0, &msg->u.s.tcntxt); // FIXME: use resonable transaction context 973 writel(0, &msg->u.s.tcntxt); // FIXME: use resonable transaction context
1028 writel(0, &msg->body[0]); 974 writel(0, &msg->body[0]);
1029 writel(0, &msg->body[1]); 975 writel(0, &msg->body[1]);
1030 writel(i2o_ptr_low((void *)c->status_block.phys), &msg->body[2]); 976 writel(i2o_dma_low(c->status_block.phys), &msg->body[2]);
1031 writel(i2o_ptr_high((void *)c->status_block.phys), &msg->body[3]); 977 writel(i2o_dma_high(c->status_block.phys), &msg->body[3]);
1032 writel(sizeof(i2o_status_block), &msg->body[4]); /* always 88 bytes */ 978 writel(sizeof(i2o_status_block), &msg->body[4]); /* always 88 bytes */
1033 979
1034 i2o_msg_post(c, m); 980 i2o_msg_post(c, m);
@@ -1037,14 +983,12 @@ int i2o_status_get(struct i2o_controller *c)
1037 timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ; 983 timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ;
1038 while (status_block[87] != 0xFF) { 984 while (status_block[87] != 0xFF) {
1039 if (time_after(jiffies, timeout)) { 985 if (time_after(jiffies, timeout)) {
1040 printk(KERN_ERR "%s: Get status timeout.\n", c->name); 986 osm_err("%s: Get status timeout.\n", c->name);
1041 return -ETIMEDOUT; 987 return -ETIMEDOUT;
1042 } 988 }
1043 989
1044 set_current_state(TASK_UNINTERRUPTIBLE); 990 set_current_state(TASK_UNINTERRUPTIBLE);
1045 schedule_timeout(1); 991 schedule_timeout(1);
1046
1047 rmb();
1048 } 992 }
1049 993
1050#ifdef DEBUG 994#ifdef DEBUG
@@ -1088,8 +1032,8 @@ static int i2o_hrt_get(struct i2o_controller *c)
1088 rc = i2o_msg_post_wait_mem(c, m, 20, &c->hrt); 1032 rc = i2o_msg_post_wait_mem(c, m, 20, &c->hrt);
1089 1033
1090 if (rc < 0) { 1034 if (rc < 0) {
1091 printk(KERN_ERR "%s: Unable to get HRT (status=%#x)\n", 1035 osm_err("%s: Unable to get HRT (status=%#x)\n", c->name,
1092 c->name, -rc); 1036 -rc);
1093 return rc; 1037 return rc;
1094 } 1038 }
1095 1039
@@ -1103,13 +1047,41 @@ static int i2o_hrt_get(struct i2o_controller *c)
1103 return i2o_parse_hrt(c); 1047 return i2o_parse_hrt(c);
1104 } 1048 }
1105 1049
1106 printk(KERN_ERR "%s: Unable to get HRT after %d tries, giving up\n", 1050 osm_err("%s: Unable to get HRT after %d tries, giving up\n", c->name,
1107 c->name, I2O_HRT_GET_TRIES); 1051 I2O_HRT_GET_TRIES);
1108 1052
1109 return -EBUSY; 1053 return -EBUSY;
1110} 1054}
1111 1055
1112/** 1056/**
1057 * i2o_iop_free - Free the i2o_controller struct
1058 * @c: I2O controller to free
1059 */
1060void i2o_iop_free(struct i2o_controller *c)
1061{
1062 kfree(c);
1063};
1064
1065/**
1066 * i2o_iop_release - release the memory for a I2O controller
1067 * @dev: I2O controller which should be released
1068 *
1069 * Release the allocated memory. This function is called if refcount of
1070 * device reaches 0 automatically.
1071 */
1072static void i2o_iop_release(struct device *dev)
1073{
1074 struct i2o_controller *c = to_i2o_controller(dev);
1075
1076 i2o_iop_free(c);
1077};
1078
1079/* I2O controller class */
1080static struct class i2o_controller_class = {
1081 .name = "i2o_controller",
1082};
1083
1084/**
1113 * i2o_iop_alloc - Allocate and initialize a i2o_controller struct 1085 * i2o_iop_alloc - Allocate and initialize a i2o_controller struct
1114 * 1086 *
1115 * Allocate the necessary memory for a i2o_controller struct and 1087 * Allocate the necessary memory for a i2o_controller struct and
@@ -1125,8 +1097,8 @@ struct i2o_controller *i2o_iop_alloc(void)
1125 1097
1126 c = kmalloc(sizeof(*c), GFP_KERNEL); 1098 c = kmalloc(sizeof(*c), GFP_KERNEL);
1127 if (!c) { 1099 if (!c) {
1128 printk(KERN_ERR "i2o: Insufficient memory to allocate a I2O " 1100 osm_err("i2o: Insufficient memory to allocate a I2O controller."
1129 "controller.\n"); 1101 "\n");
1130 return ERR_PTR(-ENOMEM); 1102 return ERR_PTR(-ENOMEM);
1131 } 1103 }
1132 memset(c, 0, sizeof(*c)); 1104 memset(c, 0, sizeof(*c));
@@ -1137,6 +1109,16 @@ struct i2o_controller *i2o_iop_alloc(void)
1137 c->unit = unit++; 1109 c->unit = unit++;
1138 sprintf(c->name, "iop%d", c->unit); 1110 sprintf(c->name, "iop%d", c->unit);
1139 1111
1112 device_initialize(&c->device);
1113 class_device_initialize(&c->classdev);
1114
1115 c->device.release = &i2o_iop_release;
1116 c->classdev.class = &i2o_controller_class;
1117 c->classdev.dev = &c->device;
1118
1119 snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
1120 snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit);
1121
1140#if BITS_PER_LONG == 64 1122#if BITS_PER_LONG == 64
1141 spin_lock_init(&c->context_list_lock); 1123 spin_lock_init(&c->context_list_lock);
1142 atomic_set(&c->context_list_counter, 0); 1124 atomic_set(&c->context_list_counter, 0);
@@ -1147,15 +1129,6 @@ struct i2o_controller *i2o_iop_alloc(void)
1147}; 1129};
1148 1130
1149/** 1131/**
1150 * i2o_iop_free - Free the i2o_controller struct
1151 * @c: I2O controller to free
1152 */
1153void i2o_iop_free(struct i2o_controller *c)
1154{
1155 kfree(c);
1156};
1157
1158/**
1159 * i2o_iop_add - Initialize the I2O controller and add him to the I2O core 1132 * i2o_iop_add - Initialize the I2O controller and add him to the I2O core
1160 * @c: controller 1133 * @c: controller
1161 * 1134 *
@@ -1168,45 +1141,58 @@ int i2o_iop_add(struct i2o_controller *c)
1168{ 1141{
1169 int rc; 1142 int rc;
1170 1143
1171 printk(KERN_INFO "%s: Activating I2O controller...\n", c->name); 1144 if ((rc = device_add(&c->device))) {
1172 printk(KERN_INFO "%s: This may take a few minutes if there are many " 1145 osm_err("%s: could not add controller\n", c->name);
1173 "devices\n", c->name); 1146 goto iop_reset;
1147 }
1174 1148
1175 if ((rc = i2o_iop_activate(c))) { 1149 if ((rc = class_device_add(&c->classdev))) {
1176 printk(KERN_ERR "%s: could not activate controller\n", 1150 osm_err("%s: could not add controller class\n", c->name);
1177 c->name); 1151 goto device_del;
1178 i2o_iop_reset(c);
1179 return rc;
1180 } 1152 }
1181 1153
1182 pr_debug("%s: building sys table...\n", c->name); 1154 osm_info("%s: Activating I2O controller...\n", c->name);
1155 osm_info("%s: This may take a few minutes if there are many devices\n",
1156 c->name);
1183 1157
1184 if ((rc = i2o_systab_build())) { 1158 if ((rc = i2o_iop_activate(c))) {
1185 i2o_iop_reset(c); 1159 osm_err("%s: could not activate controller\n", c->name);
1186 return rc; 1160 goto class_del;
1187 } 1161 }
1188 1162
1189 pr_debug("%s: online controller...\n", c->name); 1163 osm_debug("%s: building sys table...\n", c->name);
1190 1164
1191 if ((rc = i2o_iop_online(c))) { 1165 if ((rc = i2o_systab_build()))
1192 i2o_iop_reset(c); 1166 goto class_del;
1193 return rc;
1194 }
1195 1167
1196 pr_debug("%s: getting LCT...\n", c->name); 1168 osm_debug("%s: online controller...\n", c->name);
1197 1169
1198 if ((rc = i2o_exec_lct_get(c))) { 1170 if ((rc = i2o_iop_online(c)))
1199 i2o_iop_reset(c); 1171 goto class_del;
1200 return rc; 1172
1201 } 1173 osm_debug("%s: getting LCT...\n", c->name);
1174
1175 if ((rc = i2o_exec_lct_get(c)))
1176 goto class_del;
1202 1177
1203 list_add(&c->list, &i2o_controllers); 1178 list_add(&c->list, &i2o_controllers);
1204 1179
1205 i2o_driver_notify_controller_add_all(c); 1180 i2o_driver_notify_controller_add_all(c);
1206 1181
1207 printk(KERN_INFO "%s: Controller added\n", c->name); 1182 osm_info("%s: Controller added\n", c->name);
1208 1183
1209 return 0; 1184 return 0;
1185
1186 class_del:
1187 class_device_del(&c->classdev);
1188
1189 device_del:
1190 device_del(&c->device);
1191
1192 iop_reset:
1193 i2o_iop_reset(c);
1194
1195 return rc;
1210}; 1196};
1211 1197
1212/** 1198/**
@@ -1264,16 +1250,18 @@ static int __init i2o_iop_init(void)
1264 if (rc) 1250 if (rc)
1265 goto exit; 1251 goto exit;
1266 1252
1267 rc = i2o_driver_init(); 1253 if ((rc = class_register(&i2o_controller_class))) {
1268 if (rc) 1254 osm_err("can't register class i2o_controller\n");
1269 goto device_exit; 1255 goto device_exit;
1256 }
1270 1257
1271 rc = i2o_exec_init(); 1258 if ((rc = i2o_driver_init()))
1272 if (rc) 1259 goto class_exit;
1260
1261 if ((rc = i2o_exec_init()))
1273 goto driver_exit; 1262 goto driver_exit;
1274 1263
1275 rc = i2o_pci_init(); 1264 if ((rc = i2o_pci_init()))
1276 if (rc < 0)
1277 goto exec_exit; 1265 goto exec_exit;
1278 1266
1279 return 0; 1267 return 0;
@@ -1284,6 +1272,9 @@ static int __init i2o_iop_init(void)
1284 driver_exit: 1272 driver_exit:
1285 i2o_driver_exit(); 1273 i2o_driver_exit();
1286 1274
1275 class_exit:
1276 class_unregister(&i2o_controller_class);
1277
1287 device_exit: 1278 device_exit:
1288 i2o_device_exit(); 1279 i2o_device_exit();
1289 1280
@@ -1301,6 +1292,7 @@ static void __exit i2o_iop_exit(void)
1301 i2o_pci_exit(); 1292 i2o_pci_exit();
1302 i2o_exec_exit(); 1293 i2o_exec_exit();
1303 i2o_driver_exit(); 1294 i2o_driver_exit();
1295 class_unregister(&i2o_controller_class);
1304 i2o_device_exit(); 1296 i2o_device_exit();
1305}; 1297};
1306 1298
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index e772752f056d..7a60fd7be8ad 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -30,53 +30,18 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/i2o.h> 32#include <linux/i2o.h>
33 33#include "core.h"
34#ifdef CONFIG_MTRR
35#include <asm/mtrr.h>
36#endif // CONFIG_MTRR
37
38/* Module internal functions from other sources */
39extern struct i2o_controller *i2o_iop_alloc(void);
40extern void i2o_iop_free(struct i2o_controller *);
41
42extern int i2o_iop_add(struct i2o_controller *);
43extern void i2o_iop_remove(struct i2o_controller *);
44
45extern int i2o_driver_dispatch(struct i2o_controller *, u32,
46 struct i2o_message *);
47 34
48/* PCI device id table for all I2O controllers */ 35/* PCI device id table for all I2O controllers */
49static struct pci_device_id __devinitdata i2o_pci_ids[] = { 36static struct pci_device_id __devinitdata i2o_pci_ids[] = {
50 {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)}, 37 {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)},
51 {PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)}, 38 {PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)},
39 {.vendor = PCI_VENDOR_ID_INTEL,.device = 0x1962,
40 .subvendor = PCI_VENDOR_ID_PROMISE,.subdevice = PCI_ANY_ID},
52 {0} 41 {0}
53}; 42};
54 43
55/** 44/**
56 * i2o_dma_realloc - Realloc DMA memory
57 * @dev: struct device pointer to the PCI device of the I2O controller
58 * @addr: pointer to a i2o_dma struct DMA buffer
59 * @len: new length of memory
60 * @gfp_mask: GFP mask
61 *
62 * If there was something allocated in the addr, free it first. If len > 0
63 * than try to allocate it and write the addresses back to the addr
64 * structure. If len == 0 set the virtual address to NULL.
65 *
66 * Returns the 0 on success or negative error code on failure.
67 */
68int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len,
69 unsigned int gfp_mask)
70{
71 i2o_dma_free(dev, addr);
72
73 if (len)
74 return i2o_dma_alloc(dev, addr, len, gfp_mask);
75
76 return 0;
77};
78
79/**
80 * i2o_pci_free - Frees the DMA memory for the I2O controller 45 * i2o_pci_free - Frees the DMA memory for the I2O controller
81 * @c: I2O controller to free 46 * @c: I2O controller to free
82 * 47 *
@@ -91,19 +56,11 @@ static void i2o_pci_free(struct i2o_controller *c)
91 56
92 i2o_dma_free(dev, &c->out_queue); 57 i2o_dma_free(dev, &c->out_queue);
93 i2o_dma_free(dev, &c->status_block); 58 i2o_dma_free(dev, &c->status_block);
94 if (c->lct) 59 kfree(c->lct);
95 kfree(c->lct);
96 i2o_dma_free(dev, &c->dlct); 60 i2o_dma_free(dev, &c->dlct);
97 i2o_dma_free(dev, &c->hrt); 61 i2o_dma_free(dev, &c->hrt);
98 i2o_dma_free(dev, &c->status); 62 i2o_dma_free(dev, &c->status);
99 63
100#ifdef CONFIG_MTRR
101 if (c->mtrr_reg0 >= 0)
102 mtrr_del(c->mtrr_reg0, 0, 0);
103 if (c->mtrr_reg1 >= 0)
104 mtrr_del(c->mtrr_reg1, 0, 0);
105#endif
106
107 if (c->raptor && c->in_queue.virt) 64 if (c->raptor && c->in_queue.virt)
108 iounmap(c->in_queue.virt); 65 iounmap(c->in_queue.virt);
109 66
@@ -178,14 +135,15 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
178 c->name, (unsigned long)c->base.phys, 135 c->name, (unsigned long)c->base.phys,
179 (unsigned long)c->base.len); 136 (unsigned long)c->base.len);
180 137
181 c->base.virt = ioremap(c->base.phys, c->base.len); 138 c->base.virt = ioremap_nocache(c->base.phys, c->base.len);
182 if (!c->base.virt) { 139 if (!c->base.virt) {
183 printk(KERN_ERR "%s: Unable to map controller.\n", c->name); 140 printk(KERN_ERR "%s: Unable to map controller.\n", c->name);
184 return -ENOMEM; 141 return -ENOMEM;
185 } 142 }
186 143
187 if (c->raptor) { 144 if (c->raptor) {
188 c->in_queue.virt = ioremap(c->in_queue.phys, c->in_queue.len); 145 c->in_queue.virt =
146 ioremap_nocache(c->in_queue.phys, c->in_queue.len);
189 if (!c->in_queue.virt) { 147 if (!c->in_queue.virt) {
190 printk(KERN_ERR "%s: Unable to map controller.\n", 148 printk(KERN_ERR "%s: Unable to map controller.\n",
191 c->name); 149 c->name);
@@ -195,43 +153,10 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
195 } else 153 } else
196 c->in_queue = c->base; 154 c->in_queue = c->base;
197 155
198 c->irq_mask = c->base.virt + 0x34; 156 c->irq_status = c->base.virt + I2O_IRQ_STATUS;
199 c->post_port = c->base.virt + 0x40; 157 c->irq_mask = c->base.virt + I2O_IRQ_MASK;
200 c->reply_port = c->base.virt + 0x44; 158 c->in_port = c->base.virt + I2O_IN_PORT;
201 159 c->out_port = c->base.virt + I2O_OUT_PORT;
202#ifdef CONFIG_MTRR
203 /* Enable Write Combining MTRR for IOP's memory region */
204 c->mtrr_reg0 = mtrr_add(c->in_queue.phys, c->in_queue.len,
205 MTRR_TYPE_WRCOMB, 1);
206 c->mtrr_reg1 = -1;
207
208 if (c->mtrr_reg0 < 0)
209 printk(KERN_WARNING "%s: could not enable write combining "
210 "MTRR\n", c->name);
211 else
212 printk(KERN_INFO "%s: using write combining MTRR\n", c->name);
213
214 /*
215 * If it is an INTEL i960 I/O processor then set the first 64K to
216 * Uncacheable since the region contains the messaging unit which
217 * shouldn't be cached.
218 */
219 if ((pdev->vendor == PCI_VENDOR_ID_INTEL ||
220 pdev->vendor == PCI_VENDOR_ID_DPT) && !c->raptor) {
221 printk(KERN_INFO "%s: MTRR workaround for Intel i960 processor"
222 "\n", c->name);
223 c->mtrr_reg1 = mtrr_add(c->base.phys, 0x10000,
224 MTRR_TYPE_UNCACHABLE, 1);
225
226 if (c->mtrr_reg1 < 0) {
227 printk(KERN_WARNING "%s: Error in setting "
228 "MTRR_TYPE_UNCACHABLE\n", c->name);
229 mtrr_del(c->mtrr_reg0, c->in_queue.phys,
230 c->in_queue.len);
231 c->mtrr_reg0 = -1;
232 }
233 }
234#endif
235 160
236 if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { 161 if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
237 i2o_pci_free(c); 162 i2o_pci_free(c);
@@ -254,7 +179,10 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
254 return -ENOMEM; 179 return -ENOMEM;
255 } 180 }
256 181
257 if (i2o_dma_alloc(dev, &c->out_queue, MSG_POOL_SIZE, GFP_KERNEL)) { 182 if (i2o_dma_alloc
183 (dev, &c->out_queue,
184 I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
185 sizeof(u32), GFP_KERNEL)) {
258 i2o_pci_free(c); 186 i2o_pci_free(c);
259 return -ENOMEM; 187 return -ENOMEM;
260 } 188 }
@@ -276,51 +204,30 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
276static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) 204static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
277{ 205{
278 struct i2o_controller *c = dev_id; 206 struct i2o_controller *c = dev_id;
279 struct device *dev = &c->pdev->dev; 207 u32 m;
280 struct i2o_message *m; 208 irqreturn_t rc = IRQ_NONE;
281 u32 mv; 209
282 210 while (readl(c->irq_status) & I2O_IRQ_OUTBOUND_POST) {
283 /* 211 m = readl(c->out_port);
284 * Old 960 steppings had a bug in the I2O unit that caused 212 if (m == I2O_QUEUE_EMPTY) {
285 * the queue to appear empty when it wasn't. 213 /*
286 */ 214 * Old 960 steppings had a bug in the I2O unit that
287 mv = I2O_REPLY_READ32(c); 215 * caused the queue to appear empty when it wasn't.
288 if (mv == I2O_QUEUE_EMPTY) { 216 */
289 mv = I2O_REPLY_READ32(c); 217 m = readl(c->out_port);
290 if (unlikely(mv == I2O_QUEUE_EMPTY)) { 218 if (unlikely(m == I2O_QUEUE_EMPTY))
291 return IRQ_NONE; 219 break;
292 } else 220 }
293 pr_debug("%s: 960 bug detected\n", c->name);
294 }
295
296 while (mv != I2O_QUEUE_EMPTY) {
297 /*
298 * Map the message from the page frame map to kernel virtual.
299 * Because bus_to_virt is deprecated, we have calculate the
300 * location by ourself!
301 */
302 m = i2o_msg_out_to_virt(c, mv);
303
304 /*
305 * Ensure this message is seen coherently but cachably by
306 * the processor
307 */
308 dma_sync_single_for_cpu(dev, mv, MSG_FRAME_SIZE * 4,
309 PCI_DMA_FROMDEVICE);
310 221
311 /* dispatch it */ 222 /* dispatch it */
312 if (i2o_driver_dispatch(c, mv, m)) 223 if (i2o_driver_dispatch(c, m))
313 /* flush it if result != 0 */ 224 /* flush it if result != 0 */
314 i2o_flush_reply(c, mv); 225 i2o_flush_reply(c, m);
315 226
316 /* 227 rc = IRQ_HANDLED;
317 * That 960 bug again...
318 */
319 mv = I2O_REPLY_READ32(c);
320 if (mv == I2O_QUEUE_EMPTY)
321 mv = I2O_REPLY_READ32(c);
322 } 228 }
323 return IRQ_HANDLED; 229
230 return rc;
324} 231}
325 232
326/** 233/**
@@ -336,7 +243,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
336 struct pci_dev *pdev = c->pdev; 243 struct pci_dev *pdev = c->pdev;
337 int rc; 244 int rc;
338 245
339 I2O_IRQ_WRITE32(c, 0xffffffff); 246 writel(0xffffffff, c->irq_mask);
340 247
341 if (pdev->irq) { 248 if (pdev->irq) {
342 rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ, 249 rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ,
@@ -348,7 +255,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
348 } 255 }
349 } 256 }
350 257
351 I2O_IRQ_WRITE32(c, 0x00000000); 258 writel(0x00000000, c->irq_mask);
352 259
353 printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq); 260 printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq);
354 261
@@ -363,7 +270,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
363 */ 270 */
364static void i2o_pci_irq_disable(struct i2o_controller *c) 271static void i2o_pci_irq_disable(struct i2o_controller *c)
365{ 272{
366 I2O_IRQ_WRITE32(c, 0xffffffff); 273 writel(0xffffffff, c->irq_mask);
367 274
368 if (c->pdev->irq > 0) 275 if (c->pdev->irq > 0)
369 free_irq(c->pdev->irq, c); 276 free_irq(c->pdev->irq, c);
@@ -385,28 +292,25 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
385{ 292{
386 struct i2o_controller *c; 293 struct i2o_controller *c;
387 int rc; 294 int rc;
295 struct pci_dev *i960 = NULL;
388 296
389 printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); 297 printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
390 298
391 if ((pdev->class & 0xff) > 1) { 299 if ((pdev->class & 0xff) > 1) {
392 printk(KERN_WARNING "i2o: I2O controller found but does not " 300 printk(KERN_WARNING "i2o: %s does not support I2O 1.5 "
393 "support I2O 1.5 (skipping).\n"); 301 "(skipping).\n", pci_name(pdev));
394 return -ENODEV; 302 return -ENODEV;
395 } 303 }
396 304
397 if ((rc = pci_enable_device(pdev))) { 305 if ((rc = pci_enable_device(pdev))) {
398 printk(KERN_WARNING "i2o: I2O controller found but could not be" 306 printk(KERN_WARNING "i2o: couldn't enable device %s\n",
399 " enabled.\n"); 307 pci_name(pdev));
400 return rc; 308 return rc;
401 } 309 }
402 310
403 printk(KERN_INFO "i2o: I2O controller found on bus %d at %d.\n",
404 pdev->bus->number, pdev->devfn);
405
406 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { 311 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
407 printk(KERN_WARNING "i2o: I2O controller on bus %d at %d: No " 312 printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
408 "suitable DMA available!\n", pdev->bus->number, 313 pci_name(pdev));
409 pdev->devfn);
410 rc = -ENODEV; 314 rc = -ENODEV;
411 goto disable; 315 goto disable;
412 } 316 }
@@ -415,14 +319,16 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
415 319
416 c = i2o_iop_alloc(); 320 c = i2o_iop_alloc();
417 if (IS_ERR(c)) { 321 if (IS_ERR(c)) {
418 printk(KERN_ERR "i2o: memory for I2O controller could not be " 322 printk(KERN_ERR "i2o: couldn't allocate memory for %s\n",
419 "allocated\n"); 323 pci_name(pdev));
420 rc = PTR_ERR(c); 324 rc = PTR_ERR(c);
421 goto disable; 325 goto disable;
422 } 326 } else
327 printk(KERN_INFO "%s: controller found (%s)\n", c->name,
328 pci_name(pdev));
423 329
424 c->pdev = pdev; 330 c->pdev = pdev;
425 c->device = pdev->dev; 331 c->device.parent = get_device(&pdev->dev);
426 332
427 /* Cards that fall apart if you hit them with large I/O loads... */ 333 /* Cards that fall apart if you hit them with large I/O loads... */
428 if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) { 334 if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
@@ -432,16 +338,48 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
432 } 338 }
433 339
434 if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) { 340 if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) {
341 /*
342 * Expose the ship behind i960 for initialization, or it will
343 * failed
344 */
345 i960 =
346 pci_find_slot(c->pdev->bus->number,
347 PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
348
349 if (i960)
350 pci_write_config_word(i960, 0x42, 0);
351
435 c->promise = 1; 352 c->promise = 1;
436 printk(KERN_INFO "%s: Promise workarounds activated.\n", 353 c->limit_sectors = 1;
437 c->name);
438 } 354 }
439 355
356 if (pdev->subsystem_vendor == PCI_VENDOR_ID_DPT)
357 c->adaptec = 1;
358
440 /* Cards that go bananas if you quiesce them before you reset them. */ 359 /* Cards that go bananas if you quiesce them before you reset them. */
441 if (pdev->vendor == PCI_VENDOR_ID_DPT) { 360 if (pdev->vendor == PCI_VENDOR_ID_DPT) {
442 c->no_quiesce = 1; 361 c->no_quiesce = 1;
443 if (pdev->device == 0xa511) 362 if (pdev->device == 0xa511)
444 c->raptor = 1; 363 c->raptor = 1;
364
365 if (pdev->subsystem_device == 0xc05a) {
366 c->limit_sectors = 1;
367 printk(KERN_INFO
368 "%s: limit sectors per request to %d\n", c->name,
369 I2O_MAX_SECTORS_LIMITED);
370 }
371#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
372 if (sizeof(dma_addr_t) > 4) {
373 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
374 printk(KERN_INFO "%s: 64-bit DMA unavailable\n",
375 c->name);
376 else {
377 c->pae_support = 1;
378 printk(KERN_INFO "%s: using 64-bit DMA\n",
379 c->name);
380 }
381 }
382#endif
445 } 383 }
446 384
447 if ((rc = i2o_pci_alloc(c))) { 385 if ((rc = i2o_pci_alloc(c))) {
@@ -459,6 +397,11 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
459 if ((rc = i2o_iop_add(c))) 397 if ((rc = i2o_iop_add(c)))
460 goto uninstall; 398 goto uninstall;
461 399
400 get_device(&c->device);
401
402 if (i960)
403 pci_write_config_word(i960, 0x42, 0x03ff);
404
462 return 0; 405 return 0;
463 406
464 uninstall: 407 uninstall:
@@ -469,6 +412,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
469 412
470 free_controller: 413 free_controller:
471 i2o_iop_free(c); 414 i2o_iop_free(c);
415 put_device(c->device.parent);
472 416
473 disable: 417 disable:
474 pci_disable_device(pdev); 418 pci_disable_device(pdev);
@@ -492,15 +436,17 @@ static void __devexit i2o_pci_remove(struct pci_dev *pdev)
492 i2o_pci_irq_disable(c); 436 i2o_pci_irq_disable(c);
493 i2o_pci_free(c); 437 i2o_pci_free(c);
494 438
439 pci_disable_device(pdev);
440
495 printk(KERN_INFO "%s: Controller removed.\n", c->name); 441 printk(KERN_INFO "%s: Controller removed.\n", c->name);
496 442
497 i2o_iop_free(c); 443 put_device(c->device.parent);
498 pci_disable_device(pdev); 444 put_device(&c->device);
499}; 445};
500 446
501/* PCI driver for I2O controller */ 447/* PCI driver for I2O controller */
502static struct pci_driver i2o_pci_driver = { 448static struct pci_driver i2o_pci_driver = {
503 .name = "I2O controller", 449 .name = "PCI_I2O",
504 .id_table = i2o_pci_ids, 450 .id_table = i2o_pci_ids,
505 .probe = i2o_pci_probe, 451 .probe = i2o_pci_probe,
506 .remove = __devexit_p(i2o_pci_remove), 452 .remove = __devexit_p(i2o_pci_remove),
@@ -523,6 +469,4 @@ void __exit i2o_pci_exit(void)
523{ 469{
524 pci_unregister_driver(&i2o_pci_driver); 470 pci_unregister_driver(&i2o_pci_driver);
525}; 471};
526
527EXPORT_SYMBOL(i2o_dma_realloc);
528MODULE_DEVICE_TABLE(pci, i2o_pci_ids); 472MODULE_DEVICE_TABLE(pci, i2o_pci_ids);
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 325495b8b60c..137226d98d47 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2307,6 +2307,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
2307 tso = e1000_tso(adapter, skb); 2307 tso = e1000_tso(adapter, skb);
2308 if (tso < 0) { 2308 if (tso < 0) {
2309 dev_kfree_skb_any(skb); 2309 dev_kfree_skb_any(skb);
2310 spin_unlock_irqrestore(&adapter->tx_lock, flags);
2310 return NETDEV_TX_OK; 2311 return NETDEV_TX_OK;
2311 } 2312 }
2312 2313
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 89454915b857..e44f8e9055ef 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -848,7 +848,7 @@ static void __exit sixpack_exit_driver(void)
848{ 848{
849 int ret; 849 int ret;
850 850
851 if ((ret = tty_register_ldisc(N_6PACK, NULL))) 851 if ((ret = tty_unregister_ldisc(N_6PACK)))
852 printk(msg_unregfail, ret); 852 printk(msg_unregfail, ret);
853} 853}
854 854
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 62790511098f..3035422f5ad8 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -934,7 +934,7 @@ static void __exit mkiss_exit_driver(void)
934 kfree(ax25_ctrls); 934 kfree(ax25_ctrls);
935 ax25_ctrls = NULL; 935 ax25_ctrls = NULL;
936 936
937 if ((i = tty_register_ldisc(N_AX25, NULL))) 937 if ((i = tty_unregister_ldisc(N_AX25)))
938 printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i); 938 printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);
939} 939}
940 940
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 7d23aa375908..b8d112348ba4 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -626,7 +626,7 @@ static void __exit irtty_sir_cleanup(void)
626{ 626{
627 int err; 627 int err;
628 628
629 if ((err = tty_register_ldisc(N_IRDA, NULL))) { 629 if ((err = tty_unregister_ldisc(N_IRDA))) {
630 IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n", 630 IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n",
631 __FUNCTION__, err); 631 __FUNCTION__, err);
632 } 632 }
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 33b9d79b1aad..5e48b9ab3045 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -1025,7 +1025,7 @@ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
1025 1025
1026static void __exit ppp_async_cleanup(void) 1026static void __exit ppp_async_cleanup(void)
1027{ 1027{
1028 if (tty_register_ldisc(N_PPP, NULL) != 0) 1028 if (tty_unregister_ldisc(N_PPP) != 0)
1029 printk(KERN_ERR "failed to unregister PPP line discipline\n"); 1029 printk(KERN_ERR "failed to unregister PPP line discipline\n");
1030} 1030}
1031 1031
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 7d0150b4c629..fd9f50180355 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -793,7 +793,7 @@ err:
793static void __exit 793static void __exit
794ppp_sync_cleanup(void) 794ppp_sync_cleanup(void)
795{ 795{
796 if (tty_register_ldisc(N_SYNC_PPP, NULL) != 0) 796 if (tty_unregister_ldisc(N_SYNC_PPP) != 0)
797 printk(KERN_ERR "failed to unregister Sync PPP line discipline\n"); 797 printk(KERN_ERR "failed to unregister Sync PPP line discipline\n");
798} 798}
799 799
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 8f7841c0374d..c79e0ad4ba02 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -198,18 +198,12 @@ err_exit:
198static void 198static void
199sl_free_bufs(struct slip *sl) 199sl_free_bufs(struct slip *sl)
200{ 200{
201 void * tmp;
202
203 /* Free all SLIP frame buffers. */ 201 /* Free all SLIP frame buffers. */
204 tmp = xchg(&sl->rbuff, NULL); 202 kfree(xchg(&sl->rbuff, NULL));
205 kfree(tmp); 203 kfree(xchg(&sl->xbuff, NULL));
206 tmp = xchg(&sl->xbuff, NULL);
207 kfree(tmp);
208#ifdef SL_INCLUDE_CSLIP 204#ifdef SL_INCLUDE_CSLIP
209 tmp = xchg(&sl->cbuff, NULL); 205 kfree(xchg(&sl->cbuff, NULL));
210 kfree(tmp); 206 slhc_free(xchg(&sl->slcomp, NULL));
211 if ((tmp = xchg(&sl->slcomp, NULL)) != NULL)
212 slhc_free(tmp);
213#endif 207#endif
214} 208}
215 209
@@ -1430,7 +1424,7 @@ static void __exit slip_exit(void)
1430 kfree(slip_devs); 1424 kfree(slip_devs);
1431 slip_devs = NULL; 1425 slip_devs = NULL;
1432 1426
1433 if ((i = tty_register_ldisc(N_SLIP, NULL))) 1427 if ((i = tty_unregister_ldisc(N_SLIP)))
1434 { 1428 {
1435 printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); 1429 printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
1436 } 1430 }
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 1c540d825551..bdf672c48182 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -829,7 +829,7 @@ static void __exit exit_x25_asy(void)
829 } 829 }
830 830
831 kfree(x25_asy_devs); 831 kfree(x25_asy_devs);
832 tty_register_ldisc(N_X25, NULL); 832 tty_unregister_ldisc(N_X25);
833} 833}
834 834
835module_init(init_x25_asy); 835module_init(init_x25_asy);
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index ec8cf29ffced..6c42b573a95a 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -2828,7 +2828,7 @@ static void __exit strip_exit_driver(void)
2828 /* Unregister with the /proc/net file here. */ 2828 /* Unregister with the /proc/net file here. */
2829 proc_net_remove("strip"); 2829 proc_net_remove("strip");
2830 2830
2831 if ((i = tty_register_ldisc(N_STRIP, NULL))) 2831 if ((i = tty_unregister_ldisc(N_STRIP)))
2832 printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i); 2832 printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
2833 2833
2834 printk(signoff); 2834 printk(signoff);
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 745a14183634..531b07313141 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -206,7 +206,7 @@ static inline unsigned long fast_get_dcookie(struct dentry * dentry,
206 */ 206 */
207static unsigned long get_exec_dcookie(struct mm_struct * mm) 207static unsigned long get_exec_dcookie(struct mm_struct * mm)
208{ 208{
209 unsigned long cookie = 0; 209 unsigned long cookie = NO_COOKIE;
210 struct vm_area_struct * vma; 210 struct vm_area_struct * vma;
211 211
212 if (!mm) 212 if (!mm)
@@ -234,35 +234,42 @@ out:
234 */ 234 */
235static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset) 235static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset)
236{ 236{
237 unsigned long cookie = 0; 237 unsigned long cookie = NO_COOKIE;
238 struct vm_area_struct * vma; 238 struct vm_area_struct * vma;
239 239
240 for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { 240 for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
241 241
242 if (!vma->vm_file)
243 continue;
244
245 if (addr < vma->vm_start || addr >= vma->vm_end) 242 if (addr < vma->vm_start || addr >= vma->vm_end)
246 continue; 243 continue;
247 244
248 cookie = fast_get_dcookie(vma->vm_file->f_dentry, 245 if (vma->vm_file) {
249 vma->vm_file->f_vfsmnt); 246 cookie = fast_get_dcookie(vma->vm_file->f_dentry,
250 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; 247 vma->vm_file->f_vfsmnt);
248 *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr -
249 vma->vm_start;
250 } else {
251 /* must be an anonymous map */
252 *offset = addr;
253 }
254
251 break; 255 break;
252 } 256 }
253 257
258 if (!vma)
259 cookie = INVALID_COOKIE;
260
254 return cookie; 261 return cookie;
255} 262}
256 263
257 264
258static unsigned long last_cookie = ~0UL; 265static unsigned long last_cookie = INVALID_COOKIE;
259 266
260static void add_cpu_switch(int i) 267static void add_cpu_switch(int i)
261{ 268{
262 add_event_entry(ESCAPE_CODE); 269 add_event_entry(ESCAPE_CODE);
263 add_event_entry(CPU_SWITCH_CODE); 270 add_event_entry(CPU_SWITCH_CODE);
264 add_event_entry(i); 271 add_event_entry(i);
265 last_cookie = ~0UL; 272 last_cookie = INVALID_COOKIE;
266} 273}
267 274
268static void add_kernel_ctx_switch(unsigned int in_kernel) 275static void add_kernel_ctx_switch(unsigned int in_kernel)
@@ -317,7 +324,7 @@ static int add_us_sample(struct mm_struct * mm, struct op_sample * s)
317 324
318 cookie = lookup_dcookie(mm, s->eip, &offset); 325 cookie = lookup_dcookie(mm, s->eip, &offset);
319 326
320 if (!cookie) { 327 if (cookie == INVALID_COOKIE) {
321 atomic_inc(&oprofile_stats.sample_lost_no_mapping); 328 atomic_inc(&oprofile_stats.sample_lost_no_mapping);
322 return 0; 329 return 0;
323 } 330 }
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
index 442aaad391e0..018023630599 100644
--- a/drivers/oprofile/event_buffer.h
+++ b/drivers/oprofile/event_buffer.h
@@ -35,6 +35,9 @@ void wake_up_buffer_waiter(void);
35#define TRACE_BEGIN_CODE 8 35#define TRACE_BEGIN_CODE 8
36#define TRACE_END_CODE 9 36#define TRACE_END_CODE 9
37 37
38#define INVALID_COOKIE ~0UL
39#define NO_COOKIE 0UL
40
38/* add data to the event buffer */ 41/* add data to the event buffer */
39void add_event_entry(unsigned long data); 42void add_event_entry(unsigned long data);
40 43
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index e7f3bcb79000..80edfa3abd29 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2751,7 +2751,6 @@ enum parport_pc_pci_cards {
2751 netmos_9755, 2751 netmos_9755,
2752 netmos_9805, 2752 netmos_9805,
2753 netmos_9815, 2753 netmos_9815,
2754 netmos_9855,
2755}; 2754};
2756 2755
2757 2756
@@ -2826,7 +2825,6 @@ static struct parport_pc_pci {
2826 /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */ 2825 /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
2827 /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ 2826 /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */
2828 /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ 2827 /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
2829 /* netmos_9855 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
2830}; 2828};
2831 2829
2832static struct pci_device_id parport_pc_pci_tbl[] = { 2830static struct pci_device_id parport_pc_pci_tbl[] = {
@@ -2907,8 +2905,6 @@ static struct pci_device_id parport_pc_pci_tbl[] = {
2907 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, 2905 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 },
2908 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, 2906 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815,
2909 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, 2907 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 },
2910 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
2911 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
2912 { 0, } /* terminate list */ 2908 { 0, } /* terminate list */
2913}; 2909};
2914MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); 2910MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 6715a17b5d0f..00498e2f1205 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -34,6 +34,7 @@ enum parport_pc_pci_cards {
34 titan_110l = 0, 34 titan_110l = 0,
35 titan_210l, 35 titan_210l,
36 netmos_9xx5_combo, 36 netmos_9xx5_combo,
37 netmos_9855,
37 avlab_1s1p, 38 avlab_1s1p,
38 avlab_1s1p_650, 39 avlab_1s1p_650,
39 avlab_1s1p_850, 40 avlab_1s1p_850,
@@ -87,6 +88,7 @@ static struct parport_pc_pci cards[] __devinitdata = {
87 /* titan_110l */ { 1, { { 3, -1 }, } }, 88 /* titan_110l */ { 1, { { 3, -1 }, } },
88 /* titan_210l */ { 1, { { 3, -1 }, } }, 89 /* titan_210l */ { 1, { { 3, -1 }, } },
89 /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, 90 /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init },
91 /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init },
90 /* avlab_1s1p */ { 1, { { 1, 2}, } }, 92 /* avlab_1s1p */ { 1, { { 1, 2}, } },
91 /* avlab_1s1p_650 */ { 1, { { 1, 2}, } }, 93 /* avlab_1s1p_650 */ { 1, { { 1, 2}, } },
92 /* avlab_1s1p_850 */ { 1, { { 1, 2}, } }, 94 /* avlab_1s1p_850 */ { 1, { { 1, 2}, } },
@@ -120,7 +122,7 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
120 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, 122 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
121 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, 123 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
122 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, 124 { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
123 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, 125 PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
124 /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ 126 /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
125 { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p}, 127 { 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p},
126 { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650}, 128 { 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650},
@@ -207,6 +209,7 @@ static struct pci_board_no_ids pci_boards[] __devinitdata = {
207/* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, 209/* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 },
208/* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, 210/* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
209/* netmos_9xx5_combo */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, 211/* netmos_9xx5_combo */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init },
212/* netmos_9855 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init },
210/* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, 213/* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
211/* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, 214/* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
212/* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, 215/* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index c94963145e17..6e6f42d01e64 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -48,14 +48,6 @@ static void pretty_print(struct parport *port, int device)
48 printk("\n"); 48 printk("\n");
49} 49}
50 50
51static char *strdup(char *str)
52{
53 int n = strlen(str)+1;
54 char *s = kmalloc(n, GFP_KERNEL);
55 if (!s) return NULL;
56 return strcpy(s, str);
57}
58
59static void parse_data(struct parport *port, int device, char *str) 51static void parse_data(struct parport *port, int device, char *str)
60{ 52{
61 char *txt = kmalloc(strlen(str)+1, GFP_KERNEL); 53 char *txt = kmalloc(strlen(str)+1, GFP_KERNEL);
@@ -88,16 +80,16 @@ static void parse_data(struct parport *port, int device, char *str)
88 if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) { 80 if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
89 if (info->mfr) 81 if (info->mfr)
90 kfree (info->mfr); 82 kfree (info->mfr);
91 info->mfr = strdup(sep); 83 info->mfr = kstrdup(sep, GFP_KERNEL);
92 } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) { 84 } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
93 if (info->model) 85 if (info->model)
94 kfree (info->model); 86 kfree (info->model);
95 info->model = strdup(sep); 87 info->model = kstrdup(sep, GFP_KERNEL);
96 } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) { 88 } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
97 int i; 89 int i;
98 if (info->class_name) 90 if (info->class_name)
99 kfree (info->class_name); 91 kfree (info->class_name);
100 info->class_name = strdup(sep); 92 info->class_name = kstrdup(sep, GFP_KERNEL);
101 for (u = sep; *u; u++) 93 for (u = sep; *u; u++)
102 *u = toupper(*u); 94 *u = toupper(*u);
103 for (i = 0; classes[i].token; i++) { 95 for (i = 0; classes[i].token; i++) {
@@ -112,7 +104,7 @@ static void parse_data(struct parport *port, int device, char *str)
112 !strcmp(p, "COMMAND SET")) { 104 !strcmp(p, "COMMAND SET")) {
113 if (info->cmdset) 105 if (info->cmdset)
114 kfree (info->cmdset); 106 kfree (info->cmdset);
115 info->cmdset = strdup(sep); 107 info->cmdset = kstrdup(sep, GFP_KERNEL);
116 /* if it speaks printer language, it's 108 /* if it speaks printer language, it's
117 probably a printer */ 109 probably a printer */
118 if (strstr(sep, "PJL") || strstr(sep, "PCL")) 110 if (strstr(sep, "PJL") || strstr(sep, "PCL"))
@@ -120,7 +112,7 @@ static void parse_data(struct parport *port, int device, char *str)
120 } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) { 112 } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
121 if (info->description) 113 if (info->description)
122 kfree (info->description); 114 kfree (info->description);
123 info->description = strdup(sep); 115 info->description = kstrdup(sep, GFP_KERNEL);
124 } 116 }
125 } 117 }
126 rock_on: 118 rock_on:
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 03fc885db1c5..d136b3c8fac9 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -508,6 +508,10 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
508 cs_err(skt, "unsupported voltage key.\n"); 508 cs_err(skt, "unsupported voltage key.\n");
509 return CS_BAD_TYPE; 509 return CS_BAD_TYPE;
510 } 510 }
511
512 if (skt->power_hook)
513 skt->power_hook(skt, HOOK_POWER_PRE);
514
511 skt->socket.flags = 0; 515 skt->socket.flags = 0;
512 skt->ops->set_socket(skt, &skt->socket); 516 skt->ops->set_socket(skt, &skt->socket);
513 517
@@ -522,7 +526,12 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
522 return CS_BAD_TYPE; 526 return CS_BAD_TYPE;
523 } 527 }
524 528
525 return socket_reset(skt); 529 status = socket_reset(skt);
530
531 if (skt->power_hook)
532 skt->power_hook(skt, HOOK_POWER_POST);
533
534 return status;
526} 535}
527 536
528/* 537/*
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index a8a1d104524a..c7ba99871aca 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -611,6 +611,170 @@ out:
611 } 611 }
612} 612}
613 613
614
615/* Returns true value if the second slot of a two-slot controller is empty */
616static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
617{
618 struct pci_dev *func;
619 struct yenta_socket *slot2;
620 int devfn;
621 unsigned int state;
622 int ret = 1;
623
624 /* catch the two-slot controllers */
625 switch (socket->dev->device) {
626 case PCI_DEVICE_ID_TI_1220:
627 case PCI_DEVICE_ID_TI_1221:
628 case PCI_DEVICE_ID_TI_1225:
629 case PCI_DEVICE_ID_TI_1251A:
630 case PCI_DEVICE_ID_TI_1251B:
631 case PCI_DEVICE_ID_TI_1420:
632 case PCI_DEVICE_ID_TI_1450:
633 case PCI_DEVICE_ID_TI_1451A:
634 case PCI_DEVICE_ID_TI_1520:
635 case PCI_DEVICE_ID_TI_1620:
636 case PCI_DEVICE_ID_TI_4520:
637 case PCI_DEVICE_ID_TI_4450:
638 case PCI_DEVICE_ID_TI_4451:
639 /*
640 * there are way more, but they need to be added in yenta_socket.c
641 * and pci_ids.h first anyway.
642 */
643 break;
644
645 /* single-slot controllers have the 2nd slot empty always :) */
646 default:
647 return 1;
648 }
649
650 /* get other slot */
651 devfn = socket->dev->devfn & ~0x07;
652 func = pci_get_slot(socket->dev->bus,
653 (socket->dev->devfn & 0x07) ? devfn : devfn | 0x01);
654 if (!func)
655 return 1;
656
657 slot2 = pci_get_drvdata(func);
658 if (!slot2)
659 goto out;
660
661 /* check state */
662 yenta_get_status(&socket->socket, &state);
663 if (state & SS_DETECT) {
664 ret = 0;
665 goto out;
666 }
667
668out:
669 pci_dev_put(func);
670 return ret;
671}
672
673/*
674 * TI specifiy parts for the power hook.
675 *
676 * some TI's with some CB's produces interrupt storm on power on. it has been
677 * seen with atheros wlan cards on TI1225 and TI1410. solution is simply to
678 * disable any CB interrupts during this time.
679 */
680static int ti12xx_power_hook(struct pcmcia_socket *sock, int operation)
681{
682 struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
683 u32 mfunc, devctl, sysctl;
684 u8 gpio3;
685
686 /* only POWER_PRE and POWER_POST are interesting */
687 if ((operation != HOOK_POWER_PRE) && (operation != HOOK_POWER_POST))
688 return 0;
689
690 devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
691 sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
692 mfunc = config_readl(socket, TI122X_MFUNC);
693
694 /*
695 * all serial/tied: only disable when modparm set. always doing it
696 * would mean a regression for working setups 'cos it disables the
697 * interrupts for both both slots on 2-slot controllers
698 * (and users of single slot controllers where it's save have to
699 * live with setting the modparm, most don't have to anyway)
700 */
701 if (((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) &&
702 (pwr_irqs_off || ti12xx_2nd_slot_empty(socket))) {
703 switch (socket->dev->device) {
704 case PCI_DEVICE_ID_TI_1250:
705 case PCI_DEVICE_ID_TI_1251A:
706 case PCI_DEVICE_ID_TI_1251B:
707 case PCI_DEVICE_ID_TI_1450:
708 case PCI_DEVICE_ID_TI_1451A:
709 case PCI_DEVICE_ID_TI_4450:
710 case PCI_DEVICE_ID_TI_4451:
711 /* these chips have no IRQSER setting in MFUNC3 */
712 break;
713
714 default:
715 if (operation == HOOK_POWER_PRE)
716 mfunc = (mfunc & ~TI122X_MFUNC3_MASK);
717 else
718 mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER;
719 }
720
721 return 0;
722 }
723
724 /* do the job differently for func0/1 */
725 if ((PCI_FUNC(socket->dev->devfn) == 0) ||
726 ((sysctl & TI122X_SCR_INTRTIE) &&
727 (pwr_irqs_off || ti12xx_2nd_slot_empty(socket)))) {
728 /* some bridges are different */
729 switch (socket->dev->device) {
730 case PCI_DEVICE_ID_TI_1250:
731 case PCI_DEVICE_ID_TI_1251A:
732 case PCI_DEVICE_ID_TI_1251B:
733 case PCI_DEVICE_ID_TI_1450:
734 /* those oldies use gpio3 for INTA */
735 gpio3 = config_readb(socket, TI1250_GPIO3_CONTROL);
736 if (operation == HOOK_POWER_PRE)
737 gpio3 = (gpio3 & ~TI1250_GPIO_MODE_MASK) | 0x40;
738 else
739 gpio3 &= ~TI1250_GPIO_MODE_MASK;
740 config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3);
741 break;
742
743 default:
744 /* all new bridges are the same */
745 if (operation == HOOK_POWER_PRE)
746 mfunc &= ~TI122X_MFUNC0_MASK;
747 else
748 mfunc |= TI122X_MFUNC0_INTA;
749 config_writel(socket, TI122X_MFUNC, mfunc);
750 }
751 } else {
752 switch (socket->dev->device) {
753 case PCI_DEVICE_ID_TI_1251A:
754 case PCI_DEVICE_ID_TI_1251B:
755 case PCI_DEVICE_ID_TI_1450:
756 /* those have INTA elsewhere and INTB in MFUNC0 */
757 if (operation == HOOK_POWER_PRE)
758 mfunc &= ~TI122X_MFUNC0_MASK;
759 else
760 mfunc |= TI125X_MFUNC0_INTB;
761 config_writel(socket, TI122X_MFUNC, mfunc);
762
763 break;
764
765 default:
766 /* all new bridges are the same */
767 if (operation == HOOK_POWER_PRE)
768 mfunc &= ~TI122X_MFUNC1_MASK;
769 else
770 mfunc |= TI122X_MFUNC1_INTB;
771 config_writel(socket, TI122X_MFUNC, mfunc);
772 }
773 }
774
775 return 0;
776}
777
614static int ti12xx_override(struct yenta_socket *socket) 778static int ti12xx_override(struct yenta_socket *socket)
615{ 779{
616 u32 val, val_orig; 780 u32 val, val_orig;
@@ -654,6 +818,9 @@ static int ti12xx_override(struct yenta_socket *socket)
654 else 818 else
655 ti12xx_irqroute_func1(socket); 819 ti12xx_irqroute_func1(socket);
656 820
821 /* install power hook */
822 socket->socket.power_hook = ti12xx_power_hook;
823
657 return ti_override(socket); 824 return ti_override(socket);
658} 825}
659 826
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 6404d97a12eb..bee05362fd24 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -32,6 +32,14 @@ static int disable_clkrun;
32module_param(disable_clkrun, bool, 0444); 32module_param(disable_clkrun, bool, 0444);
33MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option"); 33MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
34 34
35static int isa_probe = 1;
36module_param(isa_probe, bool, 0444);
37MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing");
38
39static int pwr_irqs_off;
40module_param(pwr_irqs_off, bool, 0644);
41MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
42
35#if 0 43#if 0
36#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) 44#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
37#else 45#else
@@ -150,15 +158,16 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
150 158
151 val = (state & CB_3VCARD) ? SS_3VCARD : 0; 159 val = (state & CB_3VCARD) ? SS_3VCARD : 0;
152 val |= (state & CB_XVCARD) ? SS_XVCARD : 0; 160 val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
153 val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD 161 val |= (state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
154 | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING; 162 val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? SS_PENDING : 0;
163
155 164
156 if (state & CB_CBCARD) { 165 if (state & CB_CBCARD) {
157 val |= SS_CARDBUS; 166 val |= SS_CARDBUS;
158 val |= (state & CB_CARDSTS) ? SS_STSCHG : 0; 167 val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
159 val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT; 168 val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
160 val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0; 169 val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
161 } else { 170 } else if (state & CB_16BITCARD) {
162 u8 status = exca_readb(socket, I365_STATUS); 171 u8 status = exca_readb(socket, I365_STATUS);
163 val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0; 172 val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
164 if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { 173 if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
@@ -405,11 +414,13 @@ static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *
405} 414}
406 415
407 416
408static unsigned int yenta_events(struct yenta_socket *socket) 417
418static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
409{ 419{
420 unsigned int events;
421 struct yenta_socket *socket = (struct yenta_socket *) dev_id;
410 u8 csc; 422 u8 csc;
411 u32 cb_event; 423 u32 cb_event;
412 unsigned int events;
413 424
414 /* Clear interrupt status for the event */ 425 /* Clear interrupt status for the event */
415 cb_event = cb_readl(socket, CB_SOCKET_EVENT); 426 cb_event = cb_readl(socket, CB_SOCKET_EVENT);
@@ -426,20 +437,13 @@ static unsigned int yenta_events(struct yenta_socket *socket)
426 events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0; 437 events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
427 events |= (csc & I365_CSC_READY) ? SS_READY : 0; 438 events |= (csc & I365_CSC_READY) ? SS_READY : 0;
428 } 439 }
429 return events;
430}
431
432
433static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
434{
435 unsigned int events;
436 struct yenta_socket *socket = (struct yenta_socket *) dev_id;
437 440
438 events = yenta_events(socket); 441 if (events)
439 if (events) {
440 pcmcia_parse_events(&socket->socket, events); 442 pcmcia_parse_events(&socket->socket, events);
443
444 if (cb_event || csc)
441 return IRQ_HANDLED; 445 return IRQ_HANDLED;
442 } 446
443 return IRQ_NONE; 447 return IRQ_NONE;
444} 448}
445 449
@@ -470,11 +474,22 @@ static void yenta_clear_maps(struct yenta_socket *socket)
470 } 474 }
471} 475}
472 476
477/* redoes voltage interrogation if required */
478static void yenta_interrogate(struct yenta_socket *socket)
479{
480 u32 state;
481
482 state = cb_readl(socket, CB_SOCKET_STATE);
483 if (!(state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ||
484 (state & (CB_CDETECT1 | CB_CDETECT2 | CB_NOTACARD | CB_BADVCCREQ)) ||
485 ((state & (CB_16BITCARD | CB_CBCARD)) == (CB_16BITCARD | CB_CBCARD)))
486 cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
487}
488
473/* Called at resume and initialization events */ 489/* Called at resume and initialization events */
474static int yenta_sock_init(struct pcmcia_socket *sock) 490static int yenta_sock_init(struct pcmcia_socket *sock)
475{ 491{
476 struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); 492 struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
477 u32 state;
478 u16 bridge; 493 u16 bridge;
479 494
480 bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR; 495 bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
@@ -486,10 +501,7 @@ static int yenta_sock_init(struct pcmcia_socket *sock)
486 exca_writeb(socket, I365_GENCTL, 0x00); 501 exca_writeb(socket, I365_GENCTL, 0x00);
487 502
488 /* Redo card voltage interrogation */ 503 /* Redo card voltage interrogation */
489 state = cb_readl(socket, CB_SOCKET_STATE); 504 yenta_interrogate(socket);
490 if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD |
491 CB_3VCARD | CB_XVCARD | CB_YVCARD)))
492 cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
493 505
494 yenta_clear_maps(socket); 506 yenta_clear_maps(socket);
495 507
@@ -856,7 +868,10 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i
856 socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS; 868 socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
857 socket->socket.map_size = 0x1000; 869 socket->socket.map_size = 0x1000;
858 socket->socket.pci_irq = socket->cb_irq; 870 socket->socket.pci_irq = socket->cb_irq;
859 socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); 871 if (isa_probe)
872 socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
873 else
874 socket->socket.irq_mask = 0;
860 socket->socket.cb_dev = socket->dev; 875 socket->socket.cb_dev = socket->dev;
861 876
862 printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n", 877 printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
@@ -996,6 +1011,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
996 } 1011 }
997 1012
998 /* Figure out what the dang thing can do for the PCMCIA layer... */ 1013 /* Figure out what the dang thing can do for the PCMCIA layer... */
1014 yenta_interrogate(socket);
999 yenta_get_socket_capabilities(socket, isa_interrupts); 1015 yenta_get_socket_capabilities(socket, isa_interrupts);
1000 printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE)); 1016 printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
1001 1017
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index 3252662958d3..add12f7c489a 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -259,7 +259,6 @@ int pnp_add_card_device(struct pnp_card * card, struct pnp_dev * dev)
259 259
260/** 260/**
261 * pnp_remove_card_device- removes a device from the specified card 261 * pnp_remove_card_device- removes a device from the specified card
262 * @card: pointer to the card to remove from
263 * @dev: pointer to the device to remove 262 * @dev: pointer to the device to remove
264 */ 263 */
265 264
@@ -274,7 +273,7 @@ void pnp_remove_card_device(struct pnp_dev * dev)
274 273
275/** 274/**
276 * pnp_request_card_device - Searches for a PnP device under the specified card 275 * pnp_request_card_device - Searches for a PnP device under the specified card
277 * @lcard: pointer to the card link, cannot be NULL 276 * @clink: pointer to the card link, cannot be NULL
278 * @id: pointer to a PnP ID structure that explains the rules for finding the device 277 * @id: pointer to a PnP ID structure that explains the rules for finding the device
279 * @from: Starting place to search from. If NULL it will start from the begining. 278 * @from: Starting place to search from. If NULL it will start from the begining.
280 */ 279 */
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 65ecef738537..6c510c19ad7d 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -390,6 +390,7 @@ fail:
390 * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table 390 * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
391 * @dev: pointer to the desired device 391 * @dev: pointer to the desired device
392 * @res: pointer to the new resource config 392 * @res: pointer to the new resource config
393 * @mode: 0 or PNP_CONFIG_FORCE
393 * 394 *
394 * This function can be used by drivers that want to manually set thier resources. 395 * This function can be used by drivers that want to manually set thier resources.
395 */ 396 */
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 16ab8d363ac6..6bc27d52326f 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -35,14 +35,17 @@
35static int dcssblk_open(struct inode *inode, struct file *filp); 35static int dcssblk_open(struct inode *inode, struct file *filp);
36static int dcssblk_release(struct inode *inode, struct file *filp); 36static int dcssblk_release(struct inode *inode, struct file *filp);
37static int dcssblk_make_request(struct request_queue *q, struct bio *bio); 37static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
38static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
39 unsigned long *data);
38 40
39static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0"; 41static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
40 42
41static int dcssblk_major; 43static int dcssblk_major;
42static struct block_device_operations dcssblk_devops = { 44static struct block_device_operations dcssblk_devops = {
43 .owner = THIS_MODULE, 45 .owner = THIS_MODULE,
44 .open = dcssblk_open, 46 .open = dcssblk_open,
45 .release = dcssblk_release, 47 .release = dcssblk_release,
48 .direct_access = dcssblk_direct_access,
46}; 49};
47 50
48static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf, 51static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
@@ -641,6 +644,20 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
641 /* Request beyond end of DCSS segment. */ 644 /* Request beyond end of DCSS segment. */
642 goto fail; 645 goto fail;
643 } 646 }
647 /* verify data transfer direction */
648 if (dev_info->is_shared) {
649 switch (dev_info->segment_type) {
650 case SEG_TYPE_SR:
651 case SEG_TYPE_ER:
652 case SEG_TYPE_SC:
653 /* cannot write to these segments */
654 if (bio_data_dir(bio) == WRITE) {
655 PRINT_WARN("rejecting write to ro segment %s\n", dev_info->dev.bus_id);
656 goto fail;
657 }
658 }
659 }
660
644 index = (bio->bi_sector >> 3); 661 index = (bio->bi_sector >> 3);
645 bio_for_each_segment(bvec, bio, i) { 662 bio_for_each_segment(bvec, bio, i) {
646 page_addr = (unsigned long) 663 page_addr = (unsigned long)
@@ -661,7 +678,26 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
661 bio_endio(bio, bytes_done, 0); 678 bio_endio(bio, bytes_done, 0);
662 return 0; 679 return 0;
663fail: 680fail:
664 bio_io_error(bio, bytes_done); 681 bio_io_error(bio, bio->bi_size);
682 return 0;
683}
684
685static int
686dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
687 unsigned long *data)
688{
689 struct dcssblk_dev_info *dev_info;
690 unsigned long pgoff;
691
692 dev_info = bdev->bd_disk->private_data;
693 if (!dev_info)
694 return -ENODEV;
695 if (secnum % (PAGE_SIZE/512))
696 return -EINVAL;
697 pgoff = secnum / (PAGE_SIZE / 512);
698 if ((pgoff+1)*PAGE_SIZE-1 > dev_info->end - dev_info->start)
699 return -ERANGE;
700 *data = (unsigned long) (dev_info->start+pgoff*PAGE_SIZE);
665 return 0; 701 return 0;
666} 702}
667 703
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 9cc0015b717d..a699c30b2662 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -1126,11 +1126,11 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
1126 struct adpt_i2o_post_wait_data *p1, *p2; 1126 struct adpt_i2o_post_wait_data *p1, *p2;
1127 struct adpt_i2o_post_wait_data *wait_data = 1127 struct adpt_i2o_post_wait_data *wait_data =
1128 kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL); 1128 kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
1129 adpt_wait_queue_t wait; 1129 DECLARE_WAITQUEUE(wait, current);
1130 1130
1131 if(!wait_data){ 1131 if (!wait_data)
1132 return -ENOMEM; 1132 return -ENOMEM;
1133 } 1133
1134 /* 1134 /*
1135 * The spin locking is needed to keep anyone from playing 1135 * The spin locking is needed to keep anyone from playing
1136 * with the queue pointers and id while we do the same 1136 * with the queue pointers and id while we do the same
@@ -1148,12 +1148,7 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
1148 wait_data->wq = &adpt_wq_i2o_post; 1148 wait_data->wq = &adpt_wq_i2o_post;
1149 wait_data->status = -ETIMEDOUT; 1149 wait_data->status = -ETIMEDOUT;
1150 1150
1151 // this code is taken from kernel/sched.c:interruptible_sleep_on_timeout 1151 add_wait_queue(&adpt_wq_i2o_post, &wait);
1152 wait.task = current;
1153 init_waitqueue_entry(&wait, current);
1154 spin_lock_irqsave(&adpt_wq_i2o_post.lock, flags);
1155 __add_wait_queue(&adpt_wq_i2o_post, &wait);
1156 spin_unlock(&adpt_wq_i2o_post.lock);
1157 1152
1158 msg[2] |= 0x80000000 | ((u32)wait_data->id); 1153 msg[2] |= 0x80000000 | ((u32)wait_data->id);
1159 timeout *= HZ; 1154 timeout *= HZ;
@@ -1175,9 +1170,7 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
1175 if(pHba->host) 1170 if(pHba->host)
1176 spin_lock_irq(pHba->host->host_lock); 1171 spin_lock_irq(pHba->host->host_lock);
1177 } 1172 }
1178 spin_lock_irq(&adpt_wq_i2o_post.lock); 1173 remove_wait_queue(&adpt_wq_i2o_post, &wait);
1179 __remove_wait_queue(&adpt_wq_i2o_post, &wait);
1180 spin_unlock_irqrestore(&adpt_wq_i2o_post.lock, flags);
1181 1174
1182 if(status == -ETIMEDOUT){ 1175 if(status == -ETIMEDOUT){
1183 printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit); 1176 printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index ba347576d99b..d7a38b6713f9 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -56,7 +56,7 @@ static struct class shost_class = {
56 * @shost: pointer to struct Scsi_Host 56 * @shost: pointer to struct Scsi_Host
57 * recovery: recovery requested to run. 57 * recovery: recovery requested to run.
58 **/ 58 **/
59void scsi_host_cancel(struct Scsi_Host *shost, int recovery) 59static void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
60{ 60{
61 struct scsi_device *sdev; 61 struct scsi_device *sdev;
62 62
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 5578ae9a9e45..1cb5f7d4f278 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -68,6 +68,8 @@
68#include "scsi_priv.h" 68#include "scsi_priv.h"
69#include "scsi_logging.h" 69#include "scsi_logging.h"
70 70
71static void scsi_done(struct scsi_cmnd *cmd);
72static int scsi_retry_command(struct scsi_cmnd *cmd);
71 73
72/* 74/*
73 * Definitions and constants. 75 * Definitions and constants.
@@ -741,7 +743,7 @@ static DEFINE_PER_CPU(struct list_head, scsi_done_q);
741 * 743 *
742 * This function is interrupt context safe. 744 * This function is interrupt context safe.
743 */ 745 */
744void scsi_done(struct scsi_cmnd *cmd) 746static void scsi_done(struct scsi_cmnd *cmd)
745{ 747{
746 /* 748 /*
747 * We don't have to worry about this one timing out any more. 749 * We don't have to worry about this one timing out any more.
@@ -836,7 +838,7 @@ static void scsi_softirq(struct softirq_action *h)
836 * level drivers should not become re-entrant as a result of 838 * level drivers should not become re-entrant as a result of
837 * this. 839 * this.
838 */ 840 */
839int scsi_retry_command(struct scsi_cmnd *cmd) 841static int scsi_retry_command(struct scsi_cmnd *cmd)
840{ 842{
841 /* 843 /*
842 * Restore the SCSI command state. 844 * Restore the SCSI command state.
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index e0208886b45e..322b5a41a36f 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1783,7 +1783,7 @@ static void __exit scsi_debug_exit(void)
1783device_initcall(scsi_debug_init); 1783device_initcall(scsi_debug_init);
1784module_exit(scsi_debug_exit); 1784module_exit(scsi_debug_exit);
1785 1785
1786void pseudo_0_release(struct device * dev) 1786static void pseudo_0_release(struct device * dev)
1787{ 1787{
1788 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 1788 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
1789 printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n"); 1789 printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9f996499fa9d..621dee8b8cb2 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
44#endif 44#endif
45 45
46#define SP(x) { x, "sgpool-" #x } 46#define SP(x) { x, "sgpool-" #x }
47struct scsi_host_sg_pool scsi_sg_pools[] = { 47static struct scsi_host_sg_pool scsi_sg_pools[] = {
48 SP(8), 48 SP(8),
49 SP(16), 49 SP(16),
50 SP(32), 50 SP(32),
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index c01580df4476..96d4f745975c 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -61,8 +61,6 @@ extern void scsi_exit_hosts(void);
61extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd); 61extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
62extern int scsi_setup_command_freelist(struct Scsi_Host *shost); 62extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
63extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); 63extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
64extern void scsi_done(struct scsi_cmnd *cmd);
65extern int scsi_retry_command(struct scsi_cmnd *cmd);
66extern int scsi_insert_special_req(struct scsi_request *sreq, int); 64extern int scsi_insert_special_req(struct scsi_request *sreq, int);
67extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, 65extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
68 struct scsi_request *sreq); 66 struct scsi_request *sreq);
@@ -136,7 +134,6 @@ extern void scsi_exit_sysctl(void);
136#endif /* CONFIG_SYSCTL */ 134#endif /* CONFIG_SYSCTL */
137 135
138/* scsi_sysfs.c */ 136/* scsi_sysfs.c */
139extern void scsi_device_dev_release(struct device *);
140extern int scsi_sysfs_add_sdev(struct scsi_device *); 137extern int scsi_sysfs_add_sdev(struct scsi_device *);
141extern int scsi_sysfs_add_host(struct Scsi_Host *); 138extern int scsi_sysfs_add_host(struct Scsi_Host *);
142extern int scsi_sysfs_register(void); 139extern int scsi_sysfs_register(void);
@@ -145,7 +142,6 @@ extern void scsi_sysfs_device_initialize(struct scsi_device *);
145extern int scsi_sysfs_target_initialize(struct scsi_device *); 142extern int scsi_sysfs_target_initialize(struct scsi_device *);
146extern struct scsi_transport_template blank_transport_template; 143extern struct scsi_transport_template blank_transport_template;
147 144
148extern struct class sdev_class;
149extern struct bus_type scsi_bus_type; 145extern struct bus_type scsi_bus_type;
150 146
151/* 147/*
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 93b41100a6d8..beed7fbe1cbe 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -150,7 +150,7 @@ static void scsi_device_cls_release(struct class_device *class_dev)
150 put_device(&sdev->sdev_gendev); 150 put_device(&sdev->sdev_gendev);
151} 151}
152 152
153void scsi_device_dev_release(struct device *dev) 153static void scsi_device_dev_release(struct device *dev)
154{ 154{
155 struct scsi_device *sdev; 155 struct scsi_device *sdev;
156 struct device *parent; 156 struct device *parent;
@@ -185,7 +185,7 @@ void scsi_device_dev_release(struct device *dev)
185 put_device(parent); 185 put_device(parent);
186} 186}
187 187
188struct class sdev_class = { 188static struct class sdev_class = {
189 .name = "scsi_device", 189 .name = "scsi_device",
190 .release = scsi_device_cls_release, 190 .release = scsi_device_cls_release,
191}; 191};
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 30e8beb71430..d8b9d2b8c200 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -132,9 +132,9 @@ struct uart_8250_port {
132 struct uart_port port; 132 struct uart_port port;
133 struct timer_list timer; /* "no irq" timer */ 133 struct timer_list timer; /* "no irq" timer */
134 struct list_head list; /* ports on this IRQ */ 134 struct list_head list; /* ports on this IRQ */
135 unsigned int capabilities; /* port capabilities */ 135 unsigned short capabilities; /* port capabilities */
136 unsigned short bugs; /* port bugs */
136 unsigned int tx_loadsz; /* transmit fifo load size */ 137 unsigned int tx_loadsz; /* transmit fifo load size */
137 unsigned short rev;
138 unsigned char acr; 138 unsigned char acr;
139 unsigned char ier; 139 unsigned char ier;
140 unsigned char lcr; 140 unsigned char lcr;
@@ -560,7 +560,14 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
560 if (id1 == 0x16 && id2 == 0xC9 && 560 if (id1 == 0x16 && id2 == 0xC9 &&
561 (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) { 561 (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
562 up->port.type = PORT_16C950; 562 up->port.type = PORT_16C950;
563 up->rev = rev | (id3 << 8); 563
564 /*
565 * Enable work around for the Oxford Semiconductor 952 rev B
566 * chip which causes it to seriously miscalculate baud rates
567 * when DLL is 0.
568 */
569 if (id3 == 0x52 && rev == 0x01)
570 up->bugs |= UART_BUG_QUOT;
564 return; 571 return;
565 } 572 }
566 573
@@ -577,8 +584,6 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
577 584
578 id2 = id1 >> 8; 585 id2 = id1 >> 8;
579 if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) { 586 if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
580 if (id2 == 0x10)
581 up->rev = id1 & 255;
582 up->port.type = PORT_16850; 587 up->port.type = PORT_16850;
583 return; 588 return;
584 } 589 }
@@ -809,6 +814,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
809// save_flags(flags); cli(); 814// save_flags(flags); cli();
810 815
811 up->capabilities = 0; 816 up->capabilities = 0;
817 up->bugs = 0;
812 818
813 if (!(up->port.flags & UPF_BUGGY_UART)) { 819 if (!(up->port.flags & UPF_BUGGY_UART)) {
814 /* 820 /*
@@ -1021,6 +1027,8 @@ static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
1021 } 1027 }
1022} 1028}
1023 1029
1030static void transmit_chars(struct uart_8250_port *up);
1031
1024static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) 1032static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
1025{ 1033{
1026 struct uart_8250_port *up = (struct uart_8250_port *)port; 1034 struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1028,6 +1036,14 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
1028 if (!(up->ier & UART_IER_THRI)) { 1036 if (!(up->ier & UART_IER_THRI)) {
1029 up->ier |= UART_IER_THRI; 1037 up->ier |= UART_IER_THRI;
1030 serial_out(up, UART_IER, up->ier); 1038 serial_out(up, UART_IER, up->ier);
1039
1040 if (up->bugs & UART_BUG_TXEN) {
1041 unsigned char lsr, iir;
1042 lsr = serial_in(up, UART_LSR);
1043 iir = serial_in(up, UART_IIR);
1044 if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)
1045 transmit_chars(up);
1046 }
1031 } 1047 }
1032 /* 1048 /*
1033 * We only do this from uart_start 1049 * We only do this from uart_start
@@ -1433,6 +1449,7 @@ static int serial8250_startup(struct uart_port *port)
1433{ 1449{
1434 struct uart_8250_port *up = (struct uart_8250_port *)port; 1450 struct uart_8250_port *up = (struct uart_8250_port *)port;
1435 unsigned long flags; 1451 unsigned long flags;
1452 unsigned char lsr, iir;
1436 int retval; 1453 int retval;
1437 1454
1438 up->capabilities = uart_config[up->port.type].flags; 1455 up->capabilities = uart_config[up->port.type].flags;
@@ -1536,6 +1553,26 @@ static int serial8250_startup(struct uart_port *port)
1536 up->port.mctrl |= TIOCM_OUT2; 1553 up->port.mctrl |= TIOCM_OUT2;
1537 1554
1538 serial8250_set_mctrl(&up->port, up->port.mctrl); 1555 serial8250_set_mctrl(&up->port, up->port.mctrl);
1556
1557 /*
1558 * Do a quick test to see if we receive an
1559 * interrupt when we enable the TX irq.
1560 */
1561 serial_outp(up, UART_IER, UART_IER_THRI);
1562 lsr = serial_in(up, UART_LSR);
1563 iir = serial_in(up, UART_IIR);
1564 serial_outp(up, UART_IER, 0);
1565
1566 if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
1567 if (!(up->bugs & UART_BUG_TXEN)) {
1568 up->bugs |= UART_BUG_TXEN;
1569 pr_debug("ttyS%d - enabling bad tx status workarounds\n",
1570 port->line);
1571 }
1572 } else {
1573 up->bugs &= ~UART_BUG_TXEN;
1574 }
1575
1539 spin_unlock_irqrestore(&up->port.lock, flags); 1576 spin_unlock_irqrestore(&up->port.lock, flags);
1540 1577
1541 /* 1578 /*
@@ -1645,22 +1682,22 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
1645 1682
1646 switch (termios->c_cflag & CSIZE) { 1683 switch (termios->c_cflag & CSIZE) {
1647 case CS5: 1684 case CS5:
1648 cval = 0x00; 1685 cval = UART_LCR_WLEN5;
1649 break; 1686 break;
1650 case CS6: 1687 case CS6:
1651 cval = 0x01; 1688 cval = UART_LCR_WLEN6;
1652 break; 1689 break;
1653 case CS7: 1690 case CS7:
1654 cval = 0x02; 1691 cval = UART_LCR_WLEN7;
1655 break; 1692 break;
1656 default: 1693 default:
1657 case CS8: 1694 case CS8:
1658 cval = 0x03; 1695 cval = UART_LCR_WLEN8;
1659 break; 1696 break;
1660 } 1697 }
1661 1698
1662 if (termios->c_cflag & CSTOPB) 1699 if (termios->c_cflag & CSTOPB)
1663 cval |= 0x04; 1700 cval |= UART_LCR_STOP;
1664 if (termios->c_cflag & PARENB) 1701 if (termios->c_cflag & PARENB)
1665 cval |= UART_LCR_PARITY; 1702 cval |= UART_LCR_PARITY;
1666 if (!(termios->c_cflag & PARODD)) 1703 if (!(termios->c_cflag & PARODD))
@@ -1677,12 +1714,9 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
1677 quot = serial8250_get_divisor(port, baud); 1714 quot = serial8250_get_divisor(port, baud);
1678 1715
1679 /* 1716 /*
1680 * Work around a bug in the Oxford Semiconductor 952 rev B 1717 * Oxford Semi 952 rev B workaround
1681 * chip which causes it to seriously miscalculate baud rates
1682 * when DLL is 0.
1683 */ 1718 */
1684 if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 && 1719 if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
1685 up->rev == 0x5201)
1686 quot ++; 1720 quot ++;
1687 1721
1688 if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) { 1722 if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 4f3d62f222f4..9225c82faeb8 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -51,6 +51,9 @@ struct serial8250_config {
51#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */ 51#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
52#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ 52#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
53 53
54#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
55#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
56
54#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) 57#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
55#define _INLINE_ inline 58#define _INLINE_ inline
56#else 59#else
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index b6d3d5034940..5400dc2c087e 100644
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -773,22 +773,22 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
773 773
774 switch (termios->c_cflag & CSIZE) { 774 switch (termios->c_cflag & CSIZE) {
775 case CS5: 775 case CS5:
776 cval = 0x00; 776 cval = UART_LCR_WLEN5;
777 break; 777 break;
778 case CS6: 778 case CS6:
779 cval = 0x01; 779 cval = UART_LCR_WLEN6;
780 break; 780 break;
781 case CS7: 781 case CS7:
782 cval = 0x02; 782 cval = UART_LCR_WLEN7;
783 break; 783 break;
784 default: 784 default:
785 case CS8: 785 case CS8:
786 cval = 0x03; 786 cval = UART_LCR_WLEN8;
787 break; 787 break;
788 } 788 }
789 789
790 if (termios->c_cflag & CSTOPB) 790 if (termios->c_cflag & CSTOPB)
791 cval |= 0x04; 791 cval |= UART_LCR_STOP;
792 if (termios->c_cflag & PARENB) 792 if (termios->c_cflag & PARENB)
793 cval |= UART_LCR_PARITY; 793 cval |= UART_LCR_PARITY;
794 if (!(termios->c_cflag & PARODD)) 794 if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 08d61f13edc6..0301feacbde4 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -724,22 +724,22 @@ static void m32r_sio_set_termios(struct uart_port *port,
724 724
725 switch (termios->c_cflag & CSIZE) { 725 switch (termios->c_cflag & CSIZE) {
726 case CS5: 726 case CS5:
727 cval = 0x00; 727 cval = UART_LCR_WLEN5;
728 break; 728 break;
729 case CS6: 729 case CS6:
730 cval = 0x01; 730 cval = UART_LCR_WLEN6;
731 break; 731 break;
732 case CS7: 732 case CS7:
733 cval = 0x02; 733 cval = UART_LCR_WLEN7;
734 break; 734 break;
735 default: 735 default:
736 case CS8: 736 case CS8:
737 cval = 0x03; 737 cval = UART_LCR_WLEN8;
738 break; 738 break;
739 } 739 }
740 740
741 if (termios->c_cflag & CSTOPB) 741 if (termios->c_cflag & CSTOPB)
742 cval |= 0x04; 742 cval |= UART_LCR_STOP;
743 if (termios->c_cflag & PARENB) 743 if (termios->c_cflag & PARENB)
744 cval |= UART_LCR_PARITY; 744 cval |= UART_LCR_PARITY;
745 if (!(termios->c_cflag & PARODD)) 745 if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 9dc151d8fa61..08b08d6ae904 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -455,22 +455,22 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
455 455
456 switch (termios->c_cflag & CSIZE) { 456 switch (termios->c_cflag & CSIZE) {
457 case CS5: 457 case CS5:
458 cval = 0x00; 458 cval = UART_LCR_WLEN5;
459 break; 459 break;
460 case CS6: 460 case CS6:
461 cval = 0x01; 461 cval = UART_LCR_WLEN6;
462 break; 462 break;
463 case CS7: 463 case CS7:
464 cval = 0x02; 464 cval = UART_LCR_WLEN7;
465 break; 465 break;
466 default: 466 default:
467 case CS8: 467 case CS8:
468 cval = 0x03; 468 cval = UART_LCR_WLEN8;
469 break; 469 break;
470 } 470 }
471 471
472 if (termios->c_cflag & CSTOPB) 472 if (termios->c_cflag & CSTOPB)
473 cval |= 0x04; 473 cval |= UART_LCR_STOP;
474 if (termios->c_cflag & PARENB) 474 if (termios->c_cflag & PARENB)
475 cval |= UART_LCR_PARITY; 475 cval |= UART_LCR_PARITY;
476 if (!(termios->c_cflag & PARODD)) 476 if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 2a9f7ade2c9d..5c4678478b1d 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -198,7 +198,7 @@ static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
198 198
199/* translate a port to the device name */ 199/* translate a port to the device name */
200 200
201static inline char *s3c24xx_serial_portname(struct uart_port *port) 201static inline const char *s3c24xx_serial_portname(struct uart_port *port)
202{ 202{
203 return to_platform_device(port->dev)->name; 203 return to_platform_device(port->dev)->name;
204} 204}
@@ -903,7 +903,7 @@ static void s3c24xx_serial_release_port(struct uart_port *port)
903 903
904static int s3c24xx_serial_request_port(struct uart_port *port) 904static int s3c24xx_serial_request_port(struct uart_port *port)
905{ 905{
906 char *name = s3c24xx_serial_portname(port); 906 const char *name = s3c24xx_serial_portname(port);
907 return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY; 907 return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
908} 908}
909 909
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index fee6418e84c4..840815fde49b 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -572,6 +572,7 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw)
572 572
573 if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) { 573 if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) {
574 /* Nothing to do. */ 574 /* Nothing to do. */
575 ia64_sn_console_intr_disable(SAL_CONSOLE_INTR_XMIT);
575 return; 576 return;
576 } 577 }
577 578
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index d041782e0c8b..0da23732e807 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1794,7 +1794,7 @@ EXPORT_SYMBOL (usb_remove_hcd);
1794 1794
1795/*-------------------------------------------------------------------------*/ 1795/*-------------------------------------------------------------------------*/
1796 1796
1797#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) 1797#if defined(CONFIG_USB_MON)
1798 1798
1799struct usb_mon_operations *mon_ops; 1799struct usb_mon_operations *mon_ops;
1800 1800
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index f67cf1e634fc..325a51656c3f 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -399,7 +399,7 @@ static inline void usbfs_cleanup(void) { }
399 399
400/*-------------------------------------------------------------------------*/ 400/*-------------------------------------------------------------------------*/
401 401
402#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) 402#if defined(CONFIG_USB_MON)
403 403
404struct usb_mon_operations { 404struct usb_mon_operations {
405 void (*urb_submit)(struct usb_bus *bus, struct urb *urb); 405 void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index f9f9561c6bad..c3e3a95d3804 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -453,17 +453,6 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
453 return 0; 453 return 0;
454} 454}
455 455
456static struct dentry * get_dentry(struct dentry *parent, const char *name)
457{
458 struct qstr qstr;
459
460 qstr.name = name;
461 qstr.len = strlen(name);
462 qstr.hash = full_name_hash(name,qstr.len);
463 return lookup_hash(&qstr,parent);
464}
465
466
467/* 456/*
468 * fs_create_by_name - create a file, given a name 457 * fs_create_by_name - create a file, given a name
469 * @name: name of file 458 * @name: name of file
@@ -496,7 +485,7 @@ static int fs_create_by_name (const char *name, mode_t mode,
496 485
497 *dentry = NULL; 486 *dentry = NULL;
498 down(&parent->d_inode->i_sem); 487 down(&parent->d_inode->i_sem);
499 *dentry = get_dentry (parent, name); 488 *dentry = lookup_one_len(name, parent, strlen(name));
500 if (!IS_ERR(dentry)) { 489 if (!IS_ERR(dentry)) {
501 if ((mode & S_IFMT) == S_IFDIR) 490 if ((mode & S_IFMT) == S_IFDIR)
502 error = usbfs_mkdir (parent->d_inode, *dentry, mode); 491 error = usbfs_mkdir (parent->d_inode, *dentry, mode);
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c
index bc3b1635eab0..ef4204eab6c4 100644
--- a/drivers/usb/media/pwc/pwc-uncompress.c
+++ b/drivers/usb/media/pwc/pwc-uncompress.c
@@ -118,9 +118,9 @@ int pwc_decompress(struct pwc_device *pdev)
118 return -ENXIO; /* No such device or address: missing decompressor */ 118 return -ENXIO; /* No such device or address: missing decompressor */
119 } 119 }
120 120
121#if 0
121 switch (pdev->type) 122 switch (pdev->type)
122 { 123 {
123#if 0
124 case 675: 124 case 675:
125 case 680: 125 case 680:
126 case 690: 126 case 690:
@@ -128,18 +128,17 @@ int pwc_decompress(struct pwc_device *pdev)
128 case 730: 128 case 730:
129 case 740: 129 case 740:
130 case 750: 130 case 750:
131 pwc_dec23_decompress(&pdev->image, &pdev->view, &pdev->offset, 131 pwc_dec23_decompress(&pdev->image, &pdev->view,
132 yuv, image, 132 &pdev->offset, yuv, image, flags,
133 flags,
134 pdev->decompress_data, pdev->vbandlength); 133 pdev->decompress_data, pdev->vbandlength);
135 break; 134 break;
136 case 645: 135 case 645:
137 case 646: 136 case 646:
138 /* TODO & FIXME */ 137 /* TODO & FIXME */
139#endif 138 return -ENXIO; /* Missing decompressor */
140 return -ENXIO; /* No such device or address: missing decompressor */
141 break; 139 break;
142 } 140 }
141#endif
143 } 142 }
144 return 0; 143 return 0;
145} 144}
diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig
index 4e6152aa5f19..777642e26b9a 100644
--- a/drivers/usb/mon/Kconfig
+++ b/drivers/usb/mon/Kconfig
@@ -2,13 +2,9 @@
2# USB Monitor configuration 2# USB Monitor configuration
3# 3#
4 4
5# In normal life, it makes little sense to have usbmon as a module, and in fact
6# it is harmful, because there is no way to autoload the module.
7# The 'm' option is allowed for hackers who debug the usbmon itself,
8# and for those who have usbcore as a module.
9config USB_MON 5config USB_MON
10 tristate "USB Monitor" 6 bool "USB Monitor"
11 depends on USB 7 depends on USB!=n
12 default y 8 default y
13 help 9 help
14 If you say Y here, a component which captures the USB traffic 10 If you say Y here, a component which captures the USB traffic
@@ -17,6 +13,5 @@ config USB_MON
17 Harding's USBMon. 13 Harding's USBMon.
18 14
19 This is somewhat experimental at this time, but it should be safe, 15 This is somewhat experimental at this time, but it should be safe,
20 as long as you aren't building this as a module and then removing it. 16 as long as you aren't using modular USB and try to remove this
21 17 module.
22 If unsure, say Y. Do not say M.
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile
index 3cff8d444bb1..f18d10ce91f9 100644
--- a/drivers/usb/mon/Makefile
+++ b/drivers/usb/mon/Makefile
@@ -4,4 +4,4 @@
4 4
5usbmon-objs := mon_main.o mon_stat.o mon_text.o 5usbmon-objs := mon_main.o mon_stat.o mon_text.o
6 6
7obj-$(CONFIG_USB_MON) += usbmon.o 7obj-$(CONFIG_USB) += usbmon.o
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 815fbc8317fc..16e37a535d85 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -43,6 +43,7 @@
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/irq.h> 44#include <asm/irq.h>
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
46#include <asm/div64.h>
46#include <asm/arch/pxa-regs.h> 47#include <asm/arch/pxa-regs.h>
47#include <asm/arch/bitfield.h> 48#include <asm/arch/bitfield.h>
48#include <asm/arch/pxafb.h> 49#include <asm/arch/pxafb.h>
@@ -460,7 +461,7 @@ static inline unsigned int get_pcd(unsigned int pixclock)
460 * speeds */ 461 * speeds */
461 462
462 pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock; 463 pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
463 pcd /= 100000000 * 2; 464 do_div(pcd, 100000000 * 2);
464 /* no need for this, since we should subtract 1 anyway. they cancel */ 465 /* no need for this, since we should subtract 1 anyway. they cancel */
465 /* pcd += 1; */ /* make up for integer math truncations */ 466 /* pcd += 1; */ /* make up for integer math truncations */
466 return (unsigned int)pcd; 467 return (unsigned int)pcd;
diff --git a/fs/Kconfig b/fs/Kconfig
index a7c0cc3203cb..8157f2e2d515 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -50,6 +50,23 @@ config EXT2_FS_SECURITY
50 If you are not using a security module that requires using 50 If you are not using a security module that requires using
51 extended attributes for file security labels, say N. 51 extended attributes for file security labels, say N.
52 52
53config EXT2_FS_XIP
54 bool "Ext2 execute in place support"
55 depends on EXT2_FS
56 help
57 Execute in place can be used on memory-backed block devices. If you
58 enable this option, you can select to mount block devices which are
59 capable of this feature without using the page cache.
60
61 If you do not use a block device that is capable of using this,
62 or if unsure, say N.
63
64config FS_XIP
65# execute in place
66 bool
67 depends on EXT2_FS_XIP
68 default y
69
53config EXT3_FS 70config EXT3_FS
54 tristate "Ext3 journalling file system support" 71 tristate "Ext3 journalling file system support"
55 help 72 help
@@ -1413,6 +1430,8 @@ config NFSD_V4
1413 bool "Provide NFSv4 server support (EXPERIMENTAL)" 1430 bool "Provide NFSv4 server support (EXPERIMENTAL)"
1414 depends on NFSD_V3 && EXPERIMENTAL 1431 depends on NFSD_V3 && EXPERIMENTAL
1415 select NFSD_TCP 1432 select NFSD_TCP
1433 select CRYPTO_MD5
1434 select CRYPTO
1416 help 1435 help
1417 If you would like to include the NFSv4 server as well as the NFSv2 1436 If you would like to include the NFSv4 server as well as the NFSv2
1418 and NFSv3 servers, say Y here. This feature is experimental, and 1437 and NFSv3 servers, say Y here. This feature is experimental, and
diff --git a/fs/block_dev.c b/fs/block_dev.c
index c0cbd1bc1a02..e0df94c37b7e 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -777,8 +777,7 @@ static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char __user *buf,
777 return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); 777 return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
778} 778}
779 779
780static int block_ioctl(struct inode *inode, struct file *file, unsigned cmd, 780static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
781 unsigned long arg)
782{ 781{
783 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); 782 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
784} 783}
@@ -803,7 +802,7 @@ struct file_operations def_blk_fops = {
803 .aio_write = blkdev_file_aio_write, 802 .aio_write = blkdev_file_aio_write,
804 .mmap = generic_file_mmap, 803 .mmap = generic_file_mmap,
805 .fsync = block_fsync, 804 .fsync = block_fsync,
806 .ioctl = block_ioctl, 805 .unlocked_ioctl = block_ioctl,
807#ifdef CONFIG_COMPAT 806#ifdef CONFIG_COMPAT
808 .compat_ioctl = compat_blkdev_ioctl, 807 .compat_ioctl = compat_blkdev_ioctl,
809#endif 808#endif
diff --git a/fs/buffer.c b/fs/buffer.c
index 0befa724ab98..13e5938a64f6 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -331,7 +331,7 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
331 return ret; 331 return ret;
332} 332}
333 333
334asmlinkage long sys_fsync(unsigned int fd) 334static long do_fsync(unsigned int fd, int datasync)
335{ 335{
336 struct file * file; 336 struct file * file;
337 struct address_space *mapping; 337 struct address_space *mapping;
@@ -342,14 +342,14 @@ asmlinkage long sys_fsync(unsigned int fd)
342 if (!file) 342 if (!file)
343 goto out; 343 goto out;
344 344
345 mapping = file->f_mapping;
346
347 ret = -EINVAL; 345 ret = -EINVAL;
348 if (!file->f_op || !file->f_op->fsync) { 346 if (!file->f_op || !file->f_op->fsync) {
349 /* Why? We can still call filemap_fdatawrite */ 347 /* Why? We can still call filemap_fdatawrite */
350 goto out_putf; 348 goto out_putf;
351 } 349 }
352 350
351 mapping = file->f_mapping;
352
353 current->flags |= PF_SYNCWRITE; 353 current->flags |= PF_SYNCWRITE;
354 ret = filemap_fdatawrite(mapping); 354 ret = filemap_fdatawrite(mapping);
355 355
@@ -358,7 +358,7 @@ asmlinkage long sys_fsync(unsigned int fd)
358 * which could cause livelocks in fsync_buffers_list 358 * which could cause livelocks in fsync_buffers_list
359 */ 359 */
360 down(&mapping->host->i_sem); 360 down(&mapping->host->i_sem);
361 err = file->f_op->fsync(file, file->f_dentry, 0); 361 err = file->f_op->fsync(file, file->f_dentry, datasync);
362 if (!ret) 362 if (!ret)
363 ret = err; 363 ret = err;
364 up(&mapping->host->i_sem); 364 up(&mapping->host->i_sem);
@@ -373,39 +373,14 @@ out:
373 return ret; 373 return ret;
374} 374}
375 375
376asmlinkage long sys_fdatasync(unsigned int fd) 376asmlinkage long sys_fsync(unsigned int fd)
377{ 377{
378 struct file * file; 378 return do_fsync(fd, 0);
379 struct address_space *mapping; 379}
380 int ret, err;
381
382 ret = -EBADF;
383 file = fget(fd);
384 if (!file)
385 goto out;
386
387 ret = -EINVAL;
388 if (!file->f_op || !file->f_op->fsync)
389 goto out_putf;
390
391 mapping = file->f_mapping;
392
393 current->flags |= PF_SYNCWRITE;
394 ret = filemap_fdatawrite(mapping);
395 down(&mapping->host->i_sem);
396 err = file->f_op->fsync(file, file->f_dentry, 1);
397 if (!ret)
398 ret = err;
399 up(&mapping->host->i_sem);
400 err = filemap_fdatawait(mapping);
401 if (!ret)
402 ret = err;
403 current->flags &= ~PF_SYNCWRITE;
404 380
405out_putf: 381asmlinkage long sys_fdatasync(unsigned int fd)
406 fput(file); 382{
407out: 383 return do_fsync(fd, 1);
408 return ret;
409} 384}
410 385
411/* 386/*
@@ -1951,7 +1926,6 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
1951 if (err) 1926 if (err)
1952 break; 1927 break;
1953 if (buffer_new(bh)) { 1928 if (buffer_new(bh)) {
1954 clear_buffer_new(bh);
1955 unmap_underlying_metadata(bh->b_bdev, 1929 unmap_underlying_metadata(bh->b_bdev,
1956 bh->b_blocknr); 1930 bh->b_blocknr);
1957 if (PageUptodate(page)) { 1931 if (PageUptodate(page)) {
@@ -1993,9 +1967,14 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
1993 if (!buffer_uptodate(*wait_bh)) 1967 if (!buffer_uptodate(*wait_bh))
1994 err = -EIO; 1968 err = -EIO;
1995 } 1969 }
1996 if (!err) 1970 if (!err) {
1997 return err; 1971 bh = head;
1998 1972 do {
1973 if (buffer_new(bh))
1974 clear_buffer_new(bh);
1975 } while ((bh = bh->b_this_page) != head);
1976 return 0;
1977 }
1999 /* Error case: */ 1978 /* Error case: */
2000 /* 1979 /*
2001 * Zero out any newly allocated blocks to avoid exposing stale 1980 * Zero out any newly allocated blocks to avoid exposing stale
diff --git a/fs/char_dev.c b/fs/char_dev.c
index c1e3537909fc..e82aac9cc2f5 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -56,10 +56,21 @@ int get_chrdev_list(char *page)
56 56
57 down(&chrdevs_lock); 57 down(&chrdevs_lock);
58 for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) { 58 for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
59 for (cd = chrdevs[i]; cd; cd = cd->next) 59 for (cd = chrdevs[i]; cd; cd = cd->next) {
60 /*
61 * if the current name, plus the 5 extra characters
62 * in the device line for this entry
63 * would run us off the page, we're done
64 */
65 if ((len+strlen(cd->name) + 5) >= PAGE_SIZE)
66 goto page_full;
67
68
60 len += sprintf(page+len, "%3d %s\n", 69 len += sprintf(page+len, "%3d %s\n",
61 cd->major, cd->name); 70 cd->major, cd->name);
71 }
62 } 72 }
73page_full:
63 up(&chrdevs_lock); 74 up(&chrdevs_lock);
64 75
65 return len; 76 return len;
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index b529786699e7..a86ac4aeaedb 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -110,16 +110,6 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
110 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); 110 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
111} 111}
112 112
113static struct dentry * get_dentry(struct dentry *parent, const char *name)
114{
115 struct qstr qstr;
116
117 qstr.name = name;
118 qstr.len = strlen(name);
119 qstr.hash = full_name_hash(name,qstr.len);
120 return lookup_hash(&qstr,parent);
121}
122
123static struct super_block *debug_get_sb(struct file_system_type *fs_type, 113static struct super_block *debug_get_sb(struct file_system_type *fs_type,
124 int flags, const char *dev_name, 114 int flags, const char *dev_name,
125 void *data) 115 void *data)
@@ -157,7 +147,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
157 147
158 *dentry = NULL; 148 *dentry = NULL;
159 down(&parent->d_inode->i_sem); 149 down(&parent->d_inode->i_sem);
160 *dentry = get_dentry (parent, name); 150 *dentry = lookup_one_len(name, parent, strlen(name));
161 if (!IS_ERR(dentry)) { 151 if (!IS_ERR(dentry)) {
162 if ((mode & S_IFMT) == S_IFDIR) 152 if ((mode & S_IFMT) == S_IFDIR)
163 error = debugfs_mkdir(parent->d_inode, *dentry, mode); 153 error = debugfs_mkdir(parent->d_inode, *dentry, mode);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 1d55e7e67342..0d06097bc995 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -215,7 +215,7 @@ static struct page *dio_get_page(struct dio *dio)
215static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes) 215static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes)
216{ 216{
217 if (dio->end_io && dio->result) 217 if (dio->end_io && dio->result)
218 dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private); 218 dio->end_io(dio->iocb, offset, bytes, dio->map_bh.b_private);
219 if (dio->lock_type == DIO_LOCKING) 219 if (dio->lock_type == DIO_LOCKING)
220 up_read(&dio->inode->i_alloc_sem); 220 up_read(&dio->inode->i_alloc_sem);
221} 221}
diff --git a/fs/dquot.c b/fs/dquot.c
index 3995ce7907cc..37212b039a4a 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1519,14 +1519,22 @@ out_path:
1519 * This function is used when filesystem needs to initialize quotas 1519 * This function is used when filesystem needs to initialize quotas
1520 * during mount time. 1520 * during mount time.
1521 */ 1521 */
1522int vfs_quota_on_mount(int type, int format_id, struct dentry *dentry) 1522int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
1523 int format_id, int type)
1523{ 1524{
1525 struct dentry *dentry;
1524 int error; 1526 int error;
1525 1527
1528 dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
1529 if (IS_ERR(dentry))
1530 return PTR_ERR(dentry);
1531
1526 error = security_quota_on(dentry); 1532 error = security_quota_on(dentry);
1527 if (error) 1533 if (!error)
1528 return error; 1534 error = vfs_quota_on_inode(dentry->d_inode, type, format_id);
1529 return vfs_quota_on_inode(dentry->d_inode, type, format_id); 1535
1536 dput(dentry);
1537 return error;
1530} 1538}
1531 1539
1532/* Generic routine for getting common part of quota structure */ 1540/* Generic routine for getting common part of quota structure */
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 9900e333655a..6ab1dd0ca904 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -101,57 +101,6 @@
101/* Maximum number of poll wake up nests we are allowing */ 101/* Maximum number of poll wake up nests we are allowing */
102#define EP_MAX_POLLWAKE_NESTS 4 102#define EP_MAX_POLLWAKE_NESTS 4
103 103
104/* Macro to allocate a "struct epitem" from the slab cache */
105#define EPI_MEM_ALLOC() (struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
106
107/* Macro to free a "struct epitem" to the slab cache */
108#define EPI_MEM_FREE(p) kmem_cache_free(epi_cache, p)
109
110/* Macro to allocate a "struct eppoll_entry" from the slab cache */
111#define PWQ_MEM_ALLOC() (struct eppoll_entry *) kmem_cache_alloc(pwq_cache, SLAB_KERNEL)
112
113/* Macro to free a "struct eppoll_entry" to the slab cache */
114#define PWQ_MEM_FREE(p) kmem_cache_free(pwq_cache, p)
115
116/* Fast test to see if the file is an evenpoll file */
117#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
118
119/* Setup the structure that is used as key for the rb-tree */
120#define EP_SET_FFD(p, f, d) do { (p)->file = (f); (p)->fd = (d); } while (0)
121
122/* Compare rb-tree keys */
123#define EP_CMP_FFD(p1, p2) ((p1)->file > (p2)->file ? +1: \
124 ((p1)->file < (p2)->file ? -1: (p1)->fd - (p2)->fd))
125
126/* Special initialization for the rb-tree node to detect linkage */
127#define EP_RB_INITNODE(n) (n)->rb_parent = (n)
128
129/* Removes a node from the rb-tree and marks it for a fast is-linked check */
130#define EP_RB_ERASE(n, r) do { rb_erase(n, r); (n)->rb_parent = (n); } while (0)
131
132/* Fast check to verify that the item is linked to the main rb-tree */
133#define EP_RB_LINKED(n) ((n)->rb_parent != (n))
134
135/*
136 * Remove the item from the list and perform its initialization.
137 * This is useful for us because we can test if the item is linked
138 * using "EP_IS_LINKED(p)".
139 */
140#define EP_LIST_DEL(p) do { list_del(p); INIT_LIST_HEAD(p); } while (0)
141
142/* Tells us if the item is currently linked */
143#define EP_IS_LINKED(p) (!list_empty(p))
144
145/* Get the "struct epitem" from a wait queue pointer */
146#define EP_ITEM_FROM_WAIT(p) ((struct epitem *) container_of(p, struct eppoll_entry, wait)->base)
147
148/* Get the "struct epitem" from an epoll queue wrapper */
149#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
150
151/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
152#define EP_OP_HASH_EVENT(op) ((op) != EPOLL_CTL_DEL)
153
154
155struct epoll_filefd { 104struct epoll_filefd {
156 struct file *file; 105 struct file *file;
157 int fd; 106 int fd;
@@ -357,6 +306,82 @@ static struct dentry_operations eventpollfs_dentry_operations = {
357 306
358 307
359 308
309/* Fast test to see if the file is an evenpoll file */
310static inline int is_file_epoll(struct file *f)
311{
312 return f->f_op == &eventpoll_fops;
313}
314
315/* Setup the structure that is used as key for the rb-tree */
316static inline void ep_set_ffd(struct epoll_filefd *ffd,
317 struct file *file, int fd)
318{
319 ffd->file = file;
320 ffd->fd = fd;
321}
322
323/* Compare rb-tree keys */
324static inline int ep_cmp_ffd(struct epoll_filefd *p1,
325 struct epoll_filefd *p2)
326{
327 return (p1->file > p2->file ? +1:
328 (p1->file < p2->file ? -1 : p1->fd - p2->fd));
329}
330
331/* Special initialization for the rb-tree node to detect linkage */
332static inline void ep_rb_initnode(struct rb_node *n)
333{
334 n->rb_parent = n;
335}
336
337/* Removes a node from the rb-tree and marks it for a fast is-linked check */
338static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r)
339{
340 rb_erase(n, r);
341 n->rb_parent = n;
342}
343
344/* Fast check to verify that the item is linked to the main rb-tree */
345static inline int ep_rb_linked(struct rb_node *n)
346{
347 return n->rb_parent != n;
348}
349
350/*
351 * Remove the item from the list and perform its initialization.
352 * This is useful for us because we can test if the item is linked
353 * using "ep_is_linked(p)".
354 */
355static inline void ep_list_del(struct list_head *p)
356{
357 list_del(p);
358 INIT_LIST_HEAD(p);
359}
360
361/* Tells us if the item is currently linked */
362static inline int ep_is_linked(struct list_head *p)
363{
364 return !list_empty(p);
365}
366
367/* Get the "struct epitem" from a wait queue pointer */
368static inline struct epitem * ep_item_from_wait(wait_queue_t *p)
369{
370 return container_of(p, struct eppoll_entry, wait)->base;
371}
372
373/* Get the "struct epitem" from an epoll queue wrapper */
374static inline struct epitem * ep_item_from_epqueue(poll_table *p)
375{
376 return container_of(p, struct ep_pqueue, pt)->epi;
377}
378
379/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
380static inline int ep_op_hash_event(int op)
381{
382 return op != EPOLL_CTL_DEL;
383}
384
360/* Initialize the poll safe wake up structure */ 385/* Initialize the poll safe wake up structure */
361static void ep_poll_safewake_init(struct poll_safewake *psw) 386static void ep_poll_safewake_init(struct poll_safewake *psw)
362{ 387{
@@ -456,7 +481,7 @@ void eventpoll_release_file(struct file *file)
456 epi = list_entry(lsthead->next, struct epitem, fllink); 481 epi = list_entry(lsthead->next, struct epitem, fllink);
457 482
458 ep = epi->ep; 483 ep = epi->ep;
459 EP_LIST_DEL(&epi->fllink); 484 ep_list_del(&epi->fllink);
460 down_write(&ep->sem); 485 down_write(&ep->sem);
461 ep_remove(ep, epi); 486 ep_remove(ep, epi);
462 up_write(&ep->sem); 487 up_write(&ep->sem);
@@ -534,7 +559,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
534 current, epfd, op, fd, event)); 559 current, epfd, op, fd, event));
535 560
536 error = -EFAULT; 561 error = -EFAULT;
537 if (EP_OP_HASH_EVENT(op) && 562 if (ep_op_hash_event(op) &&
538 copy_from_user(&epds, event, sizeof(struct epoll_event))) 563 copy_from_user(&epds, event, sizeof(struct epoll_event)))
539 goto eexit_1; 564 goto eexit_1;
540 565
@@ -560,7 +585,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
560 * adding an epoll file descriptor inside itself. 585 * adding an epoll file descriptor inside itself.
561 */ 586 */
562 error = -EINVAL; 587 error = -EINVAL;
563 if (file == tfile || !IS_FILE_EPOLL(file)) 588 if (file == tfile || !is_file_epoll(file))
564 goto eexit_3; 589 goto eexit_3;
565 590
566 /* 591 /*
@@ -656,7 +681,7 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
656 * the user passed to us _is_ an eventpoll file. 681 * the user passed to us _is_ an eventpoll file.
657 */ 682 */
658 error = -EINVAL; 683 error = -EINVAL;
659 if (!IS_FILE_EPOLL(file)) 684 if (!is_file_epoll(file))
660 goto eexit_2; 685 goto eexit_2;
661 686
662 /* 687 /*
@@ -831,11 +856,11 @@ static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd)
831 struct epitem *epi, *epir = NULL; 856 struct epitem *epi, *epir = NULL;
832 struct epoll_filefd ffd; 857 struct epoll_filefd ffd;
833 858
834 EP_SET_FFD(&ffd, file, fd); 859 ep_set_ffd(&ffd, file, fd);
835 read_lock_irqsave(&ep->lock, flags); 860 read_lock_irqsave(&ep->lock, flags);
836 for (rbp = ep->rbr.rb_node; rbp; ) { 861 for (rbp = ep->rbr.rb_node; rbp; ) {
837 epi = rb_entry(rbp, struct epitem, rbn); 862 epi = rb_entry(rbp, struct epitem, rbn);
838 kcmp = EP_CMP_FFD(&ffd, &epi->ffd); 863 kcmp = ep_cmp_ffd(&ffd, &epi->ffd);
839 if (kcmp > 0) 864 if (kcmp > 0)
840 rbp = rbp->rb_right; 865 rbp = rbp->rb_right;
841 else if (kcmp < 0) 866 else if (kcmp < 0)
@@ -875,7 +900,7 @@ static void ep_release_epitem(struct epitem *epi)
875{ 900{
876 901
877 if (atomic_dec_and_test(&epi->usecnt)) 902 if (atomic_dec_and_test(&epi->usecnt))
878 EPI_MEM_FREE(epi); 903 kmem_cache_free(epi_cache, epi);
879} 904}
880 905
881 906
@@ -886,10 +911,10 @@ static void ep_release_epitem(struct epitem *epi)
886static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, 911static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
887 poll_table *pt) 912 poll_table *pt)
888{ 913{
889 struct epitem *epi = EP_ITEM_FROM_EPQUEUE(pt); 914 struct epitem *epi = ep_item_from_epqueue(pt);
890 struct eppoll_entry *pwq; 915 struct eppoll_entry *pwq;
891 916
892 if (epi->nwait >= 0 && (pwq = PWQ_MEM_ALLOC())) { 917 if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, SLAB_KERNEL))) {
893 init_waitqueue_func_entry(&pwq->wait, ep_poll_callback); 918 init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
894 pwq->whead = whead; 919 pwq->whead = whead;
895 pwq->base = epi; 920 pwq->base = epi;
@@ -912,7 +937,7 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
912 while (*p) { 937 while (*p) {
913 parent = *p; 938 parent = *p;
914 epic = rb_entry(parent, struct epitem, rbn); 939 epic = rb_entry(parent, struct epitem, rbn);
915 kcmp = EP_CMP_FFD(&epi->ffd, &epic->ffd); 940 kcmp = ep_cmp_ffd(&epi->ffd, &epic->ffd);
916 if (kcmp > 0) 941 if (kcmp > 0)
917 p = &parent->rb_right; 942 p = &parent->rb_right;
918 else 943 else
@@ -932,17 +957,17 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
932 struct ep_pqueue epq; 957 struct ep_pqueue epq;
933 958
934 error = -ENOMEM; 959 error = -ENOMEM;
935 if (!(epi = EPI_MEM_ALLOC())) 960 if (!(epi = kmem_cache_alloc(epi_cache, SLAB_KERNEL)))
936 goto eexit_1; 961 goto eexit_1;
937 962
938 /* Item initialization follow here ... */ 963 /* Item initialization follow here ... */
939 EP_RB_INITNODE(&epi->rbn); 964 ep_rb_initnode(&epi->rbn);
940 INIT_LIST_HEAD(&epi->rdllink); 965 INIT_LIST_HEAD(&epi->rdllink);
941 INIT_LIST_HEAD(&epi->fllink); 966 INIT_LIST_HEAD(&epi->fllink);
942 INIT_LIST_HEAD(&epi->txlink); 967 INIT_LIST_HEAD(&epi->txlink);
943 INIT_LIST_HEAD(&epi->pwqlist); 968 INIT_LIST_HEAD(&epi->pwqlist);
944 epi->ep = ep; 969 epi->ep = ep;
945 EP_SET_FFD(&epi->ffd, tfile, fd); 970 ep_set_ffd(&epi->ffd, tfile, fd);
946 epi->event = *event; 971 epi->event = *event;
947 atomic_set(&epi->usecnt, 1); 972 atomic_set(&epi->usecnt, 1);
948 epi->nwait = 0; 973 epi->nwait = 0;
@@ -978,7 +1003,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
978 ep_rbtree_insert(ep, epi); 1003 ep_rbtree_insert(ep, epi);
979 1004
980 /* If the file is already "ready" we drop it inside the ready list */ 1005 /* If the file is already "ready" we drop it inside the ready list */
981 if ((revents & event->events) && !EP_IS_LINKED(&epi->rdllink)) { 1006 if ((revents & event->events) && !ep_is_linked(&epi->rdllink)) {
982 list_add_tail(&epi->rdllink, &ep->rdllist); 1007 list_add_tail(&epi->rdllink, &ep->rdllist);
983 1008
984 /* Notify waiting tasks that events are available */ 1009 /* Notify waiting tasks that events are available */
@@ -1007,11 +1032,11 @@ eexit_2:
1007 * allocated wait queue. 1032 * allocated wait queue.
1008 */ 1033 */
1009 write_lock_irqsave(&ep->lock, flags); 1034 write_lock_irqsave(&ep->lock, flags);
1010 if (EP_IS_LINKED(&epi->rdllink)) 1035 if (ep_is_linked(&epi->rdllink))
1011 EP_LIST_DEL(&epi->rdllink); 1036 ep_list_del(&epi->rdllink);
1012 write_unlock_irqrestore(&ep->lock, flags); 1037 write_unlock_irqrestore(&ep->lock, flags);
1013 1038
1014 EPI_MEM_FREE(epi); 1039 kmem_cache_free(epi_cache, epi);
1015eexit_1: 1040eexit_1:
1016 return error; 1041 return error;
1017} 1042}
@@ -1050,14 +1075,14 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
1050 * If the item is not linked to the hash it means that it's on its 1075 * If the item is not linked to the hash it means that it's on its
1051 * way toward the removal. Do nothing in this case. 1076 * way toward the removal. Do nothing in this case.
1052 */ 1077 */
1053 if (EP_RB_LINKED(&epi->rbn)) { 1078 if (ep_rb_linked(&epi->rbn)) {
1054 /* 1079 /*
1055 * If the item is "hot" and it is not registered inside the ready 1080 * If the item is "hot" and it is not registered inside the ready
1056 * list, push it inside. If the item is not "hot" and it is currently 1081 * list, push it inside. If the item is not "hot" and it is currently
1057 * registered inside the ready list, unlink it. 1082 * registered inside the ready list, unlink it.
1058 */ 1083 */
1059 if (revents & event->events) { 1084 if (revents & event->events) {
1060 if (!EP_IS_LINKED(&epi->rdllink)) { 1085 if (!ep_is_linked(&epi->rdllink)) {
1061 list_add_tail(&epi->rdllink, &ep->rdllist); 1086 list_add_tail(&epi->rdllink, &ep->rdllist);
1062 1087
1063 /* Notify waiting tasks that events are available */ 1088 /* Notify waiting tasks that events are available */
@@ -1097,9 +1122,9 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
1097 while (!list_empty(lsthead)) { 1122 while (!list_empty(lsthead)) {
1098 pwq = list_entry(lsthead->next, struct eppoll_entry, llink); 1123 pwq = list_entry(lsthead->next, struct eppoll_entry, llink);
1099 1124
1100 EP_LIST_DEL(&pwq->llink); 1125 ep_list_del(&pwq->llink);
1101 remove_wait_queue(pwq->whead, &pwq->wait); 1126 remove_wait_queue(pwq->whead, &pwq->wait);
1102 PWQ_MEM_FREE(pwq); 1127 kmem_cache_free(pwq_cache, pwq);
1103 } 1128 }
1104 } 1129 }
1105} 1130}
@@ -1118,7 +1143,7 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
1118 * The check protect us from doing a double unlink ( crash ). 1143 * The check protect us from doing a double unlink ( crash ).
1119 */ 1144 */
1120 error = -ENOENT; 1145 error = -ENOENT;
1121 if (!EP_RB_LINKED(&epi->rbn)) 1146 if (!ep_rb_linked(&epi->rbn))
1122 goto eexit_1; 1147 goto eexit_1;
1123 1148
1124 /* 1149 /*
@@ -1133,14 +1158,14 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
1133 * This operation togheter with the above check closes the door to 1158 * This operation togheter with the above check closes the door to
1134 * double unlinks. 1159 * double unlinks.
1135 */ 1160 */
1136 EP_RB_ERASE(&epi->rbn, &ep->rbr); 1161 ep_rb_erase(&epi->rbn, &ep->rbr);
1137 1162
1138 /* 1163 /*
1139 * If the item we are going to remove is inside the ready file descriptors 1164 * If the item we are going to remove is inside the ready file descriptors
1140 * we want to remove it from this list to avoid stale events. 1165 * we want to remove it from this list to avoid stale events.
1141 */ 1166 */
1142 if (EP_IS_LINKED(&epi->rdllink)) 1167 if (ep_is_linked(&epi->rdllink))
1143 EP_LIST_DEL(&epi->rdllink); 1168 ep_list_del(&epi->rdllink);
1144 1169
1145 error = 0; 1170 error = 0;
1146eexit_1: 1171eexit_1:
@@ -1174,8 +1199,8 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
1174 1199
1175 /* Remove the current item from the list of epoll hooks */ 1200 /* Remove the current item from the list of epoll hooks */
1176 spin_lock(&file->f_ep_lock); 1201 spin_lock(&file->f_ep_lock);
1177 if (EP_IS_LINKED(&epi->fllink)) 1202 if (ep_is_linked(&epi->fllink))
1178 EP_LIST_DEL(&epi->fllink); 1203 ep_list_del(&epi->fllink);
1179 spin_unlock(&file->f_ep_lock); 1204 spin_unlock(&file->f_ep_lock);
1180 1205
1181 /* We need to acquire the write IRQ lock before calling ep_unlink() */ 1206 /* We need to acquire the write IRQ lock before calling ep_unlink() */
@@ -1210,7 +1235,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
1210{ 1235{
1211 int pwake = 0; 1236 int pwake = 0;
1212 unsigned long flags; 1237 unsigned long flags;
1213 struct epitem *epi = EP_ITEM_FROM_WAIT(wait); 1238 struct epitem *epi = ep_item_from_wait(wait);
1214 struct eventpoll *ep = epi->ep; 1239 struct eventpoll *ep = epi->ep;
1215 1240
1216 DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n", 1241 DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
@@ -1228,7 +1253,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
1228 goto is_disabled; 1253 goto is_disabled;
1229 1254
1230 /* If this file is already in the ready list we exit soon */ 1255 /* If this file is already in the ready list we exit soon */
1231 if (EP_IS_LINKED(&epi->rdllink)) 1256 if (ep_is_linked(&epi->rdllink))
1232 goto is_linked; 1257 goto is_linked;
1233 1258
1234 list_add_tail(&epi->rdllink, &ep->rdllist); 1259 list_add_tail(&epi->rdllink, &ep->rdllist);
@@ -1307,7 +1332,7 @@ static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist
1307 lnk = lnk->next; 1332 lnk = lnk->next;
1308 1333
1309 /* If this file is already in the ready list we exit soon */ 1334 /* If this file is already in the ready list we exit soon */
1310 if (!EP_IS_LINKED(&epi->txlink)) { 1335 if (!ep_is_linked(&epi->txlink)) {
1311 /* 1336 /*
1312 * This is initialized in this way so that the default 1337 * This is initialized in this way so that the default
1313 * behaviour of the reinjecting code will be to push back 1338 * behaviour of the reinjecting code will be to push back
@@ -1322,7 +1347,7 @@ static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist
1322 /* 1347 /*
1323 * Unlink the item from the ready list. 1348 * Unlink the item from the ready list.
1324 */ 1349 */
1325 EP_LIST_DEL(&epi->rdllink); 1350 ep_list_del(&epi->rdllink);
1326 } 1351 }
1327 } 1352 }
1328 1353
@@ -1401,7 +1426,7 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
1401 epi = list_entry(txlist->next, struct epitem, txlink); 1426 epi = list_entry(txlist->next, struct epitem, txlink);
1402 1427
1403 /* Unlink the current item from the transfer list */ 1428 /* Unlink the current item from the transfer list */
1404 EP_LIST_DEL(&epi->txlink); 1429 ep_list_del(&epi->txlink);
1405 1430
1406 /* 1431 /*
1407 * If the item is no more linked to the interest set, we don't 1432 * If the item is no more linked to the interest set, we don't
@@ -1410,8 +1435,8 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
1410 * item is set to have an Edge Triggered behaviour, we don't have 1435 * item is set to have an Edge Triggered behaviour, we don't have
1411 * to push it back either. 1436 * to push it back either.
1412 */ 1437 */
1413 if (EP_RB_LINKED(&epi->rbn) && !(epi->event.events & EPOLLET) && 1438 if (ep_rb_linked(&epi->rbn) && !(epi->event.events & EPOLLET) &&
1414 (epi->revents & epi->event.events) && !EP_IS_LINKED(&epi->rdllink)) { 1439 (epi->revents & epi->event.events) && !ep_is_linked(&epi->rdllink)) {
1415 list_add_tail(&epi->rdllink, &ep->rdllist); 1440 list_add_tail(&epi->rdllink, &ep->rdllist);
1416 ricnt++; 1441 ricnt++;
1417 } 1442 }
diff --git a/fs/exec.c b/fs/exec.c
index 3a4b35a14c0d..48871917d363 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -58,6 +58,9 @@
58 58
59int core_uses_pid; 59int core_uses_pid;
60char core_pattern[65] = "core"; 60char core_pattern[65] = "core";
61int suid_dumpable = 0;
62
63EXPORT_SYMBOL(suid_dumpable);
61/* The maximal length of core_pattern is also specified in sysctl.c */ 64/* The maximal length of core_pattern is also specified in sysctl.c */
62 65
63static struct linux_binfmt *formats; 66static struct linux_binfmt *formats;
@@ -864,6 +867,9 @@ int flush_old_exec(struct linux_binprm * bprm)
864 867
865 if (current->euid == current->uid && current->egid == current->gid) 868 if (current->euid == current->uid && current->egid == current->gid)
866 current->mm->dumpable = 1; 869 current->mm->dumpable = 1;
870 else
871 current->mm->dumpable = suid_dumpable;
872
867 name = bprm->filename; 873 name = bprm->filename;
868 874
869 /* Copies the binary name from after last slash */ 875 /* Copies the binary name from after last slash */
@@ -884,7 +890,7 @@ int flush_old_exec(struct linux_binprm * bprm)
884 permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) || 890 permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
885 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { 891 (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
886 suid_keys(current); 892 suid_keys(current);
887 current->mm->dumpable = 0; 893 current->mm->dumpable = suid_dumpable;
888 } 894 }
889 895
890 /* An exec changes our domain. We are no longer part of the thread 896 /* An exec changes our domain. We are no longer part of the thread
@@ -1432,6 +1438,8 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1432 struct inode * inode; 1438 struct inode * inode;
1433 struct file * file; 1439 struct file * file;
1434 int retval = 0; 1440 int retval = 0;
1441 int fsuid = current->fsuid;
1442 int flag = 0;
1435 1443
1436 binfmt = current->binfmt; 1444 binfmt = current->binfmt;
1437 if (!binfmt || !binfmt->core_dump) 1445 if (!binfmt || !binfmt->core_dump)
@@ -1441,6 +1449,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1441 up_write(&mm->mmap_sem); 1449 up_write(&mm->mmap_sem);
1442 goto fail; 1450 goto fail;
1443 } 1451 }
1452
1453 /*
1454 * We cannot trust fsuid as being the "true" uid of the
1455 * process nor do we know its entire history. We only know it
1456 * was tainted so we dump it as root in mode 2.
1457 */
1458 if (mm->dumpable == 2) { /* Setuid core dump mode */
1459 flag = O_EXCL; /* Stop rewrite attacks */
1460 current->fsuid = 0; /* Dump root private */
1461 }
1444 mm->dumpable = 0; 1462 mm->dumpable = 0;
1445 init_completion(&mm->core_done); 1463 init_completion(&mm->core_done);
1446 spin_lock_irq(&current->sighand->siglock); 1464 spin_lock_irq(&current->sighand->siglock);
@@ -1466,7 +1484,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1466 lock_kernel(); 1484 lock_kernel();
1467 format_corename(corename, core_pattern, signr); 1485 format_corename(corename, core_pattern, signr);
1468 unlock_kernel(); 1486 unlock_kernel();
1469 file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); 1487 file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600);
1470 if (IS_ERR(file)) 1488 if (IS_ERR(file))
1471 goto fail_unlock; 1489 goto fail_unlock;
1472 inode = file->f_dentry->d_inode; 1490 inode = file->f_dentry->d_inode;
@@ -1491,6 +1509,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1491close_fail: 1509close_fail:
1492 filp_close(file, NULL); 1510 filp_close(file, NULL);
1493fail_unlock: 1511fail_unlock:
1512 current->fsuid = fsuid;
1494 complete_all(&mm->core_done); 1513 complete_all(&mm->core_done);
1495fail: 1514fail:
1496 return retval; 1515 return retval;
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile
index ee240a14e70f..c5d02da73bc3 100644
--- a/fs/ext2/Makefile
+++ b/fs/ext2/Makefile
@@ -10,3 +10,4 @@ ext2-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
10ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o 10ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o
11ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o 11ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
12ext2-$(CONFIG_EXT2_FS_SECURITY) += xattr_security.o 12ext2-$(CONFIG_EXT2_FS_SECURITY) += xattr_security.o
13ext2-$(CONFIG_EXT2_FS_XIP) += xip.o
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 25f4a64fd6bc..213148c36ebe 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -396,12 +396,12 @@ static size_t
396ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size, 396ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size,
397 const char *name, size_t name_len) 397 const char *name, size_t name_len)
398{ 398{
399 const size_t size = sizeof(XATTR_NAME_ACL_ACCESS); 399 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
400 400
401 if (!test_opt(inode->i_sb, POSIX_ACL)) 401 if (!test_opt(inode->i_sb, POSIX_ACL))
402 return 0; 402 return 0;
403 if (list && size <= list_size) 403 if (list && size <= list_size)
404 memcpy(list, XATTR_NAME_ACL_ACCESS, size); 404 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
405 return size; 405 return size;
406} 406}
407 407
@@ -409,12 +409,12 @@ static size_t
409ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size, 409ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size,
410 const char *name, size_t name_len) 410 const char *name, size_t name_len)
411{ 411{
412 const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT); 412 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
413 413
414 if (!test_opt(inode->i_sb, POSIX_ACL)) 414 if (!test_opt(inode->i_sb, POSIX_ACL))
415 return 0; 415 return 0;
416 if (list && size <= list_size) 416 if (list && size <= list_size)
417 memcpy(list, XATTR_NAME_ACL_DEFAULT, size); 417 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
418 return size; 418 return size;
419} 419}
420 420
@@ -506,14 +506,14 @@ ext2_xattr_set_acl_default(struct inode *inode, const char *name,
506} 506}
507 507
508struct xattr_handler ext2_xattr_acl_access_handler = { 508struct xattr_handler ext2_xattr_acl_access_handler = {
509 .prefix = XATTR_NAME_ACL_ACCESS, 509 .prefix = POSIX_ACL_XATTR_ACCESS,
510 .list = ext2_xattr_list_acl_access, 510 .list = ext2_xattr_list_acl_access,
511 .get = ext2_xattr_get_acl_access, 511 .get = ext2_xattr_get_acl_access,
512 .set = ext2_xattr_set_acl_access, 512 .set = ext2_xattr_set_acl_access,
513}; 513};
514 514
515struct xattr_handler ext2_xattr_acl_default_handler = { 515struct xattr_handler ext2_xattr_acl_default_handler = {
516 .prefix = XATTR_NAME_ACL_DEFAULT, 516 .prefix = POSIX_ACL_XATTR_DEFAULT,
517 .list = ext2_xattr_list_acl_default, 517 .list = ext2_xattr_list_acl_default,
518 .get = ext2_xattr_get_acl_default, 518 .get = ext2_xattr_get_acl_default,
519 .set = ext2_xattr_set_acl_default, 519 .set = ext2_xattr_set_acl_default,
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h
index fed96ae81a7d..0bde85bafe38 100644
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -4,7 +4,7 @@
4 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org> 4 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
5*/ 5*/
6 6
7#include <linux/xattr_acl.h> 7#include <linux/posix_acl_xattr.h>
8 8
9#define EXT2_ACL_VERSION 0x0001 9#define EXT2_ACL_VERSION 0x0001
10 10
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 8f0fd726c3f1..eed521d22cf0 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -147,9 +147,11 @@ extern struct file_operations ext2_dir_operations;
147/* file.c */ 147/* file.c */
148extern struct inode_operations ext2_file_inode_operations; 148extern struct inode_operations ext2_file_inode_operations;
149extern struct file_operations ext2_file_operations; 149extern struct file_operations ext2_file_operations;
150extern struct file_operations ext2_xip_file_operations;
150 151
151/* inode.c */ 152/* inode.c */
152extern struct address_space_operations ext2_aops; 153extern struct address_space_operations ext2_aops;
154extern struct address_space_operations ext2_aops_xip;
153extern struct address_space_operations ext2_nobh_aops; 155extern struct address_space_operations ext2_nobh_aops;
154 156
155/* namei.c */ 157/* namei.c */
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index f5e86141ec54..a484412fc782 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -55,6 +55,20 @@ struct file_operations ext2_file_operations = {
55 .sendfile = generic_file_sendfile, 55 .sendfile = generic_file_sendfile,
56}; 56};
57 57
58#ifdef CONFIG_EXT2_FS_XIP
59struct file_operations ext2_xip_file_operations = {
60 .llseek = generic_file_llseek,
61 .read = xip_file_read,
62 .write = xip_file_write,
63 .ioctl = ext2_ioctl,
64 .mmap = xip_file_mmap,
65 .open = generic_file_open,
66 .release = ext2_release_file,
67 .fsync = ext2_sync_file,
68 .sendfile = xip_file_sendfile,
69};
70#endif
71
58struct inode_operations ext2_file_inode_operations = { 72struct inode_operations ext2_file_inode_operations = {
59 .truncate = ext2_truncate, 73 .truncate = ext2_truncate,
60#ifdef CONFIG_EXT2_FS_XATTR 74#ifdef CONFIG_EXT2_FS_XATTR
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index a50d9db4b6e4..53dceb0c6593 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -33,6 +33,7 @@
33#include <linux/mpage.h> 33#include <linux/mpage.h>
34#include "ext2.h" 34#include "ext2.h"
35#include "acl.h" 35#include "acl.h"
36#include "xip.h"
36 37
37MODULE_AUTHOR("Remy Card and others"); 38MODULE_AUTHOR("Remy Card and others");
38MODULE_DESCRIPTION("Second Extended Filesystem"); 39MODULE_DESCRIPTION("Second Extended Filesystem");
@@ -594,6 +595,16 @@ out:
594 if (err) 595 if (err)
595 goto cleanup; 596 goto cleanup;
596 597
598 if (ext2_use_xip(inode->i_sb)) {
599 /*
600 * we need to clear the block
601 */
602 err = ext2_clear_xip_target (inode,
603 le32_to_cpu(chain[depth-1].key));
604 if (err)
605 goto cleanup;
606 }
607
597 if (ext2_splice_branch(inode, iblock, chain, partial, left) < 0) 608 if (ext2_splice_branch(inode, iblock, chain, partial, left) < 0)
598 goto changed; 609 goto changed;
599 610
@@ -691,6 +702,11 @@ struct address_space_operations ext2_aops = {
691 .writepages = ext2_writepages, 702 .writepages = ext2_writepages,
692}; 703};
693 704
705struct address_space_operations ext2_aops_xip = {
706 .bmap = ext2_bmap,
707 .get_xip_page = ext2_get_xip_page,
708};
709
694struct address_space_operations ext2_nobh_aops = { 710struct address_space_operations ext2_nobh_aops = {
695 .readpage = ext2_readpage, 711 .readpage = ext2_readpage,
696 .readpages = ext2_readpages, 712 .readpages = ext2_readpages,
@@ -910,7 +926,9 @@ void ext2_truncate (struct inode * inode)
910 iblock = (inode->i_size + blocksize-1) 926 iblock = (inode->i_size + blocksize-1)
911 >> EXT2_BLOCK_SIZE_BITS(inode->i_sb); 927 >> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
912 928
913 if (test_opt(inode->i_sb, NOBH)) 929 if (mapping_is_xip(inode->i_mapping))
930 xip_truncate_page(inode->i_mapping, inode->i_size);
931 else if (test_opt(inode->i_sb, NOBH))
914 nobh_truncate_page(inode->i_mapping, inode->i_size); 932 nobh_truncate_page(inode->i_mapping, inode->i_size);
915 else 933 else
916 block_truncate_page(inode->i_mapping, 934 block_truncate_page(inode->i_mapping,
@@ -1110,11 +1128,16 @@ void ext2_read_inode (struct inode * inode)
1110 1128
1111 if (S_ISREG(inode->i_mode)) { 1129 if (S_ISREG(inode->i_mode)) {
1112 inode->i_op = &ext2_file_inode_operations; 1130 inode->i_op = &ext2_file_inode_operations;
1113 inode->i_fop = &ext2_file_operations; 1131 if (ext2_use_xip(inode->i_sb)) {
1114 if (test_opt(inode->i_sb, NOBH)) 1132 inode->i_mapping->a_ops = &ext2_aops_xip;
1133 inode->i_fop = &ext2_xip_file_operations;
1134 } else if (test_opt(inode->i_sb, NOBH)) {
1115 inode->i_mapping->a_ops = &ext2_nobh_aops; 1135 inode->i_mapping->a_ops = &ext2_nobh_aops;
1116 else 1136 inode->i_fop = &ext2_file_operations;
1137 } else {
1117 inode->i_mapping->a_ops = &ext2_aops; 1138 inode->i_mapping->a_ops = &ext2_aops;
1139 inode->i_fop = &ext2_file_operations;
1140 }
1118 } else if (S_ISDIR(inode->i_mode)) { 1141 } else if (S_ISDIR(inode->i_mode)) {
1119 inode->i_op = &ext2_dir_inode_operations; 1142 inode->i_op = &ext2_dir_inode_operations;
1120 inode->i_fop = &ext2_dir_operations; 1143 inode->i_fop = &ext2_dir_operations;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 3176b3d3ffa8..c5513953c825 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -34,6 +34,7 @@
34#include "ext2.h" 34#include "ext2.h"
35#include "xattr.h" 35#include "xattr.h"
36#include "acl.h" 36#include "acl.h"
37#include "xip.h"
37 38
38/* 39/*
39 * Couple of helper functions - make the code slightly cleaner. 40 * Couple of helper functions - make the code slightly cleaner.
@@ -127,11 +128,16 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st
127 int err = PTR_ERR(inode); 128 int err = PTR_ERR(inode);
128 if (!IS_ERR(inode)) { 129 if (!IS_ERR(inode)) {
129 inode->i_op = &ext2_file_inode_operations; 130 inode->i_op = &ext2_file_inode_operations;
130 inode->i_fop = &ext2_file_operations; 131 if (ext2_use_xip(inode->i_sb)) {
131 if (test_opt(inode->i_sb, NOBH)) 132 inode->i_mapping->a_ops = &ext2_aops_xip;
133 inode->i_fop = &ext2_xip_file_operations;
134 } else if (test_opt(inode->i_sb, NOBH)) {
132 inode->i_mapping->a_ops = &ext2_nobh_aops; 135 inode->i_mapping->a_ops = &ext2_nobh_aops;
133 else 136 inode->i_fop = &ext2_file_operations;
137 } else {
134 inode->i_mapping->a_ops = &ext2_aops; 138 inode->i_mapping->a_ops = &ext2_aops;
139 inode->i_fop = &ext2_file_operations;
140 }
135 mark_inode_dirty(inode); 141 mark_inode_dirty(inode);
136 err = ext2_add_nondir(dentry, inode); 142 err = ext2_add_nondir(dentry, inode);
137 } 143 }
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 661c3d98d946..876e391f2871 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -31,6 +31,7 @@
31#include "ext2.h" 31#include "ext2.h"
32#include "xattr.h" 32#include "xattr.h"
33#include "acl.h" 33#include "acl.h"
34#include "xip.h"
34 35
35static void ext2_sync_super(struct super_block *sb, 36static void ext2_sync_super(struct super_block *sb,
36 struct ext2_super_block *es); 37 struct ext2_super_block *es);
@@ -257,7 +258,7 @@ enum {
257 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid, 258 Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
258 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro, 259 Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
259 Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh, 260 Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh,
260 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, 261 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_xip,
261 Opt_ignore, Opt_err, 262 Opt_ignore, Opt_err,
262}; 263};
263 264
@@ -286,6 +287,7 @@ static match_table_t tokens = {
286 {Opt_nouser_xattr, "nouser_xattr"}, 287 {Opt_nouser_xattr, "nouser_xattr"},
287 {Opt_acl, "acl"}, 288 {Opt_acl, "acl"},
288 {Opt_noacl, "noacl"}, 289 {Opt_noacl, "noacl"},
290 {Opt_xip, "xip"},
289 {Opt_ignore, "grpquota"}, 291 {Opt_ignore, "grpquota"},
290 {Opt_ignore, "noquota"}, 292 {Opt_ignore, "noquota"},
291 {Opt_ignore, "quota"}, 293 {Opt_ignore, "quota"},
@@ -397,6 +399,13 @@ static int parse_options (char * options,
397 printk("EXT2 (no)acl options not supported\n"); 399 printk("EXT2 (no)acl options not supported\n");
398 break; 400 break;
399#endif 401#endif
402 case Opt_xip:
403#ifdef CONFIG_EXT2_FS_XIP
404 set_opt (sbi->s_mount_opt, XIP);
405#else
406 printk("EXT2 xip option not supported\n");
407#endif
408 break;
400 case Opt_ignore: 409 case Opt_ignore:
401 break; 410 break;
402 default: 411 default:
@@ -640,6 +649,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
640 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? 649 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
641 MS_POSIXACL : 0); 650 MS_POSIXACL : 0);
642 651
652 ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset
653 EXT2_MOUNT_XIP if not */
654
643 if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV && 655 if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
644 (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) || 656 (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
645 EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) || 657 EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -668,6 +680,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
668 680
669 blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); 681 blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
670 682
683 if ((ext2_use_xip(sb)) && ((blocksize != PAGE_SIZE) ||
684 (sb->s_blocksize != blocksize))) {
685 if (!silent)
686 printk("XIP: Unsupported blocksize\n");
687 goto failed_mount;
688 }
689
671 /* If the blocksize doesn't match, re-read the thing.. */ 690 /* If the blocksize doesn't match, re-read the thing.. */
672 if (sb->s_blocksize != blocksize) { 691 if (sb->s_blocksize != blocksize) {
673 brelse(bh); 692 brelse(bh);
@@ -916,6 +935,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
916{ 935{
917 struct ext2_sb_info * sbi = EXT2_SB(sb); 936 struct ext2_sb_info * sbi = EXT2_SB(sb);
918 struct ext2_super_block * es; 937 struct ext2_super_block * es;
938 unsigned long old_mount_opt = sbi->s_mount_opt;
919 939
920 /* 940 /*
921 * Allow the "check" option to be passed as a remount option. 941 * Allow the "check" option to be passed as a remount option.
@@ -927,6 +947,11 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
927 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); 947 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
928 948
929 es = sbi->s_es; 949 es = sbi->s_es;
950 if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) !=
951 (old_mount_opt & EXT2_MOUNT_XIP)) &&
952 invalidate_inodes(sb))
953 ext2_warning(sb, __FUNCTION__, "busy inodes while remounting "\
954 "xip remain in cache (no functional problem)");
930 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) 955 if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
931 return 0; 956 return 0;
932 if (*flags & MS_RDONLY) { 957 if (*flags & MS_RDONLY) {
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
new file mode 100644
index 000000000000..d44431d1a338
--- /dev/null
+++ b/fs/ext2/xip.c
@@ -0,0 +1,80 @@
1/*
2 * linux/fs/ext2/xip.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 * Author: Carsten Otte (cotte@de.ibm.com)
6 */
7
8#include <linux/mm.h>
9#include <linux/fs.h>
10#include <linux/genhd.h>
11#include <linux/buffer_head.h>
12#include <linux/ext2_fs_sb.h>
13#include <linux/ext2_fs.h>
14#include "ext2.h"
15#include "xip.h"
16
17static inline int
18__inode_direct_access(struct inode *inode, sector_t sector, unsigned long *data) {
19 BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
20 return inode->i_sb->s_bdev->bd_disk->fops
21 ->direct_access(inode->i_sb->s_bdev,sector,data);
22}
23
24int
25ext2_clear_xip_target(struct inode *inode, int block) {
26 sector_t sector = block*(PAGE_SIZE/512);
27 unsigned long data;
28 int rc;
29
30 rc = __inode_direct_access(inode, sector, &data);
31 if (rc)
32 return rc;
33 clear_page((void*)data);
34 return 0;
35}
36
37void ext2_xip_verify_sb(struct super_block *sb)
38{
39 struct ext2_sb_info *sbi = EXT2_SB(sb);
40
41 if ((sbi->s_mount_opt & EXT2_MOUNT_XIP)) {
42 if ((sb->s_bdev == NULL) ||
43 sb->s_bdev->bd_disk == NULL ||
44 sb->s_bdev->bd_disk->fops == NULL ||
45 sb->s_bdev->bd_disk->fops->direct_access == NULL) {
46 sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
47 ext2_warning(sb, __FUNCTION__,
48 "ignoring xip option - not supported by bdev");
49 }
50 }
51}
52
53struct page*
54ext2_get_xip_page(struct address_space *mapping, sector_t blockno,
55 int create)
56{
57 int rc;
58 unsigned long data;
59 struct buffer_head tmp;
60
61 tmp.b_state = 0;
62 tmp.b_blocknr = 0;
63 rc = ext2_get_block(mapping->host, blockno/(PAGE_SIZE/512) , &tmp,
64 create);
65 if (rc)
66 return ERR_PTR(rc);
67 if (tmp.b_blocknr == 0) {
68 /* SPARSE block */
69 BUG_ON(create);
70 return ERR_PTR(-ENODATA);
71 }
72
73 rc = __inode_direct_access
74 (mapping->host,tmp.b_blocknr*(PAGE_SIZE/512) ,&data);
75 if (rc)
76 return ERR_PTR(rc);
77
78 SetPageUptodate(virt_to_page(data));
79 return virt_to_page(data);
80}
diff --git a/fs/ext2/xip.h b/fs/ext2/xip.h
new file mode 100644
index 000000000000..aa85331d6c56
--- /dev/null
+++ b/fs/ext2/xip.h
@@ -0,0 +1,25 @@
1/*
2 * linux/fs/ext2/xip.h
3 *
4 * Copyright (C) 2005 IBM Corporation
5 * Author: Carsten Otte (cotte@de.ibm.com)
6 */
7
8#ifdef CONFIG_EXT2_FS_XIP
9extern void ext2_xip_verify_sb (struct super_block *);
10extern int ext2_clear_xip_target (struct inode *, int);
11
12static inline int ext2_use_xip (struct super_block *sb)
13{
14 struct ext2_sb_info *sbi = EXT2_SB(sb);
15 return (sbi->s_mount_opt & EXT2_MOUNT_XIP);
16}
17struct page* ext2_get_xip_page (struct address_space *, sector_t, int);
18#define mapping_is_xip(map) unlikely(map->a_ops->get_xip_page)
19#else
20#define mapping_is_xip(map) 0
21#define ext2_xip_verify_sb(sb) do { } while (0)
22#define ext2_use_xip(sb) 0
23#define ext2_clear_xip_target(inode, chain) 0
24#define ext2_get_xip_page NULL
25#endif
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 638c13a26c03..3ac38266fc9e 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -393,7 +393,8 @@ ext3_acl_chmod(struct inode *inode)
393 int retries = 0; 393 int retries = 0;
394 394
395 retry: 395 retry:
396 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS); 396 handle = ext3_journal_start(inode,
397 EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
397 if (IS_ERR(handle)) { 398 if (IS_ERR(handle)) {
398 error = PTR_ERR(handle); 399 error = PTR_ERR(handle);
399 ext3_std_error(inode->i_sb, error); 400 ext3_std_error(inode->i_sb, error);
@@ -417,12 +418,12 @@ static size_t
417ext3_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len, 418ext3_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len,
418 const char *name, size_t name_len) 419 const char *name, size_t name_len)
419{ 420{
420 const size_t size = sizeof(XATTR_NAME_ACL_ACCESS); 421 const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
421 422
422 if (!test_opt(inode->i_sb, POSIX_ACL)) 423 if (!test_opt(inode->i_sb, POSIX_ACL))
423 return 0; 424 return 0;
424 if (list && size <= list_len) 425 if (list && size <= list_len)
425 memcpy(list, XATTR_NAME_ACL_ACCESS, size); 426 memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
426 return size; 427 return size;
427} 428}
428 429
@@ -430,12 +431,12 @@ static size_t
430ext3_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len, 431ext3_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len,
431 const char *name, size_t name_len) 432 const char *name, size_t name_len)
432{ 433{
433 const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT); 434 const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
434 435
435 if (!test_opt(inode->i_sb, POSIX_ACL)) 436 if (!test_opt(inode->i_sb, POSIX_ACL))
436 return 0; 437 return 0;
437 if (list && size <= list_len) 438 if (list && size <= list_len)
438 memcpy(list, XATTR_NAME_ACL_DEFAULT, size); 439 memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
439 return size; 440 return size;
440} 441}
441 442
@@ -503,7 +504,7 @@ ext3_xattr_set_acl(struct inode *inode, int type, const void *value,
503 acl = NULL; 504 acl = NULL;
504 505
505retry: 506retry:
506 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS); 507 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
507 if (IS_ERR(handle)) 508 if (IS_ERR(handle))
508 return PTR_ERR(handle); 509 return PTR_ERR(handle);
509 error = ext3_set_acl(handle, inode, type, acl); 510 error = ext3_set_acl(handle, inode, type, acl);
@@ -535,14 +536,14 @@ ext3_xattr_set_acl_default(struct inode *inode, const char *name,
535} 536}
536 537
537struct xattr_handler ext3_xattr_acl_access_handler = { 538struct xattr_handler ext3_xattr_acl_access_handler = {
538 .prefix = XATTR_NAME_ACL_ACCESS, 539 .prefix = POSIX_ACL_XATTR_ACCESS,
539 .list = ext3_xattr_list_acl_access, 540 .list = ext3_xattr_list_acl_access,
540 .get = ext3_xattr_get_acl_access, 541 .get = ext3_xattr_get_acl_access,
541 .set = ext3_xattr_set_acl_access, 542 .set = ext3_xattr_set_acl_access,
542}; 543};
543 544
544struct xattr_handler ext3_xattr_acl_default_handler = { 545struct xattr_handler ext3_xattr_acl_default_handler = {
545 .prefix = XATTR_NAME_ACL_DEFAULT, 546 .prefix = POSIX_ACL_XATTR_DEFAULT,
546 .list = ext3_xattr_list_acl_default, 547 .list = ext3_xattr_list_acl_default,
547 .get = ext3_xattr_get_acl_default, 548 .get = ext3_xattr_get_acl_default,
548 .set = ext3_xattr_set_acl_default, 549 .set = ext3_xattr_set_acl_default,
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index 98af0c0d0ba9..92d50b53a933 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -4,7 +4,7 @@
4 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org> 4 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
5*/ 5*/
6 6
7#include <linux/xattr_acl.h> 7#include <linux/posix_acl_xattr.h>
8 8
9#define EXT3_ACL_VERSION 0x0001 9#define EXT3_ACL_VERSION 0x0001
10 10
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 0d5fa73b18dc..0b2db4f618cb 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -128,7 +128,7 @@ static unsigned long blocks_for_truncate(struct inode *inode)
128 if (needed > EXT3_MAX_TRANS_DATA) 128 if (needed > EXT3_MAX_TRANS_DATA)
129 needed = EXT3_MAX_TRANS_DATA; 129 needed = EXT3_MAX_TRANS_DATA;
130 130
131 return EXT3_DATA_TRANS_BLOCKS + needed; 131 return EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + needed;
132} 132}
133 133
134/* 134/*
@@ -2763,7 +2763,8 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
2763 2763
2764 /* (user+group)*(old+new) structure, inode write (sb, 2764 /* (user+group)*(old+new) structure, inode write (sb,
2765 * inode block, ? - but truncate inode update has it) */ 2765 * inode block, ? - but truncate inode update has it) */
2766 handle = ext3_journal_start(inode, 4*EXT3_QUOTA_INIT_BLOCKS+3); 2766 handle = ext3_journal_start(inode, 2*(EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)+
2767 EXT3_QUOTA_DEL_BLOCKS(inode->i_sb))+3);
2767 if (IS_ERR(handle)) { 2768 if (IS_ERR(handle)) {
2768 error = PTR_ERR(handle); 2769 error = PTR_ERR(handle);
2769 goto err_out; 2770 goto err_out;
@@ -2861,7 +2862,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode)
2861#ifdef CONFIG_QUOTA 2862#ifdef CONFIG_QUOTA
2862 /* We know that structure was already allocated during DQUOT_INIT so 2863 /* We know that structure was already allocated during DQUOT_INIT so
2863 * we will be updating only the data blocks + inodes */ 2864 * we will be updating only the data blocks + inodes */
2864 ret += 2*EXT3_QUOTA_TRANS_BLOCKS; 2865 ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb);
2865#endif 2866#endif
2866 2867
2867 return ret; 2868 return ret;
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 79742d824a0a..50378d8ff84b 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -932,8 +932,16 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
932 struct inode *dir = dentry->d_parent->d_inode; 932 struct inode *dir = dentry->d_parent->d_inode;
933 933
934 sb = dir->i_sb; 934 sb = dir->i_sb;
935 if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err))) 935 /* NFS may look up ".." - look at dx_root directory block */
936 return NULL; 936 if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
937 if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
938 return NULL;
939 } else {
940 frame = frames;
941 frame->bh = NULL; /* for dx_release() */
942 frame->at = (struct dx_entry *)frames; /* hack for zero entry*/
943 dx_set_block(frame->at, 0); /* dx_root block is 0 */
944 }
937 hash = hinfo.hash; 945 hash = hinfo.hash;
938 do { 946 do {
939 block = dx_get_block(frame->at); 947 block = dx_get_block(frame->at);
@@ -1637,9 +1645,9 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode,
1637 int err, retries = 0; 1645 int err, retries = 0;
1638 1646
1639retry: 1647retry:
1640 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 1648 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
1641 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + 1649 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
1642 2*EXT3_QUOTA_INIT_BLOCKS); 1650 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
1643 if (IS_ERR(handle)) 1651 if (IS_ERR(handle))
1644 return PTR_ERR(handle); 1652 return PTR_ERR(handle);
1645 1653
@@ -1671,9 +1679,9 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry,
1671 return -EINVAL; 1679 return -EINVAL;
1672 1680
1673retry: 1681retry:
1674 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 1682 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
1675 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + 1683 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
1676 2*EXT3_QUOTA_INIT_BLOCKS); 1684 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
1677 if (IS_ERR(handle)) 1685 if (IS_ERR(handle))
1678 return PTR_ERR(handle); 1686 return PTR_ERR(handle);
1679 1687
@@ -1707,9 +1715,9 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode)
1707 return -EMLINK; 1715 return -EMLINK;
1708 1716
1709retry: 1717retry:
1710 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 1718 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
1711 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + 1719 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
1712 2*EXT3_QUOTA_INIT_BLOCKS); 1720 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
1713 if (IS_ERR(handle)) 1721 if (IS_ERR(handle))
1714 return PTR_ERR(handle); 1722 return PTR_ERR(handle);
1715 1723
@@ -1998,7 +2006,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
1998 /* Initialize quotas before so that eventual writes go in 2006 /* Initialize quotas before so that eventual writes go in
1999 * separate transaction */ 2007 * separate transaction */
2000 DQUOT_INIT(dentry->d_inode); 2008 DQUOT_INIT(dentry->d_inode);
2001 handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); 2009 handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
2002 if (IS_ERR(handle)) 2010 if (IS_ERR(handle))
2003 return PTR_ERR(handle); 2011 return PTR_ERR(handle);
2004 2012
@@ -2057,7 +2065,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry)
2057 /* Initialize quotas before so that eventual writes go 2065 /* Initialize quotas before so that eventual writes go
2058 * in separate transaction */ 2066 * in separate transaction */
2059 DQUOT_INIT(dentry->d_inode); 2067 DQUOT_INIT(dentry->d_inode);
2060 handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); 2068 handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
2061 if (IS_ERR(handle)) 2069 if (IS_ERR(handle))
2062 return PTR_ERR(handle); 2070 return PTR_ERR(handle);
2063 2071
@@ -2112,9 +2120,9 @@ static int ext3_symlink (struct inode * dir,
2112 return -ENAMETOOLONG; 2120 return -ENAMETOOLONG;
2113 2121
2114retry: 2122retry:
2115 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 2123 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
2116 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + 2124 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 +
2117 2*EXT3_QUOTA_INIT_BLOCKS); 2125 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
2118 if (IS_ERR(handle)) 2126 if (IS_ERR(handle))
2119 return PTR_ERR(handle); 2127 return PTR_ERR(handle);
2120 2128
@@ -2166,7 +2174,7 @@ static int ext3_link (struct dentry * old_dentry,
2166 return -EMLINK; 2174 return -EMLINK;
2167 2175
2168retry: 2176retry:
2169 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 2177 handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
2170 EXT3_INDEX_EXTRA_TRANS_BLOCKS); 2178 EXT3_INDEX_EXTRA_TRANS_BLOCKS);
2171 if (IS_ERR(handle)) 2179 if (IS_ERR(handle))
2172 return PTR_ERR(handle); 2180 return PTR_ERR(handle);
@@ -2208,7 +2216,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
2208 * in separate transaction */ 2216 * in separate transaction */
2209 if (new_dentry->d_inode) 2217 if (new_dentry->d_inode)
2210 DQUOT_INIT(new_dentry->d_inode); 2218 DQUOT_INIT(new_dentry->d_inode);
2211 handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2219 handle = ext3_journal_start(old_dir, 2 *
2220 EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) +
2212 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); 2221 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
2213 if (IS_ERR(handle)) 2222 if (IS_ERR(handle))
2214 return PTR_ERR(handle); 2223 return PTR_ERR(handle);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 981ccb233ef5..b4b3e8a39131 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -589,7 +589,7 @@ enum {
589 Opt_commit, Opt_journal_update, Opt_journal_inum, 589 Opt_commit, Opt_journal_update, Opt_journal_inum,
590 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 590 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
591 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 591 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
592 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, 592 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
593 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, 593 Opt_ignore, Opt_barrier, Opt_err, Opt_resize,
594}; 594};
595 595
@@ -634,10 +634,10 @@ static match_table_t tokens = {
634 {Opt_grpjquota, "grpjquota=%s"}, 634 {Opt_grpjquota, "grpjquota=%s"},
635 {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, 635 {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
636 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, 636 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
637 {Opt_ignore, "grpquota"}, 637 {Opt_quota, "grpquota"},
638 {Opt_ignore, "noquota"}, 638 {Opt_noquota, "noquota"},
639 {Opt_ignore, "quota"}, 639 {Opt_quota, "quota"},
640 {Opt_ignore, "usrquota"}, 640 {Opt_quota, "usrquota"},
641 {Opt_barrier, "barrier=%u"}, 641 {Opt_barrier, "barrier=%u"},
642 {Opt_err, NULL}, 642 {Opt_err, NULL},
643 {Opt_resize, "resize"}, 643 {Opt_resize, "resize"},
@@ -876,6 +876,7 @@ set_qf_name:
876 sbi->s_qf_names[qtype] = NULL; 876 sbi->s_qf_names[qtype] = NULL;
877 return 0; 877 return 0;
878 } 878 }
879 set_opt(sbi->s_mount_opt, QUOTA);
879 break; 880 break;
880 case Opt_offusrjquota: 881 case Opt_offusrjquota:
881 qtype = USRQUOTA; 882 qtype = USRQUOTA;
@@ -898,6 +899,17 @@ clear_qf_name:
898 case Opt_jqfmt_vfsv0: 899 case Opt_jqfmt_vfsv0:
899 sbi->s_jquota_fmt = QFMT_VFS_V0; 900 sbi->s_jquota_fmt = QFMT_VFS_V0;
900 break; 901 break;
902 case Opt_quota:
903 set_opt(sbi->s_mount_opt, QUOTA);
904 break;
905 case Opt_noquota:
906 if (sb_any_quota_enabled(sb)) {
907 printk(KERN_ERR "EXT3-fs: Cannot change quota "
908 "options when quota turned on.\n");
909 return 0;
910 }
911 clear_opt(sbi->s_mount_opt, QUOTA);
912 break;
901#else 913#else
902 case Opt_usrjquota: 914 case Opt_usrjquota:
903 case Opt_grpjquota: 915 case Opt_grpjquota:
@@ -909,6 +921,9 @@ clear_qf_name:
909 "EXT3-fs: journalled quota options not " 921 "EXT3-fs: journalled quota options not "
910 "supported.\n"); 922 "supported.\n");
911 break; 923 break;
924 case Opt_quota:
925 case Opt_noquota:
926 break;
912#endif 927#endif
913 case Opt_abort: 928 case Opt_abort:
914 set_opt(sbi->s_mount_opt, ABORT); 929 set_opt(sbi->s_mount_opt, ABORT);
@@ -2238,7 +2253,7 @@ static int ext3_dquot_initialize(struct inode *inode, int type)
2238 int ret, err; 2253 int ret, err;
2239 2254
2240 /* We may create quota structure so we need to reserve enough blocks */ 2255 /* We may create quota structure so we need to reserve enough blocks */
2241 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); 2256 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb));
2242 if (IS_ERR(handle)) 2257 if (IS_ERR(handle))
2243 return PTR_ERR(handle); 2258 return PTR_ERR(handle);
2244 ret = dquot_initialize(inode, type); 2259 ret = dquot_initialize(inode, type);
@@ -2254,7 +2269,7 @@ static int ext3_dquot_drop(struct inode *inode)
2254 int ret, err; 2269 int ret, err;
2255 2270
2256 /* We may delete quota structure so we need to reserve enough blocks */ 2271 /* We may delete quota structure so we need to reserve enough blocks */
2257 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); 2272 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb));
2258 if (IS_ERR(handle)) 2273 if (IS_ERR(handle))
2259 return PTR_ERR(handle); 2274 return PTR_ERR(handle);
2260 ret = dquot_drop(inode); 2275 ret = dquot_drop(inode);
@@ -2272,7 +2287,7 @@ static int ext3_write_dquot(struct dquot *dquot)
2272 2287
2273 inode = dquot_to_inode(dquot); 2288 inode = dquot_to_inode(dquot);
2274 handle = ext3_journal_start(inode, 2289 handle = ext3_journal_start(inode,
2275 EXT3_QUOTA_TRANS_BLOCKS); 2290 EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
2276 if (IS_ERR(handle)) 2291 if (IS_ERR(handle))
2277 return PTR_ERR(handle); 2292 return PTR_ERR(handle);
2278 ret = dquot_commit(dquot); 2293 ret = dquot_commit(dquot);
@@ -2288,7 +2303,7 @@ static int ext3_acquire_dquot(struct dquot *dquot)
2288 handle_t *handle; 2303 handle_t *handle;
2289 2304
2290 handle = ext3_journal_start(dquot_to_inode(dquot), 2305 handle = ext3_journal_start(dquot_to_inode(dquot),
2291 EXT3_QUOTA_INIT_BLOCKS); 2306 EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
2292 if (IS_ERR(handle)) 2307 if (IS_ERR(handle))
2293 return PTR_ERR(handle); 2308 return PTR_ERR(handle);
2294 ret = dquot_acquire(dquot); 2309 ret = dquot_acquire(dquot);
@@ -2304,7 +2319,7 @@ static int ext3_release_dquot(struct dquot *dquot)
2304 handle_t *handle; 2319 handle_t *handle;
2305 2320
2306 handle = ext3_journal_start(dquot_to_inode(dquot), 2321 handle = ext3_journal_start(dquot_to_inode(dquot),
2307 EXT3_QUOTA_INIT_BLOCKS); 2322 EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
2308 if (IS_ERR(handle)) 2323 if (IS_ERR(handle))
2309 return PTR_ERR(handle); 2324 return PTR_ERR(handle);
2310 ret = dquot_release(dquot); 2325 ret = dquot_release(dquot);
@@ -2348,22 +2363,8 @@ static int ext3_write_info(struct super_block *sb, int type)
2348 */ 2363 */
2349static int ext3_quota_on_mount(struct super_block *sb, int type) 2364static int ext3_quota_on_mount(struct super_block *sb, int type)
2350{ 2365{
2351 int err; 2366 return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
2352 struct dentry *dentry; 2367 EXT3_SB(sb)->s_jquota_fmt, type);
2353 struct qstr name = { .name = EXT3_SB(sb)->s_qf_names[type],
2354 .hash = 0,
2355 .len = strlen(EXT3_SB(sb)->s_qf_names[type])};
2356
2357 dentry = lookup_hash(&name, sb->s_root);
2358 if (IS_ERR(dentry))
2359 return PTR_ERR(dentry);
2360 err = vfs_quota_on_mount(type, EXT3_SB(sb)->s_jquota_fmt, dentry);
2361 /* Now invalidate and put the dentry - quota got its own reference
2362 * to inode and dentry has at least wrong hash so we had better
2363 * throw it away */
2364 d_invalidate(dentry);
2365 dput(dentry);
2366 return err;
2367} 2368}
2368 2369
2369/* 2370/*
@@ -2375,6 +2376,8 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
2375 int err; 2376 int err;
2376 struct nameidata nd; 2377 struct nameidata nd;
2377 2378
2379 if (!test_opt(sb, QUOTA))
2380 return -EINVAL;
2378 /* Not journalling quota? */ 2381 /* Not journalling quota? */
2379 if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] && 2382 if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] &&
2380 !EXT3_SB(sb)->s_qf_names[GRPQUOTA]) 2383 !EXT3_SB(sb)->s_qf_names[GRPQUOTA])
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 4cbc6d0212d3..3f9dfa643b19 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -1044,7 +1044,7 @@ ext3_xattr_set(struct inode *inode, int name_index, const char *name,
1044 int error, retries = 0; 1044 int error, retries = 0;
1045 1045
1046retry: 1046retry:
1047 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS); 1047 handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
1048 if (IS_ERR(handle)) { 1048 if (IS_ERR(handle)) {
1049 error = PTR_ERR(handle); 1049 error = PTR_ERR(handle);
1050 } else { 1050 } else {
diff --git a/fs/file_table.c b/fs/file_table.c
index 03d83cb686b1..fa7849fae134 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -63,42 +63,45 @@ static inline void file_free(struct file *f)
63 */ 63 */
64struct file *get_empty_filp(void) 64struct file *get_empty_filp(void)
65{ 65{
66static int old_max; 66 static int old_max;
67 struct file * f; 67 struct file * f;
68 68
69 /* 69 /*
70 * Privileged users can go above max_files 70 * Privileged users can go above max_files
71 */ 71 */
72 if (files_stat.nr_files < files_stat.max_files || 72 if (files_stat.nr_files >= files_stat.max_files &&
73 capable(CAP_SYS_ADMIN)) { 73 !capable(CAP_SYS_ADMIN))
74 f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); 74 goto over;
75 if (f) { 75
76 memset(f, 0, sizeof(*f)); 76 f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
77 if (security_file_alloc(f)) { 77 if (f == NULL)
78 file_free(f); 78 goto fail;
79 goto fail; 79
80 } 80 memset(f, 0, sizeof(*f));
81 eventpoll_init_file(f); 81 if (security_file_alloc(f))
82 atomic_set(&f->f_count, 1); 82 goto fail_sec;
83 f->f_uid = current->fsuid; 83
84 f->f_gid = current->fsgid; 84 eventpoll_init_file(f);
85 rwlock_init(&f->f_owner.lock); 85 atomic_set(&f->f_count, 1);
86 /* f->f_version: 0 */ 86 f->f_uid = current->fsuid;
87 INIT_LIST_HEAD(&f->f_list); 87 f->f_gid = current->fsgid;
88 f->f_maxcount = INT_MAX; 88 rwlock_init(&f->f_owner.lock);
89 return f; 89 /* f->f_version: 0 */
90 } 90 INIT_LIST_HEAD(&f->f_list);
91 } 91 f->f_maxcount = INT_MAX;
92 92 return f;
93
94over:
93 /* Ran out of filps - report that */ 95 /* Ran out of filps - report that */
94 if (files_stat.max_files >= old_max) { 96 if (files_stat.nr_files > old_max) {
95 printk(KERN_INFO "VFS: file-max limit %d reached\n", 97 printk(KERN_INFO "VFS: file-max limit %d reached\n",
96 files_stat.max_files); 98 files_stat.max_files);
97 old_max = files_stat.max_files; 99 old_max = files_stat.nr_files;
98 } else {
99 /* Big problems... */
100 printk(KERN_WARNING "VFS: filp allocation failed\n");
101 } 100 }
101 goto fail;
102
103fail_sec:
104 file_free(f);
102fail: 105fail:
103 return NULL; 106 return NULL;
104} 107}
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 8e050fa58218..e94ab398b717 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -485,32 +485,6 @@ static void set_sb_syncing(int val)
485 spin_unlock(&sb_lock); 485 spin_unlock(&sb_lock);
486} 486}
487 487
488/*
489 * Find a superblock with inodes that need to be synced
490 */
491static struct super_block *get_super_to_sync(void)
492{
493 struct super_block *sb;
494restart:
495 spin_lock(&sb_lock);
496 sb = sb_entry(super_blocks.prev);
497 for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
498 if (sb->s_syncing)
499 continue;
500 sb->s_syncing = 1;
501 sb->s_count++;
502 spin_unlock(&sb_lock);
503 down_read(&sb->s_umount);
504 if (!sb->s_root) {
505 drop_super(sb);
506 goto restart;
507 }
508 return sb;
509 }
510 spin_unlock(&sb_lock);
511 return NULL;
512}
513
514/** 488/**
515 * sync_inodes - writes all inodes to disk 489 * sync_inodes - writes all inodes to disk
516 * @wait: wait for completion 490 * @wait: wait for completion
@@ -530,23 +504,39 @@ restart:
530 * outstanding dirty inodes, the writeback goes block-at-a-time within the 504 * outstanding dirty inodes, the writeback goes block-at-a-time within the
531 * filesystem's write_inode(). This is extremely slow. 505 * filesystem's write_inode(). This is extremely slow.
532 */ 506 */
533void sync_inodes(int wait) 507static void __sync_inodes(int wait)
534{ 508{
535 struct super_block *sb; 509 struct super_block *sb;
536 510
537 set_sb_syncing(0); 511 spin_lock(&sb_lock);
538 while ((sb = get_super_to_sync()) != NULL) { 512restart:
539 sync_inodes_sb(sb, 0); 513 list_for_each_entry(sb, &super_blocks, s_list) {
540 sync_blockdev(sb->s_bdev); 514 if (sb->s_syncing)
541 drop_super(sb); 515 continue;
516 sb->s_syncing = 1;
517 sb->s_count++;
518 spin_unlock(&sb_lock);
519 down_read(&sb->s_umount);
520 if (sb->s_root) {
521 sync_inodes_sb(sb, wait);
522 sync_blockdev(sb->s_bdev);
523 }
524 up_read(&sb->s_umount);
525 spin_lock(&sb_lock);
526 if (__put_super_and_need_restart(sb))
527 goto restart;
542 } 528 }
529 spin_unlock(&sb_lock);
530}
531
532void sync_inodes(int wait)
533{
534 set_sb_syncing(0);
535 __sync_inodes(0);
536
543 if (wait) { 537 if (wait) {
544 set_sb_syncing(0); 538 set_sb_syncing(0);
545 while ((sb = get_super_to_sync()) != NULL) { 539 __sync_inodes(1);
546 sync_inodes_sb(sb, 1);
547 sync_blockdev(sb->s_bdev);
548 drop_super(sb);
549 }
550 } 540 }
551} 541}
552 542
diff --git a/fs/inode.c b/fs/inode.c
index 801fe7f36280..1f9a3a2b89bc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -500,7 +500,7 @@ repeat:
500 continue; 500 continue;
501 if (!test(inode, data)) 501 if (!test(inode, data))
502 continue; 502 continue;
503 if (inode->i_state & (I_FREEING|I_CLEAR)) { 503 if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
504 __wait_on_freeing_inode(inode); 504 __wait_on_freeing_inode(inode);
505 goto repeat; 505 goto repeat;
506 } 506 }
@@ -525,7 +525,7 @@ repeat:
525 continue; 525 continue;
526 if (inode->i_sb != sb) 526 if (inode->i_sb != sb)
527 continue; 527 continue;
528 if (inode->i_state & (I_FREEING|I_CLEAR)) { 528 if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
529 __wait_on_freeing_inode(inode); 529 __wait_on_freeing_inode(inode);
530 goto repeat; 530 goto repeat;
531 } 531 }
@@ -727,7 +727,7 @@ EXPORT_SYMBOL(iunique);
727struct inode *igrab(struct inode *inode) 727struct inode *igrab(struct inode *inode)
728{ 728{
729 spin_lock(&inode_lock); 729 spin_lock(&inode_lock);
730 if (!(inode->i_state & I_FREEING)) 730 if (!(inode->i_state & (I_FREEING|I_WILL_FREE)))
731 __iget(inode); 731 __iget(inode);
732 else 732 else
733 /* 733 /*
@@ -1024,17 +1024,21 @@ static void generic_forget_inode(struct inode *inode)
1024 if (!(inode->i_state & (I_DIRTY|I_LOCK))) 1024 if (!(inode->i_state & (I_DIRTY|I_LOCK)))
1025 list_move(&inode->i_list, &inode_unused); 1025 list_move(&inode->i_list, &inode_unused);
1026 inodes_stat.nr_unused++; 1026 inodes_stat.nr_unused++;
1027 spin_unlock(&inode_lock); 1027 if (!sb || (sb->s_flags & MS_ACTIVE)) {
1028 if (!sb || (sb->s_flags & MS_ACTIVE)) 1028 spin_unlock(&inode_lock);
1029 return; 1029 return;
1030 }
1031 inode->i_state |= I_WILL_FREE;
1032 spin_unlock(&inode_lock);
1030 write_inode_now(inode, 1); 1033 write_inode_now(inode, 1);
1031 spin_lock(&inode_lock); 1034 spin_lock(&inode_lock);
1035 inode->i_state &= ~I_WILL_FREE;
1032 inodes_stat.nr_unused--; 1036 inodes_stat.nr_unused--;
1033 hlist_del_init(&inode->i_hash); 1037 hlist_del_init(&inode->i_hash);
1034 } 1038 }
1035 list_del_init(&inode->i_list); 1039 list_del_init(&inode->i_list);
1036 list_del_init(&inode->i_sb_list); 1040 list_del_init(&inode->i_sb_list);
1037 inode->i_state|=I_FREEING; 1041 inode->i_state |= I_FREEING;
1038 inodes_stat.nr_inodes--; 1042 inodes_stat.nr_inodes--;
1039 spin_unlock(&inode_lock); 1043 spin_unlock(&inode_lock);
1040 if (inode->i_data.nrpages) 1044 if (inode->i_data.nrpages)
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 30a2bf9eeda5..e892dab40c26 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -21,6 +21,7 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include <linux/quotaops.h> 23#include <linux/quotaops.h>
24#include <linux/posix_acl_xattr.h>
24#include "jfs_incore.h" 25#include "jfs_incore.h"
25#include "jfs_xattr.h" 26#include "jfs_xattr.h"
26#include "jfs_acl.h" 27#include "jfs_acl.h"
@@ -36,11 +37,11 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
36 37
37 switch(type) { 38 switch(type) {
38 case ACL_TYPE_ACCESS: 39 case ACL_TYPE_ACCESS:
39 ea_name = XATTR_NAME_ACL_ACCESS; 40 ea_name = POSIX_ACL_XATTR_ACCESS;
40 p_acl = &ji->i_acl; 41 p_acl = &ji->i_acl;
41 break; 42 break;
42 case ACL_TYPE_DEFAULT: 43 case ACL_TYPE_DEFAULT:
43 ea_name = XATTR_NAME_ACL_DEFAULT; 44 ea_name = POSIX_ACL_XATTR_DEFAULT;
44 p_acl = &ji->i_default_acl; 45 p_acl = &ji->i_default_acl;
45 break; 46 break;
46 default: 47 default:
@@ -88,11 +89,11 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
88 89
89 switch(type) { 90 switch(type) {
90 case ACL_TYPE_ACCESS: 91 case ACL_TYPE_ACCESS:
91 ea_name = XATTR_NAME_ACL_ACCESS; 92 ea_name = POSIX_ACL_XATTR_ACCESS;
92 p_acl = &ji->i_acl; 93 p_acl = &ji->i_acl;
93 break; 94 break;
94 case ACL_TYPE_DEFAULT: 95 case ACL_TYPE_DEFAULT:
95 ea_name = XATTR_NAME_ACL_DEFAULT; 96 ea_name = POSIX_ACL_XATTR_DEFAULT;
96 p_acl = &ji->i_default_acl; 97 p_acl = &ji->i_default_acl;
97 if (!S_ISDIR(inode->i_mode)) 98 if (!S_ISDIR(inode->i_mode))
98 return acl ? -EACCES : 0; 99 return acl ? -EACCES : 0;
@@ -101,7 +102,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
101 return -EINVAL; 102 return -EINVAL;
102 } 103 }
103 if (acl) { 104 if (acl) {
104 size = xattr_acl_size(acl->a_count); 105 size = posix_acl_xattr_size(acl->a_count);
105 value = kmalloc(size, GFP_KERNEL); 106 value = kmalloc(size, GFP_KERNEL);
106 if (!value) 107 if (!value)
107 return -ENOMEM; 108 return -ENOMEM;
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index d2ae430adecf..a3acd3eec059 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -20,8 +20,6 @@
20 20
21#ifdef CONFIG_JFS_POSIX_ACL 21#ifdef CONFIG_JFS_POSIX_ACL
22 22
23#include <linux/xattr_acl.h>
24
25int jfs_permission(struct inode *, int, struct nameidata *); 23int jfs_permission(struct inode *, int, struct nameidata *);
26int jfs_init_acl(struct inode *, struct inode *); 24int jfs_init_acl(struct inode *, struct inode *);
27int jfs_setattr(struct dentry *, struct iattr *); 25int jfs_setattr(struct dentry *, struct iattr *);
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 810a3653d8b3..ee32211288ce 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -24,6 +24,7 @@
24#include <linux/completion.h> 24#include <linux/completion.h>
25#include <linux/vfs.h> 25#include <linux/vfs.h>
26#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/posix_acl.h>
27#include <asm/uaccess.h> 28#include <asm/uaccess.h>
28 29
29#include "jfs_incore.h" 30#include "jfs_incore.h"
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 6016373701a3..ee438d429d45 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/xattr.h> 21#include <linux/xattr.h>
22#include <linux/posix_acl_xattr.h>
22#include <linux/quotaops.h> 23#include <linux/quotaops.h>
23#include "jfs_incore.h" 24#include "jfs_incore.h"
24#include "jfs_superblock.h" 25#include "jfs_superblock.h"
@@ -718,9 +719,9 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
718 return -EPERM; 719 return -EPERM;
719 720
720 /* 721 /*
721 * XATTR_NAME_ACL_ACCESS is tied to i_mode 722 * POSIX_ACL_XATTR_ACCESS is tied to i_mode
722 */ 723 */
723 if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) { 724 if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) {
724 acl = posix_acl_from_xattr(value, value_len); 725 acl = posix_acl_from_xattr(value, value_len);
725 if (IS_ERR(acl)) { 726 if (IS_ERR(acl)) {
726 rc = PTR_ERR(acl); 727 rc = PTR_ERR(acl);
@@ -750,7 +751,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
750 JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED; 751 JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
751 752
752 return 0; 753 return 0;
753 } else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) { 754 } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) {
754 acl = posix_acl_from_xattr(value, value_len); 755 acl = posix_acl_from_xattr(value, value_len);
755 if (IS_ERR(acl)) { 756 if (IS_ERR(acl)) {
756 rc = PTR_ERR(acl); 757 rc = PTR_ERR(acl);
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index b82e470912e8..6e242556b903 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -191,7 +191,9 @@ lockd(struct svc_rqst *rqstp)
191 printk(KERN_DEBUG 191 printk(KERN_DEBUG
192 "lockd: new process, skipping host shutdown\n"); 192 "lockd: new process, skipping host shutdown\n");
193 wake_up(&lockd_exit); 193 wake_up(&lockd_exit);
194 194
195 flush_signals(current);
196
195 /* Exit the RPC thread */ 197 /* Exit the RPC thread */
196 svc_exit_thread(rqstp); 198 svc_exit_thread(rqstp);
197 199
diff --git a/fs/namei.c b/fs/namei.c
index a7f7f44119b3..fa8df81ce8ca 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1577,19 +1577,35 @@ do_link:
1577 * 1577 *
1578 * Simple function to lookup and return a dentry and create it 1578 * Simple function to lookup and return a dentry and create it
1579 * if it doesn't exist. Is SMP-safe. 1579 * if it doesn't exist. Is SMP-safe.
1580 *
1581 * Returns with nd->dentry->d_inode->i_sem locked.
1580 */ 1582 */
1581struct dentry *lookup_create(struct nameidata *nd, int is_dir) 1583struct dentry *lookup_create(struct nameidata *nd, int is_dir)
1582{ 1584{
1583 struct dentry *dentry; 1585 struct dentry *dentry = ERR_PTR(-EEXIST);
1584 1586
1585 down(&nd->dentry->d_inode->i_sem); 1587 down(&nd->dentry->d_inode->i_sem);
1586 dentry = ERR_PTR(-EEXIST); 1588 /*
1589 * Yucky last component or no last component at all?
1590 * (foo/., foo/.., /////)
1591 */
1587 if (nd->last_type != LAST_NORM) 1592 if (nd->last_type != LAST_NORM)
1588 goto fail; 1593 goto fail;
1589 nd->flags &= ~LOOKUP_PARENT; 1594 nd->flags &= ~LOOKUP_PARENT;
1595
1596 /*
1597 * Do the final lookup.
1598 */
1590 dentry = lookup_hash(&nd->last, nd->dentry); 1599 dentry = lookup_hash(&nd->last, nd->dentry);
1591 if (IS_ERR(dentry)) 1600 if (IS_ERR(dentry))
1592 goto fail; 1601 goto fail;
1602
1603 /*
1604 * Special case - lookup gave negative, but... we had foo/bar/
1605 * From the vfs_mknod() POV we just have a negative dentry -
1606 * all is fine. Let's be bastards - you had / on the end, you've
1607 * been asking for (non-existent) directory. -ENOENT for you.
1608 */
1593 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) 1609 if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
1594 goto enoent; 1610 goto enoent;
1595 return dentry; 1611 return dentry;
diff --git a/fs/namespace.c b/fs/namespace.c
index 3b93e5d750eb..208c079e9fdb 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -337,7 +337,7 @@ int may_umount(struct vfsmount *mnt)
337 337
338EXPORT_SYMBOL(may_umount); 338EXPORT_SYMBOL(may_umount);
339 339
340void umount_tree(struct vfsmount *mnt) 340static void umount_tree(struct vfsmount *mnt)
341{ 341{
342 struct vfsmount *p; 342 struct vfsmount *p;
343 LIST_HEAD(kill); 343 LIST_HEAD(kill);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index d6a30c844de3..6537f2c4ae44 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -751,11 +751,6 @@ nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count,
751 retval = -EFAULT; 751 retval = -EFAULT;
752 if (!access_ok(VERIFY_READ, iov.iov_base, iov.iov_len)) 752 if (!access_ok(VERIFY_READ, iov.iov_base, iov.iov_len))
753 goto out; 753 goto out;
754 if (file->f_error) {
755 retval = file->f_error;
756 file->f_error = 0;
757 goto out;
758 }
759 retval = -EFBIG; 754 retval = -EFBIG;
760 if (limit != RLIM_INFINITY) { 755 if (limit != RLIM_INFINITY) {
761 if (pos >= limit) { 756 if (pos >= limit) {
diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile
index 9f043f44c92f..ce341dc76d5e 100644
--- a/fs/nfsd/Makefile
+++ b/fs/nfsd/Makefile
@@ -10,5 +10,5 @@ nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o
10nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o 10nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o
11nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o 11nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o
12nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \ 12nfsd-$(CONFIG_NFSD_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \
13 nfs4acl.o nfs4callback.o 13 nfs4acl.o nfs4callback.o nfs4recover.o
14nfsd-objs := $(nfsd-y) 14nfsd-objs := $(nfsd-y)
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 11ebf6c4aa54..4a2105552ac4 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -125,7 +125,7 @@ static short ace2type(struct nfs4_ace *);
125static int _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, unsigned int); 125static int _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, unsigned int);
126static struct posix_acl *_nfsv4_to_posix_one(struct nfs4_acl *, unsigned int); 126static struct posix_acl *_nfsv4_to_posix_one(struct nfs4_acl *, unsigned int);
127int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t); 127int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t);
128int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *); 128static int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *);
129 129
130struct nfs4_acl * 130struct nfs4_acl *
131nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl, 131nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl,
@@ -775,7 +775,7 @@ out_err:
775 return pacl; 775 return pacl;
776} 776}
777 777
778int 778static int
779nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl) 779nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
780{ 780{
781 struct list_head *h, *n; 781 struct list_head *h, *n;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 634465e9cfc6..583c0710e45e 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -54,7 +54,6 @@
54 54
55/* declarations */ 55/* declarations */
56static void nfs4_cb_null(struct rpc_task *task); 56static void nfs4_cb_null(struct rpc_task *task);
57extern spinlock_t recall_lock;
58 57
59/* Index of predefined Linux callback client operations */ 58/* Index of predefined Linux callback client operations */
60 59
@@ -329,12 +328,12 @@ out:
329 .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \ 328 .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \
330} 329}
331 330
332struct rpc_procinfo nfs4_cb_procedures[] = { 331static struct rpc_procinfo nfs4_cb_procedures[] = {
333 PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null), 332 PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null),
334 PROC(CB_RECALL, COMPOUND, enc_cb_recall, dec_cb_recall), 333 PROC(CB_RECALL, COMPOUND, enc_cb_recall, dec_cb_recall),
335}; 334};
336 335
337struct rpc_version nfs_cb_version4 = { 336static struct rpc_version nfs_cb_version4 = {
338 .number = 1, 337 .number = 1,
339 .nrprocs = sizeof(nfs4_cb_procedures)/sizeof(nfs4_cb_procedures[0]), 338 .nrprocs = sizeof(nfs4_cb_procedures)/sizeof(nfs4_cb_procedures[0]),
340 .procs = nfs4_cb_procedures 339 .procs = nfs4_cb_procedures
@@ -348,7 +347,7 @@ static struct rpc_version * nfs_cb_version[] = {
348/* 347/*
349 * Use the SETCLIENTID credential 348 * Use the SETCLIENTID credential
350 */ 349 */
351struct rpc_cred * 350static struct rpc_cred *
352nfsd4_lookupcred(struct nfs4_client *clp, int taskflags) 351nfsd4_lookupcred(struct nfs4_client *clp, int taskflags)
353{ 352{
354 struct auth_cred acred; 353 struct auth_cred acred;
@@ -387,9 +386,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
387 char hostname[32]; 386 char hostname[32];
388 int status; 387 int status;
389 388
390 dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n", 389 if (atomic_read(&cb->cb_set))
391 cb->cb_parsed, atomic_read(&cb->cb_set));
392 if (!cb->cb_parsed || atomic_read(&cb->cb_set))
393 return; 390 return;
394 391
395 /* Initialize address */ 392 /* Initialize address */
@@ -427,7 +424,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
427 * XXX AUTH_UNIX only - need AUTH_GSS.... 424 * XXX AUTH_UNIX only - need AUTH_GSS....
428 */ 425 */
429 sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr)); 426 sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
430 clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX); 427 clnt = rpc_new_client(xprt, hostname, program, 1, RPC_AUTH_UNIX);
431 if (IS_ERR(clnt)) { 428 if (IS_ERR(clnt)) {
432 dprintk("NFSD: couldn't create callback client\n"); 429 dprintk("NFSD: couldn't create callback client\n");
433 goto out_err; 430 goto out_err;
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 4ba540841cf6..5605a26efc57 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -104,7 +104,7 @@ ent_update(struct ent *new, struct ent *itm)
104 ent_init(new, itm); 104 ent_init(new, itm);
105} 105}
106 106
107void 107static void
108ent_put(struct cache_head *ch, struct cache_detail *cd) 108ent_put(struct cache_head *ch, struct cache_detail *cd)
109{ 109{
110 if (cache_put(ch, cd)) { 110 if (cache_put(ch, cd)) {
@@ -186,7 +186,7 @@ warn_no_idmapd(struct cache_detail *detail)
186static int idtoname_parse(struct cache_detail *, char *, int); 186static int idtoname_parse(struct cache_detail *, char *, int);
187static struct ent *idtoname_lookup(struct ent *, int); 187static struct ent *idtoname_lookup(struct ent *, int);
188 188
189struct cache_detail idtoname_cache = { 189static struct cache_detail idtoname_cache = {
190 .hash_size = ENT_HASHMAX, 190 .hash_size = ENT_HASHMAX,
191 .hash_table = idtoname_table, 191 .hash_table = idtoname_table,
192 .name = "nfs4.idtoname", 192 .name = "nfs4.idtoname",
@@ -277,7 +277,7 @@ nametoid_hash(struct ent *ent)
277 return hash_str(ent->name, ENT_HASHBITS); 277 return hash_str(ent->name, ENT_HASHBITS);
278} 278}
279 279
280void 280static void
281nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, 281nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
282 int *blen) 282 int *blen)
283{ 283{
@@ -317,9 +317,9 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
317} 317}
318 318
319static struct ent *nametoid_lookup(struct ent *, int); 319static struct ent *nametoid_lookup(struct ent *, int);
320int nametoid_parse(struct cache_detail *, char *, int); 320static int nametoid_parse(struct cache_detail *, char *, int);
321 321
322struct cache_detail nametoid_cache = { 322static struct cache_detail nametoid_cache = {
323 .hash_size = ENT_HASHMAX, 323 .hash_size = ENT_HASHMAX,
324 .hash_table = nametoid_table, 324 .hash_table = nametoid_table,
325 .name = "nfs4.nametoid", 325 .name = "nfs4.nametoid",
@@ -330,7 +330,7 @@ struct cache_detail nametoid_cache = {
330 .warn_no_listener = warn_no_idmapd, 330 .warn_no_listener = warn_no_idmapd,
331}; 331};
332 332
333int 333static int
334nametoid_parse(struct cache_detail *cd, char *buf, int buflen) 334nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
335{ 335{
336 struct ent ent, *res; 336 struct ent ent, *res;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e8158741e8b5..d71f14517b9c 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -45,6 +45,7 @@
45#include <linux/param.h> 45#include <linux/param.h>
46#include <linux/major.h> 46#include <linux/major.h>
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/file.h>
48 49
49#include <linux/sunrpc/svc.h> 50#include <linux/sunrpc/svc.h>
50#include <linux/nfsd/nfsd.h> 51#include <linux/nfsd/nfsd.h>
@@ -198,6 +199,11 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
198 if (status) 199 if (status)
199 goto out; 200 goto out;
200 switch (open->op_claim_type) { 201 switch (open->op_claim_type) {
202 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
203 status = nfserr_inval;
204 if (open->op_create)
205 goto out;
206 /* fall through */
201 case NFS4_OPEN_CLAIM_NULL: 207 case NFS4_OPEN_CLAIM_NULL:
202 /* 208 /*
203 * (1) set CURRENT_FH to the file being opened, 209 * (1) set CURRENT_FH to the file being opened,
@@ -220,7 +226,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
220 if (status) 226 if (status)
221 goto out; 227 goto out;
222 break; 228 break;
223 case NFS4_OPEN_CLAIM_DELEGATE_CUR:
224 case NFS4_OPEN_CLAIM_DELEGATE_PREV: 229 case NFS4_OPEN_CLAIM_DELEGATE_PREV:
225 printk("NFSD: unsupported OPEN claim type %d\n", 230 printk("NFSD: unsupported OPEN claim type %d\n",
226 open->op_claim_type); 231 open->op_claim_type);
@@ -473,26 +478,27 @@ static inline int
473nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) 478nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
474{ 479{
475 int status; 480 int status;
476 struct file *filp = NULL;
477 481
478 /* no need to check permission - this will be done in nfsd_read() */ 482 /* no need to check permission - this will be done in nfsd_read() */
479 483
484 read->rd_filp = NULL;
480 if (read->rd_offset >= OFFSET_MAX) 485 if (read->rd_offset >= OFFSET_MAX)
481 return nfserr_inval; 486 return nfserr_inval;
482 487
483 nfs4_lock_state(); 488 nfs4_lock_state();
484 /* check stateid */ 489 /* check stateid */
485 if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, 490 if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid,
486 CHECK_FH | RD_STATE, &filp))) { 491 CHECK_FH | RD_STATE, &read->rd_filp))) {
487 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); 492 dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
488 goto out; 493 goto out;
489 } 494 }
495 if (read->rd_filp)
496 get_file(read->rd_filp);
490 status = nfs_ok; 497 status = nfs_ok;
491out: 498out:
492 nfs4_unlock_state(); 499 nfs4_unlock_state();
493 read->rd_rqstp = rqstp; 500 read->rd_rqstp = rqstp;
494 read->rd_fhp = current_fh; 501 read->rd_fhp = current_fh;
495 read->rd_filp = filp;
496 return status; 502 return status;
497} 503}
498 504
@@ -532,6 +538,8 @@ nfsd4_remove(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_rem
532{ 538{
533 int status; 539 int status;
534 540
541 if (nfs4_in_grace())
542 return nfserr_grace;
535 status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen); 543 status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen);
536 if (status == nfserr_symlink) 544 if (status == nfserr_symlink)
537 return nfserr_notdir; 545 return nfserr_notdir;
@@ -550,6 +558,9 @@ nfsd4_rename(struct svc_rqst *rqstp, struct svc_fh *current_fh,
550 558
551 if (!save_fh->fh_dentry) 559 if (!save_fh->fh_dentry)
552 return status; 560 return status;
561 if (nfs4_in_grace() && !(save_fh->fh_export->ex_flags
562 & NFSEXP_NOSUBTREECHECK))
563 return nfserr_grace;
553 status = nfsd_rename(rqstp, save_fh, rename->rn_sname, 564 status = nfsd_rename(rqstp, save_fh, rename->rn_sname,
554 rename->rn_snamelen, current_fh, 565 rename->rn_snamelen, current_fh,
555 rename->rn_tname, rename->rn_tnamelen); 566 rename->rn_tname, rename->rn_tnamelen);
@@ -624,6 +635,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
624 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); 635 dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
625 goto out; 636 goto out;
626 } 637 }
638 if (filp)
639 get_file(filp);
627 nfs4_unlock_state(); 640 nfs4_unlock_state();
628 641
629 write->wr_bytes_written = write->wr_buflen; 642 write->wr_bytes_written = write->wr_buflen;
@@ -635,6 +648,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_writ
635 status = nfsd_write(rqstp, current_fh, filp, write->wr_offset, 648 status = nfsd_write(rqstp, current_fh, filp, write->wr_offset,
636 write->wr_vec, write->wr_vlen, write->wr_buflen, 649 write->wr_vec, write->wr_vlen, write->wr_buflen,
637 &write->wr_how_written); 650 &write->wr_how_written);
651 if (filp)
652 fput(filp);
638 653
639 if (status == nfserr_symlink) 654 if (status == nfserr_symlink)
640 status = nfserr_inval; 655 status = nfserr_inval;
@@ -923,6 +938,9 @@ encode_op:
923 nfs4_put_stateowner(replay_owner); 938 nfs4_put_stateowner(replay_owner);
924 replay_owner = NULL; 939 replay_owner = NULL;
925 } 940 }
941 /* XXX Ugh, we need to get rid of this kind of special case: */
942 if (op->opnum == OP_READ && op->u.read.rd_filp)
943 fput(op->u.read.rd_filp);
926 } 944 }
927 945
928out: 946out:
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
new file mode 100644
index 000000000000..095f1740f3ae
--- /dev/null
+++ b/fs/nfsd/nfs4recover.c
@@ -0,0 +1,431 @@
1/*
2* linux/fs/nfsd/nfs4recover.c
3*
4* Copyright (c) 2004 The Regents of the University of Michigan.
5* All rights reserved.
6*
7* Andy Adamson <andros@citi.umich.edu>
8*
9* Redistribution and use in source and binary forms, with or without
10* modification, are permitted provided that the following conditions
11* are met:
12*
13* 1. Redistributions of source code must retain the above copyright
14* notice, this list of conditions and the following disclaimer.
15* 2. Redistributions in binary form must reproduce the above copyright
16* notice, this list of conditions and the following disclaimer in the
17* documentation and/or other materials provided with the distribution.
18* 3. Neither the name of the University nor the names of its
19* contributors may be used to endorse or promote products derived
20* from this software without specific prior written permission.
21*
22* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*
34*/
35
36
37#include <linux/sunrpc/svc.h>
38#include <linux/nfsd/nfsd.h>
39#include <linux/nfs4.h>
40#include <linux/nfsd/state.h>
41#include <linux/nfsd/xdr4.h>
42#include <linux/param.h>
43#include <linux/file.h>
44#include <linux/namei.h>
45#include <asm/uaccess.h>
46#include <asm/scatterlist.h>
47#include <linux/crypto.h>
48
49
50#define NFSDDBG_FACILITY NFSDDBG_PROC
51
52/* Globals */
53static struct nameidata rec_dir;
54static int rec_dir_init = 0;
55
56static void
57nfs4_save_user(uid_t *saveuid, gid_t *savegid)
58{
59 *saveuid = current->fsuid;
60 *savegid = current->fsgid;
61 current->fsuid = 0;
62 current->fsgid = 0;
63}
64
65static void
66nfs4_reset_user(uid_t saveuid, gid_t savegid)
67{
68 current->fsuid = saveuid;
69 current->fsgid = savegid;
70}
71
72static void
73md5_to_hex(char *out, char *md5)
74{
75 int i;
76
77 for (i=0; i<16; i++) {
78 unsigned char c = md5[i];
79
80 *out++ = '0' + ((c&0xf0)>>4) + (c>=0xa0)*('a'-'9'-1);
81 *out++ = '0' + (c&0x0f) + ((c&0x0f)>=0x0a)*('a'-'9'-1);
82 }
83 *out = '\0';
84}
85
86int
87nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
88{
89 struct xdr_netobj cksum;
90 struct crypto_tfm *tfm;
91 struct scatterlist sg[1];
92 int status = nfserr_resource;
93
94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
95 clname->len, clname->data);
96 tfm = crypto_alloc_tfm("md5", 0);
97 if (tfm == NULL)
98 goto out;
99 cksum.len = crypto_tfm_alg_digestsize(tfm);
100 cksum.data = kmalloc(cksum.len, GFP_KERNEL);
101 if (cksum.data == NULL)
102 goto out;
103 crypto_digest_init(tfm);
104
105 sg[0].page = virt_to_page(clname->data);
106 sg[0].offset = offset_in_page(clname->data);
107 sg[0].length = clname->len;
108
109 crypto_digest_update(tfm, sg, 1);
110 crypto_digest_final(tfm, cksum.data);
111
112 md5_to_hex(dname, cksum.data);
113
114 kfree(cksum.data);
115 status = nfs_ok;
116out:
117 if (tfm)
118 crypto_free_tfm(tfm);
119 return status;
120}
121
122static int
123nfsd4_rec_fsync(struct dentry *dentry)
124{
125 struct file *filp;
126 int status = nfs_ok;
127
128 dprintk("NFSD: nfs4_fsync_rec_dir\n");
129 filp = dentry_open(dget(dentry), mntget(rec_dir.mnt), O_RDWR);
130 if (IS_ERR(filp)) {
131 status = PTR_ERR(filp);
132 goto out;
133 }
134 if (filp->f_op && filp->f_op->fsync)
135 status = filp->f_op->fsync(filp, filp->f_dentry, 0);
136 fput(filp);
137out:
138 if (status)
139 printk("nfsd4: unable to sync recovery directory\n");
140 return status;
141}
142
143int
144nfsd4_create_clid_dir(struct nfs4_client *clp)
145{
146 char *dname = clp->cl_recdir;
147 struct dentry *dentry;
148 uid_t uid;
149 gid_t gid;
150 int status;
151
152 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
153
154 if (!rec_dir_init || clp->cl_firststate)
155 return 0;
156
157 nfs4_save_user(&uid, &gid);
158
159 /* lock the parent */
160 down(&rec_dir.dentry->d_inode->i_sem);
161
162 dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
163 if (IS_ERR(dentry)) {
164 status = PTR_ERR(dentry);
165 goto out_unlock;
166 }
167 status = -EEXIST;
168 if (dentry->d_inode) {
169 dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
170 goto out_put;
171 }
172 status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
173out_put:
174 dput(dentry);
175out_unlock:
176 up(&rec_dir.dentry->d_inode->i_sem);
177 if (status == 0) {
178 clp->cl_firststate = 1;
179 status = nfsd4_rec_fsync(rec_dir.dentry);
180 }
181 nfs4_reset_user(uid, gid);
182 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
183 return status;
184}
185
186typedef int (recdir_func)(struct dentry *, struct dentry *);
187
188struct dentry_list {
189 struct dentry *dentry;
190 struct list_head list;
191};
192
193struct dentry_list_arg {
194 struct list_head dentries;
195 struct dentry *parent;
196};
197
198static int
199nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
200 loff_t offset, ino_t ino, unsigned int d_type)
201{
202 struct dentry_list_arg *dla = arg;
203 struct list_head *dentries = &dla->dentries;
204 struct dentry *parent = dla->parent;
205 struct dentry *dentry;
206 struct dentry_list *child;
207
208 if (name && isdotent(name, namlen))
209 return nfs_ok;
210 dentry = lookup_one_len(name, parent, namlen);
211 if (IS_ERR(dentry))
212 return PTR_ERR(dentry);
213 child = kmalloc(sizeof(*child), GFP_KERNEL);
214 if (child == NULL)
215 return -ENOMEM;
216 child->dentry = dentry;
217 list_add(&child->list, dentries);
218 return 0;
219}
220
221static int
222nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
223{
224 struct file *filp;
225 struct dentry_list_arg dla = {
226 .parent = dir,
227 };
228 struct list_head *dentries = &dla.dentries;
229 struct dentry_list *child;
230 uid_t uid;
231 gid_t gid;
232 int status;
233
234 if (!rec_dir_init)
235 return 0;
236
237 nfs4_save_user(&uid, &gid);
238
239 filp = dentry_open(dget(dir), mntget(rec_dir.mnt),
240 O_RDWR);
241 status = PTR_ERR(filp);
242 if (IS_ERR(filp))
243 goto out;
244 INIT_LIST_HEAD(dentries);
245 status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla);
246 fput(filp);
247 while (!list_empty(dentries)) {
248 child = list_entry(dentries->next, struct dentry_list, list);
249 status = f(dir, child->dentry);
250 if (status)
251 goto out;
252 list_del(&child->list);
253 dput(child->dentry);
254 kfree(child);
255 }
256out:
257 while (!list_empty(dentries)) {
258 child = list_entry(dentries->next, struct dentry_list, list);
259 list_del(&child->list);
260 dput(child->dentry);
261 kfree(child);
262 }
263 nfs4_reset_user(uid, gid);
264 return status;
265}
266
267static int
268nfsd4_remove_clid_file(struct dentry *dir, struct dentry *dentry)
269{
270 int status;
271
272 if (!S_ISREG(dir->d_inode->i_mode)) {
273 printk("nfsd4: non-file found in client recovery directory\n");
274 return -EINVAL;
275 }
276 down(&dir->d_inode->i_sem);
277 status = vfs_unlink(dir->d_inode, dentry);
278 up(&dir->d_inode->i_sem);
279 return status;
280}
281
282static int
283nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry)
284{
285 int status;
286
287 /* For now this directory should already be empty, but we empty it of
288 * any regular files anyway, just in case the directory was created by
289 * a kernel from the future.... */
290 nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
291 down(&dir->d_inode->i_sem);
292 status = vfs_rmdir(dir->d_inode, dentry);
293 up(&dir->d_inode->i_sem);
294 return status;
295}
296
297static int
298nfsd4_unlink_clid_dir(char *name, int namlen)
299{
300 struct dentry *dentry;
301 int status;
302
303 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
304
305 dentry = lookup_one_len(name, rec_dir.dentry, namlen);
306 if (IS_ERR(dentry)) {
307 status = PTR_ERR(dentry);
308 return status;
309 }
310 status = -ENOENT;
311 if (!dentry->d_inode)
312 goto out;
313
314 status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
315out:
316 dput(dentry);
317 return status;
318}
319
320void
321nfsd4_remove_clid_dir(struct nfs4_client *clp)
322{
323 uid_t uid;
324 gid_t gid;
325 int status;
326
327 if (!rec_dir_init || !clp->cl_firststate)
328 return;
329
330 nfs4_save_user(&uid, &gid);
331 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
332 nfs4_reset_user(uid, gid);
333 if (status == 0)
334 status = nfsd4_rec_fsync(rec_dir.dentry);
335 if (status)
336 printk("NFSD: Failed to remove expired client state directory"
337 " %.*s\n", HEXDIR_LEN, clp->cl_recdir);
338 return;
339}
340
341static int
342purge_old(struct dentry *parent, struct dentry *child)
343{
344 int status;
345
346 if (nfs4_has_reclaimed_state(child->d_name.name))
347 return nfs_ok;
348
349 status = nfsd4_clear_clid_dir(parent, child);
350 if (status)
351 printk("failed to remove client recovery directory %s\n",
352 child->d_name.name);
353 /* Keep trying, success or failure: */
354 return nfs_ok;
355}
356
357void
358nfsd4_recdir_purge_old(void) {
359 int status;
360
361 if (!rec_dir_init)
362 return;
363 status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
364 if (status == 0)
365 status = nfsd4_rec_fsync(rec_dir.dentry);
366 if (status)
367 printk("nfsd4: failed to purge old clients from recovery"
368 " directory %s\n", rec_dir.dentry->d_name.name);
369 return;
370}
371
372static int
373load_recdir(struct dentry *parent, struct dentry *child)
374{
375 if (child->d_name.len != HEXDIR_LEN - 1) {
376 printk("nfsd4: illegal name %s in recovery directory\n",
377 child->d_name.name);
378 /* Keep trying; maybe the others are OK: */
379 return nfs_ok;
380 }
381 nfs4_client_to_reclaim(child->d_name.name);
382 return nfs_ok;
383}
384
385int
386nfsd4_recdir_load(void) {
387 int status;
388
389 status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
390 if (status)
391 printk("nfsd4: failed loading clients from recovery"
392 " directory %s\n", rec_dir.dentry->d_name.name);
393 return status;
394}
395
396/*
397 * Hold reference to the recovery directory.
398 */
399
400void
401nfsd4_init_recdir(char *rec_dirname)
402{
403 uid_t uid = 0;
404 gid_t gid = 0;
405 int status;
406
407 printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
408 rec_dirname);
409
410 BUG_ON(rec_dir_init);
411
412 nfs4_save_user(&uid, &gid);
413
414 status = path_lookup(rec_dirname, LOOKUP_FOLLOW, &rec_dir);
415 if (status == -ENOENT)
416 printk("NFSD: recovery directory %s doesn't exist\n",
417 rec_dirname);
418
419 if (!status)
420 rec_dir_init = 1;
421 nfs4_reset_user(uid, gid);
422}
423
424void
425nfsd4_shutdown_recdir(void)
426{
427 if (!rec_dir_init)
428 return;
429 rec_dir_init = 0;
430 path_release(&rec_dir);
431}
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 75e8b137580c..89e36526d7f2 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -48,39 +48,32 @@
48#include <linux/nfs4.h> 48#include <linux/nfs4.h>
49#include <linux/nfsd/state.h> 49#include <linux/nfsd/state.h>
50#include <linux/nfsd/xdr4.h> 50#include <linux/nfsd/xdr4.h>
51#include <linux/namei.h>
51 52
52#define NFSDDBG_FACILITY NFSDDBG_PROC 53#define NFSDDBG_FACILITY NFSDDBG_PROC
53 54
54/* Globals */ 55/* Globals */
55static time_t lease_time = 90; /* default lease time */ 56static time_t lease_time = 90; /* default lease time */
56static time_t old_lease_time = 90; /* past incarnation lease time */ 57static time_t user_lease_time = 90;
57static u32 nfs4_reclaim_init = 0; 58static time_t boot_time;
58time_t boot_time; 59static int in_grace = 1;
59static time_t grace_end = 0;
60static u32 current_clientid = 1; 60static u32 current_clientid = 1;
61static u32 current_ownerid = 1; 61static u32 current_ownerid = 1;
62static u32 current_fileid = 1; 62static u32 current_fileid = 1;
63static u32 current_delegid = 1; 63static u32 current_delegid = 1;
64static u32 nfs4_init; 64static u32 nfs4_init;
65stateid_t zerostateid; /* bits all 0 */ 65static stateid_t zerostateid; /* bits all 0 */
66stateid_t onestateid; /* bits all 1 */ 66static stateid_t onestateid; /* bits all 1 */
67 67
68/* debug counters */ 68#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
69u32 list_add_perfile = 0; 69#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
70u32 list_del_perfile = 0;
71u32 add_perclient = 0;
72u32 del_perclient = 0;
73u32 alloc_file = 0;
74u32 free_file = 0;
75u32 vfsopen = 0;
76u32 vfsclose = 0;
77u32 alloc_delegation= 0;
78u32 free_delegation= 0;
79 70
80/* forward declarations */ 71/* forward declarations */
81struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); 72static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
82static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); 73static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
83static void release_stateid_lockowners(struct nfs4_stateid *open_stp); 74static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
75static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
76static void nfs4_set_recdir(char *recdir);
84 77
85/* Locking: 78/* Locking:
86 * 79 *
@@ -90,6 +83,11 @@ static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
90 */ 83 */
91static DECLARE_MUTEX(client_sema); 84static DECLARE_MUTEX(client_sema);
92 85
86static kmem_cache_t *stateowner_slab = NULL;
87static kmem_cache_t *file_slab = NULL;
88static kmem_cache_t *stateid_slab = NULL;
89static kmem_cache_t *deleg_slab = NULL;
90
93void 91void
94nfs4_lock_state(void) 92nfs4_lock_state(void)
95{ 93{
@@ -118,16 +116,36 @@ opaque_hashval(const void *ptr, int nbytes)
118/* forward declarations */ 116/* forward declarations */
119static void release_stateowner(struct nfs4_stateowner *sop); 117static void release_stateowner(struct nfs4_stateowner *sop);
120static void release_stateid(struct nfs4_stateid *stp, int flags); 118static void release_stateid(struct nfs4_stateid *stp, int flags);
121static void release_file(struct nfs4_file *fp);
122 119
123/* 120/*
124 * Delegation state 121 * Delegation state
125 */ 122 */
126 123
127/* recall_lock protects the del_recall_lru */ 124/* recall_lock protects the del_recall_lru */
128spinlock_t recall_lock; 125static spinlock_t recall_lock = SPIN_LOCK_UNLOCKED;
129static struct list_head del_recall_lru; 126static struct list_head del_recall_lru;
130 127
128static void
129free_nfs4_file(struct kref *kref)
130{
131 struct nfs4_file *fp = container_of(kref, struct nfs4_file, fi_ref);
132 list_del(&fp->fi_hash);
133 iput(fp->fi_inode);
134 kmem_cache_free(file_slab, fp);
135}
136
137static inline void
138put_nfs4_file(struct nfs4_file *fi)
139{
140 kref_put(&fi->fi_ref, free_nfs4_file);
141}
142
143static inline void
144get_nfs4_file(struct nfs4_file *fi)
145{
146 kref_get(&fi->fi_ref);
147}
148
131static struct nfs4_delegation * 149static struct nfs4_delegation *
132alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type) 150alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type)
133{ 151{
@@ -136,13 +154,14 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
136 struct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback; 154 struct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback;
137 155
138 dprintk("NFSD alloc_init_deleg\n"); 156 dprintk("NFSD alloc_init_deleg\n");
139 if ((dp = kmalloc(sizeof(struct nfs4_delegation), 157 dp = kmem_cache_alloc(deleg_slab, GFP_KERNEL);
140 GFP_KERNEL)) == NULL) 158 if (dp == NULL)
141 return dp; 159 return dp;
142 INIT_LIST_HEAD(&dp->dl_del_perfile); 160 INIT_LIST_HEAD(&dp->dl_perfile);
143 INIT_LIST_HEAD(&dp->dl_del_perclnt); 161 INIT_LIST_HEAD(&dp->dl_perclnt);
144 INIT_LIST_HEAD(&dp->dl_recall_lru); 162 INIT_LIST_HEAD(&dp->dl_recall_lru);
145 dp->dl_client = clp; 163 dp->dl_client = clp;
164 get_nfs4_file(fp);
146 dp->dl_file = fp; 165 dp->dl_file = fp;
147 dp->dl_flock = NULL; 166 dp->dl_flock = NULL;
148 get_file(stp->st_vfs_file); 167 get_file(stp->st_vfs_file);
@@ -160,9 +179,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
160 current_fh->fh_handle.fh_size); 179 current_fh->fh_handle.fh_size);
161 dp->dl_time = 0; 180 dp->dl_time = 0;
162 atomic_set(&dp->dl_count, 1); 181 atomic_set(&dp->dl_count, 1);
163 list_add(&dp->dl_del_perfile, &fp->fi_del_perfile); 182 list_add(&dp->dl_perfile, &fp->fi_delegations);
164 list_add(&dp->dl_del_perclnt, &clp->cl_del_perclnt); 183 list_add(&dp->dl_perclnt, &clp->cl_delegations);
165 alloc_delegation++;
166 return dp; 184 return dp;
167} 185}
168 186
@@ -171,8 +189,8 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
171{ 189{
172 if (atomic_dec_and_test(&dp->dl_count)) { 190 if (atomic_dec_and_test(&dp->dl_count)) {
173 dprintk("NFSD: freeing dp %p\n",dp); 191 dprintk("NFSD: freeing dp %p\n",dp);
174 kfree(dp); 192 put_nfs4_file(dp->dl_file);
175 free_delegation++; 193 kmem_cache_free(deleg_slab, dp);
176 } 194 }
177} 195}
178 196
@@ -193,15 +211,14 @@ nfs4_close_delegation(struct nfs4_delegation *dp)
193 if (dp->dl_flock) 211 if (dp->dl_flock)
194 setlease(filp, F_UNLCK, &dp->dl_flock); 212 setlease(filp, F_UNLCK, &dp->dl_flock);
195 nfsd_close(filp); 213 nfsd_close(filp);
196 vfsclose++;
197} 214}
198 215
199/* Called under the state lock. */ 216/* Called under the state lock. */
200static void 217static void
201unhash_delegation(struct nfs4_delegation *dp) 218unhash_delegation(struct nfs4_delegation *dp)
202{ 219{
203 list_del_init(&dp->dl_del_perfile); 220 list_del_init(&dp->dl_perfile);
204 list_del_init(&dp->dl_del_perclnt); 221 list_del_init(&dp->dl_perclnt);
205 spin_lock(&recall_lock); 222 spin_lock(&recall_lock);
206 list_del_init(&dp->dl_recall_lru); 223 list_del_init(&dp->dl_recall_lru);
207 spin_unlock(&recall_lock); 224 spin_unlock(&recall_lock);
@@ -220,8 +237,8 @@ unhash_delegation(struct nfs4_delegation *dp)
220 237
221#define clientid_hashval(id) \ 238#define clientid_hashval(id) \
222 ((id) & CLIENT_HASH_MASK) 239 ((id) & CLIENT_HASH_MASK)
223#define clientstr_hashval(name, namelen) \ 240#define clientstr_hashval(name) \
224 (opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK) 241 (opaque_hashval((name), 8) & CLIENT_HASH_MASK)
225/* 242/*
226 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot 243 * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
227 * used in reboot/reset lease grace period processing 244 * used in reboot/reset lease grace period processing
@@ -331,11 +348,11 @@ expire_client(struct nfs4_client *clp)
331 348
332 INIT_LIST_HEAD(&reaplist); 349 INIT_LIST_HEAD(&reaplist);
333 spin_lock(&recall_lock); 350 spin_lock(&recall_lock);
334 while (!list_empty(&clp->cl_del_perclnt)) { 351 while (!list_empty(&clp->cl_delegations)) {
335 dp = list_entry(clp->cl_del_perclnt.next, struct nfs4_delegation, dl_del_perclnt); 352 dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
336 dprintk("NFSD: expire client. dp %p, fp %p\n", dp, 353 dprintk("NFSD: expire client. dp %p, fp %p\n", dp,
337 dp->dl_flock); 354 dp->dl_flock);
338 list_del_init(&dp->dl_del_perclnt); 355 list_del_init(&dp->dl_perclnt);
339 list_move(&dp->dl_recall_lru, &reaplist); 356 list_move(&dp->dl_recall_lru, &reaplist);
340 } 357 }
341 spin_unlock(&recall_lock); 358 spin_unlock(&recall_lock);
@@ -347,26 +364,26 @@ expire_client(struct nfs4_client *clp)
347 list_del(&clp->cl_idhash); 364 list_del(&clp->cl_idhash);
348 list_del(&clp->cl_strhash); 365 list_del(&clp->cl_strhash);
349 list_del(&clp->cl_lru); 366 list_del(&clp->cl_lru);
350 while (!list_empty(&clp->cl_perclient)) { 367 while (!list_empty(&clp->cl_openowners)) {
351 sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient); 368 sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient);
352 release_stateowner(sop); 369 release_stateowner(sop);
353 } 370 }
354 put_nfs4_client(clp); 371 put_nfs4_client(clp);
355} 372}
356 373
357static struct nfs4_client * 374static struct nfs4_client *
358create_client(struct xdr_netobj name) { 375create_client(struct xdr_netobj name, char *recdir) {
359 struct nfs4_client *clp; 376 struct nfs4_client *clp;
360 377
361 if (!(clp = alloc_client(name))) 378 if (!(clp = alloc_client(name)))
362 goto out; 379 goto out;
380 memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
363 atomic_set(&clp->cl_count, 1); 381 atomic_set(&clp->cl_count, 1);
364 atomic_set(&clp->cl_callback.cb_set, 0); 382 atomic_set(&clp->cl_callback.cb_set, 0);
365 clp->cl_callback.cb_parsed = 0;
366 INIT_LIST_HEAD(&clp->cl_idhash); 383 INIT_LIST_HEAD(&clp->cl_idhash);
367 INIT_LIST_HEAD(&clp->cl_strhash); 384 INIT_LIST_HEAD(&clp->cl_strhash);
368 INIT_LIST_HEAD(&clp->cl_perclient); 385 INIT_LIST_HEAD(&clp->cl_openowners);
369 INIT_LIST_HEAD(&clp->cl_del_perclnt); 386 INIT_LIST_HEAD(&clp->cl_delegations);
370 INIT_LIST_HEAD(&clp->cl_lru); 387 INIT_LIST_HEAD(&clp->cl_lru);
371out: 388out:
372 return clp; 389 return clp;
@@ -392,11 +409,9 @@ copy_cred(struct svc_cred *target, struct svc_cred *source) {
392 get_group_info(target->cr_group_info); 409 get_group_info(target->cr_group_info);
393} 410}
394 411
395static int 412static inline int
396cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) { 413same_name(const char *n1, const char *n2) {
397 if (!n1 || !n2) 414 return 0 == memcmp(n1, n2, HEXDIR_LEN);
398 return 0;
399 return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
400} 415}
401 416
402static int 417static int
@@ -446,7 +461,7 @@ check_name(struct xdr_netobj name) {
446 return 1; 461 return 1;
447} 462}
448 463
449void 464static void
450add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval) 465add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
451{ 466{
452 unsigned int idhashval; 467 unsigned int idhashval;
@@ -458,7 +473,7 @@ add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
458 clp->cl_time = get_seconds(); 473 clp->cl_time = get_seconds();
459} 474}
460 475
461void 476static void
462move_to_confirmed(struct nfs4_client *clp) 477move_to_confirmed(struct nfs4_client *clp)
463{ 478{
464 unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id); 479 unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
@@ -468,8 +483,7 @@ move_to_confirmed(struct nfs4_client *clp)
468 list_del_init(&clp->cl_strhash); 483 list_del_init(&clp->cl_strhash);
469 list_del_init(&clp->cl_idhash); 484 list_del_init(&clp->cl_idhash);
470 list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); 485 list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
471 strhashval = clientstr_hashval(clp->cl_name.data, 486 strhashval = clientstr_hashval(clp->cl_recdir);
472 clp->cl_name.len);
473 list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]); 487 list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
474 renew_client(clp); 488 renew_client(clp);
475} 489}
@@ -500,6 +514,30 @@ find_unconfirmed_client(clientid_t *clid)
500 return NULL; 514 return NULL;
501} 515}
502 516
517static struct nfs4_client *
518find_confirmed_client_by_str(const char *dname, unsigned int hashval)
519{
520 struct nfs4_client *clp;
521
522 list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
523 if (same_name(clp->cl_recdir, dname))
524 return clp;
525 }
526 return NULL;
527}
528
529static struct nfs4_client *
530find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
531{
532 struct nfs4_client *clp;
533
534 list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
535 if (same_name(clp->cl_recdir, dname))
536 return clp;
537 }
538 return NULL;
539}
540
503/* a helper function for parse_callback */ 541/* a helper function for parse_callback */
504static int 542static int
505parse_octet(unsigned int *lenp, char **addrp) 543parse_octet(unsigned int *lenp, char **addrp)
@@ -534,7 +572,7 @@ parse_octet(unsigned int *lenp, char **addrp)
534} 572}
535 573
536/* parse and set the setclientid ipv4 callback address */ 574/* parse and set the setclientid ipv4 callback address */
537int 575static int
538parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp) 576parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp)
539{ 577{
540 int temp = 0; 578 int temp = 0;
@@ -570,7 +608,7 @@ parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigne
570 return 1; 608 return 1;
571} 609}
572 610
573void 611static void
574gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se) 612gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
575{ 613{
576 struct nfs4_callback *cb = &clp->cl_callback; 614 struct nfs4_callback *cb = &clp->cl_callback;
@@ -584,14 +622,12 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
584 goto out_err; 622 goto out_err;
585 cb->cb_prog = se->se_callback_prog; 623 cb->cb_prog = se->se_callback_prog;
586 cb->cb_ident = se->se_callback_ident; 624 cb->cb_ident = se->se_callback_ident;
587 cb->cb_parsed = 1;
588 return; 625 return;
589out_err: 626out_err:
590 printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) " 627 printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
591 "will not receive delegations\n", 628 "will not receive delegations\n",
592 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); 629 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
593 630
594 cb->cb_parsed = 0;
595 return; 631 return;
596} 632}
597 633
@@ -638,59 +674,43 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
638 }; 674 };
639 nfs4_verifier clverifier = setclid->se_verf; 675 nfs4_verifier clverifier = setclid->se_verf;
640 unsigned int strhashval; 676 unsigned int strhashval;
641 struct nfs4_client * conf, * unconf, * new, * clp; 677 struct nfs4_client *conf, *unconf, *new;
642 int status; 678 int status;
679 char dname[HEXDIR_LEN];
643 680
644 status = nfserr_inval; 681 status = nfserr_inval;
645 if (!check_name(clname)) 682 if (!check_name(clname))
646 goto out; 683 goto out;
647 684
685 status = nfs4_make_rec_clidname(dname, &clname);
686 if (status)
687 goto out;
688
648 /* 689 /*
649 * XXX The Duplicate Request Cache (DRC) has been checked (??) 690 * XXX The Duplicate Request Cache (DRC) has been checked (??)
650 * We get here on a DRC miss. 691 * We get here on a DRC miss.
651 */ 692 */
652 693
653 strhashval = clientstr_hashval(clname.data, clname.len); 694 strhashval = clientstr_hashval(dname);
654 695
655 conf = NULL;
656 nfs4_lock_state(); 696 nfs4_lock_state();
657 list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) { 697 conf = find_confirmed_client_by_str(dname, strhashval);
658 if (!cmp_name(&clp->cl_name, &clname)) 698 if (conf) {
659 continue;
660 /* 699 /*
661 * CASE 0: 700 * CASE 0:
662 * clname match, confirmed, different principal 701 * clname match, confirmed, different principal
663 * or different ip_address 702 * or different ip_address
664 */ 703 */
665 status = nfserr_clid_inuse; 704 status = nfserr_clid_inuse;
666 if (!cmp_creds(&clp->cl_cred,&rqstp->rq_cred)) { 705 if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred)
667 printk("NFSD: setclientid: string in use by client" 706 || conf->cl_addr != ip_addr) {
668 "(clientid %08x/%08x)\n",
669 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
670 goto out;
671 }
672 if (clp->cl_addr != ip_addr) {
673 printk("NFSD: setclientid: string in use by client" 707 printk("NFSD: setclientid: string in use by client"
674 "(clientid %08x/%08x)\n", 708 "(clientid %08x/%08x)\n",
675 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id); 709 conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id);
676 goto out; 710 goto out;
677 } 711 }
678
679 /*
680 * cl_name match from a previous SETCLIENTID operation
681 * XXX check for additional matches?
682 */
683 conf = clp;
684 break;
685 }
686 unconf = NULL;
687 list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) {
688 if (!cmp_name(&clp->cl_name, &clname))
689 continue;
690 /* cl_name match from a previous SETCLIENTID operation */
691 unconf = clp;
692 break;
693 } 712 }
713 unconf = find_unconfirmed_client_by_str(dname, strhashval);
694 status = nfserr_resource; 714 status = nfserr_resource;
695 if (!conf) { 715 if (!conf) {
696 /* 716 /*
@@ -699,7 +719,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
699 */ 719 */
700 if (unconf) 720 if (unconf)
701 expire_client(unconf); 721 expire_client(unconf);
702 if (!(new = create_client(clname))) 722 new = create_client(clname, dname);
723 if (new == NULL)
703 goto out; 724 goto out;
704 copy_verf(new, &clverifier); 725 copy_verf(new, &clverifier);
705 new->cl_addr = ip_addr; 726 new->cl_addr = ip_addr;
@@ -722,12 +743,16 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
722 * nfs4_client, but with the new callback info and a 743 * nfs4_client, but with the new callback info and a
723 * new cl_confirm 744 * new cl_confirm
724 */ 745 */
725 if ((unconf) && 746 if (unconf) {
726 cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) && 747 /* Note this is removing unconfirmed {*x***},
727 cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) { 748 * which is stronger than RFC recommended {vxc**}.
728 expire_client(unconf); 749 * This has the advantage that there is at most
750 * one {*x***} in either list at any time.
751 */
752 expire_client(unconf);
729 } 753 }
730 if (!(new = create_client(clname))) 754 new = create_client(clname, dname);
755 if (new == NULL)
731 goto out; 756 goto out;
732 copy_verf(new,&conf->cl_verifier); 757 copy_verf(new,&conf->cl_verifier);
733 new->cl_addr = ip_addr; 758 new->cl_addr = ip_addr;
@@ -745,7 +770,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
745 * using input clverifier, clname, and callback info 770 * using input clverifier, clname, and callback info
746 * and generate a new cl_clientid and cl_confirm. 771 * and generate a new cl_clientid and cl_confirm.
747 */ 772 */
748 if (!(new = create_client(clname))) 773 new = create_client(clname, dname);
774 if (new == NULL)
749 goto out; 775 goto out;
750 copy_verf(new,&clverifier); 776 copy_verf(new,&clverifier);
751 new->cl_addr = ip_addr; 777 new->cl_addr = ip_addr;
@@ -771,7 +797,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid)
771 * new cl_verifier and a new cl_confirm 797 * new cl_verifier and a new cl_confirm
772 */ 798 */
773 expire_client(unconf); 799 expire_client(unconf);
774 if (!(new = create_client(clname))) 800 new = create_client(clname, dname);
801 if (new == NULL)
775 goto out; 802 goto out;
776 copy_verf(new,&clverifier); 803 copy_verf(new,&clverifier);
777 new->cl_addr = ip_addr; 804 new->cl_addr = ip_addr;
@@ -807,7 +834,7 @@ int
807nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm) 834nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
808{ 835{
809 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr; 836 u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
810 struct nfs4_client *clp, *conf = NULL, *unconf = NULL; 837 struct nfs4_client *conf, *unconf;
811 nfs4_verifier confirm = setclientid_confirm->sc_confirm; 838 nfs4_verifier confirm = setclientid_confirm->sc_confirm;
812 clientid_t * clid = &setclientid_confirm->sc_clientid; 839 clientid_t * clid = &setclientid_confirm->sc_clientid;
813 int status; 840 int status;
@@ -820,102 +847,90 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
820 */ 847 */
821 848
822 nfs4_lock_state(); 849 nfs4_lock_state();
823 clp = find_confirmed_client(clid); 850
824 if (clp) { 851 conf = find_confirmed_client(clid);
825 status = nfserr_inval; 852 unconf = find_unconfirmed_client(clid);
826 /* 853
827 * Found a record for this clientid. If the IP addresses 854 status = nfserr_clid_inuse;
828 * don't match, return ERR_INVAL just as if the record had 855 if (conf && conf->cl_addr != ip_addr)
829 * not been found. 856 goto out;
830 */ 857 if (unconf && unconf->cl_addr != ip_addr)
831 if (clp->cl_addr != ip_addr) { 858 goto out;
832 printk("NFSD: setclientid: string in use by client" 859
833 "(clientid %08x/%08x)\n",
834 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
835 goto out;
836 }
837 conf = clp;
838 }
839 clp = find_unconfirmed_client(clid);
840 if (clp) {
841 status = nfserr_inval;
842 if (clp->cl_addr != ip_addr) {
843 printk("NFSD: setclientid: string in use by client"
844 "(clientid %08x/%08x)\n",
845 clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
846 goto out;
847 }
848 unconf = clp;
849 }
850 /* CASE 1:
851 * unconf record that matches input clientid and input confirm.
852 * conf record that matches input clientid.
853 * conf and unconf records match names, verifiers
854 */
855 if ((conf && unconf) && 860 if ((conf && unconf) &&
856 (cmp_verf(&unconf->cl_confirm, &confirm)) && 861 (cmp_verf(&unconf->cl_confirm, &confirm)) &&
857 (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) && 862 (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
858 (cmp_name(&conf->cl_name,&unconf->cl_name)) && 863 (same_name(conf->cl_recdir,unconf->cl_recdir)) &&
859 (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) { 864 (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
865 /* CASE 1:
866 * unconf record that matches input clientid and input confirm.
867 * conf record that matches input clientid.
868 * conf and unconf records match names, verifiers
869 */
860 if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred)) 870 if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred))
861 status = nfserr_clid_inuse; 871 status = nfserr_clid_inuse;
862 else { 872 else {
863 expire_client(conf); 873 /* XXX: We just turn off callbacks until we can handle
864 clp = unconf; 874 * change request correctly. */
865 move_to_confirmed(unconf); 875 atomic_set(&conf->cl_callback.cb_set, 0);
876 gen_confirm(conf);
877 expire_client(unconf);
866 status = nfs_ok; 878 status = nfs_ok;
879
867 } 880 }
868 goto out; 881 } else if ((conf && !unconf) ||
869 }
870 /* CASE 2:
871 * conf record that matches input clientid.
872 * if unconf record that matches input clientid, then unconf->cl_name
873 * or unconf->cl_verifier don't match the conf record.
874 */
875 if ((conf && !unconf) ||
876 ((conf && unconf) && 882 ((conf && unconf) &&
877 (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) || 883 (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
878 !cmp_name(&conf->cl_name, &unconf->cl_name)))) { 884 !same_name(conf->cl_recdir, unconf->cl_recdir)))) {
879 if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) { 885 /* CASE 2:
886 * conf record that matches input clientid.
887 * if unconf record matches input clientid, then
888 * unconf->cl_name or unconf->cl_verifier don't match the
889 * conf record.
890 */
891 if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred))
880 status = nfserr_clid_inuse; 892 status = nfserr_clid_inuse;
881 } else { 893 else
882 clp = conf;
883 status = nfs_ok; 894 status = nfs_ok;
884 } 895 } else if (!conf && unconf
885 goto out; 896 && cmp_verf(&unconf->cl_confirm, &confirm)) {
886 } 897 /* CASE 3:
887 /* CASE 3: 898 * conf record not found.
888 * conf record not found. 899 * unconf record found.
889 * unconf record found. 900 * unconf->cl_confirm matches input confirm
890 * unconf->cl_confirm matches input confirm 901 */
891 */
892 if (!conf && unconf && cmp_verf(&unconf->cl_confirm, &confirm)) {
893 if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) { 902 if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
894 status = nfserr_clid_inuse; 903 status = nfserr_clid_inuse;
895 } else { 904 } else {
896 status = nfs_ok; 905 unsigned int hash =
897 clp = unconf; 906 clientstr_hashval(unconf->cl_recdir);
907 conf = find_confirmed_client_by_str(unconf->cl_recdir,
908 hash);
909 if (conf) {
910 nfsd4_remove_clid_dir(conf);
911 expire_client(conf);
912 }
898 move_to_confirmed(unconf); 913 move_to_confirmed(unconf);
914 conf = unconf;
915 status = nfs_ok;
899 } 916 }
900 goto out; 917 } else if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm)))
901 } 918 && (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm,
902 /* CASE 4: 919 &confirm)))) {
903 * conf record not found, or if conf, then conf->cl_confirm does not 920 /* CASE 4:
904 * match input confirm. 921 * conf record not found, or if conf, conf->cl_confirm does not
905 * unconf record not found, or if unconf, then unconf->cl_confirm 922 * match input confirm.
906 * does not match input confirm. 923 * unconf record not found, or if unconf, unconf->cl_confirm
907 */ 924 * does not match input confirm.
908 if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) && 925 */
909 (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
910 status = nfserr_stale_clientid; 926 status = nfserr_stale_clientid;
911 goto out; 927 } else {
928 /* check that we have hit one of the cases...*/
929 status = nfserr_clid_inuse;
912 } 930 }
913 /* check that we have hit one of the cases...*/
914 status = nfserr_inval;
915 goto out;
916out: 931out:
917 if (!status) 932 if (!status)
918 nfsd4_probe_callback(clp); 933 nfsd4_probe_callback(conf);
919 nfs4_unlock_state(); 934 nfs4_unlock_state();
920 return status; 935 return status;
921} 936}
@@ -961,60 +976,65 @@ alloc_init_file(struct inode *ino)
961 struct nfs4_file *fp; 976 struct nfs4_file *fp;
962 unsigned int hashval = file_hashval(ino); 977 unsigned int hashval = file_hashval(ino);
963 978
964 if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) { 979 fp = kmem_cache_alloc(file_slab, GFP_KERNEL);
980 if (fp) {
981 kref_init(&fp->fi_ref);
965 INIT_LIST_HEAD(&fp->fi_hash); 982 INIT_LIST_HEAD(&fp->fi_hash);
966 INIT_LIST_HEAD(&fp->fi_perfile); 983 INIT_LIST_HEAD(&fp->fi_stateids);
967 INIT_LIST_HEAD(&fp->fi_del_perfile); 984 INIT_LIST_HEAD(&fp->fi_delegations);
968 list_add(&fp->fi_hash, &file_hashtbl[hashval]); 985 list_add(&fp->fi_hash, &file_hashtbl[hashval]);
969 fp->fi_inode = igrab(ino); 986 fp->fi_inode = igrab(ino);
970 fp->fi_id = current_fileid++; 987 fp->fi_id = current_fileid++;
971 alloc_file++;
972 return fp; 988 return fp;
973 } 989 }
974 return NULL; 990 return NULL;
975} 991}
976 992
977static void 993static void
978release_all_files(void) 994nfsd4_free_slab(kmem_cache_t **slab)
979{ 995{
980 int i; 996 int status;
981 struct nfs4_file *fp;
982 997
983 for (i=0;i<FILE_HASH_SIZE;i++) { 998 if (*slab == NULL)
984 while (!list_empty(&file_hashtbl[i])) { 999 return;
985 fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash); 1000 status = kmem_cache_destroy(*slab);
986 /* this should never be more than once... */ 1001 *slab = NULL;
987 if (!list_empty(&fp->fi_perfile) || !list_empty(&fp->fi_del_perfile)) { 1002 WARN_ON(status);
988 printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
989 }
990 release_file(fp);
991 }
992 }
993} 1003}
994 1004
995kmem_cache_t *stateowner_slab = NULL; 1005static void
1006nfsd4_free_slabs(void)
1007{
1008 nfsd4_free_slab(&stateowner_slab);
1009 nfsd4_free_slab(&file_slab);
1010 nfsd4_free_slab(&stateid_slab);
1011 nfsd4_free_slab(&deleg_slab);
1012}
996 1013
997static int 1014static int
998nfsd4_init_slabs(void) 1015nfsd4_init_slabs(void)
999{ 1016{
1000 stateowner_slab = kmem_cache_create("nfsd4_stateowners", 1017 stateowner_slab = kmem_cache_create("nfsd4_stateowners",
1001 sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL); 1018 sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL);
1002 if (stateowner_slab == NULL) { 1019 if (stateowner_slab == NULL)
1003 dprintk("nfsd4: out of memory while initializing nfsv4\n"); 1020 goto out_nomem;
1004 return -ENOMEM; 1021 file_slab = kmem_cache_create("nfsd4_files",
1005 } 1022 sizeof(struct nfs4_file), 0, 0, NULL, NULL);
1023 if (file_slab == NULL)
1024 goto out_nomem;
1025 stateid_slab = kmem_cache_create("nfsd4_stateids",
1026 sizeof(struct nfs4_stateid), 0, 0, NULL, NULL);
1027 if (stateid_slab == NULL)
1028 goto out_nomem;
1029 deleg_slab = kmem_cache_create("nfsd4_delegations",
1030 sizeof(struct nfs4_delegation), 0, 0, NULL, NULL);
1031 if (deleg_slab == NULL)
1032 goto out_nomem;
1006 return 0; 1033 return 0;
1007} 1034out_nomem:
1008 1035 nfsd4_free_slabs();
1009static void 1036 dprintk("nfsd4: out of memory while initializing nfsv4\n");
1010nfsd4_free_slabs(void) 1037 return -ENOMEM;
1011{
1012 int status = 0;
1013
1014 if (stateowner_slab)
1015 status = kmem_cache_destroy(stateowner_slab);
1016 stateowner_slab = NULL;
1017 BUG_ON(status);
1018} 1038}
1019 1039
1020void 1040void
@@ -1055,14 +1075,13 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
1055 INIT_LIST_HEAD(&sop->so_idhash); 1075 INIT_LIST_HEAD(&sop->so_idhash);
1056 INIT_LIST_HEAD(&sop->so_strhash); 1076 INIT_LIST_HEAD(&sop->so_strhash);
1057 INIT_LIST_HEAD(&sop->so_perclient); 1077 INIT_LIST_HEAD(&sop->so_perclient);
1058 INIT_LIST_HEAD(&sop->so_perfilestate); 1078 INIT_LIST_HEAD(&sop->so_stateids);
1059 INIT_LIST_HEAD(&sop->so_perlockowner); /* not used */ 1079 INIT_LIST_HEAD(&sop->so_perstateid); /* not used */
1060 INIT_LIST_HEAD(&sop->so_close_lru); 1080 INIT_LIST_HEAD(&sop->so_close_lru);
1061 sop->so_time = 0; 1081 sop->so_time = 0;
1062 list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]); 1082 list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
1063 list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]); 1083 list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
1064 list_add(&sop->so_perclient, &clp->cl_perclient); 1084 list_add(&sop->so_perclient, &clp->cl_openowners);
1065 add_perclient++;
1066 sop->so_is_open_owner = 1; 1085 sop->so_is_open_owner = 1;
1067 sop->so_id = current_ownerid++; 1086 sop->so_id = current_ownerid++;
1068 sop->so_client = clp; 1087 sop->so_client = clp;
@@ -1080,10 +1099,10 @@ release_stateid_lockowners(struct nfs4_stateid *open_stp)
1080{ 1099{
1081 struct nfs4_stateowner *lock_sop; 1100 struct nfs4_stateowner *lock_sop;
1082 1101
1083 while (!list_empty(&open_stp->st_perlockowner)) { 1102 while (!list_empty(&open_stp->st_lockowners)) {
1084 lock_sop = list_entry(open_stp->st_perlockowner.next, 1103 lock_sop = list_entry(open_stp->st_lockowners.next,
1085 struct nfs4_stateowner, so_perlockowner); 1104 struct nfs4_stateowner, so_perstateid);
1086 /* list_del(&open_stp->st_perlockowner); */ 1105 /* list_del(&open_stp->st_lockowners); */
1087 BUG_ON(lock_sop->so_is_open_owner); 1106 BUG_ON(lock_sop->so_is_open_owner);
1088 release_stateowner(lock_sop); 1107 release_stateowner(lock_sop);
1089 } 1108 }
@@ -1096,14 +1115,12 @@ unhash_stateowner(struct nfs4_stateowner *sop)
1096 1115
1097 list_del(&sop->so_idhash); 1116 list_del(&sop->so_idhash);
1098 list_del(&sop->so_strhash); 1117 list_del(&sop->so_strhash);
1099 if (sop->so_is_open_owner) { 1118 if (sop->so_is_open_owner)
1100 list_del(&sop->so_perclient); 1119 list_del(&sop->so_perclient);
1101 del_perclient++; 1120 list_del(&sop->so_perstateid);
1102 } 1121 while (!list_empty(&sop->so_stateids)) {
1103 list_del(&sop->so_perlockowner); 1122 stp = list_entry(sop->so_stateids.next,
1104 while (!list_empty(&sop->so_perfilestate)) { 1123 struct nfs4_stateid, st_perstateowner);
1105 stp = list_entry(sop->so_perfilestate.next,
1106 struct nfs4_stateid, st_perfilestate);
1107 if (sop->so_is_open_owner) 1124 if (sop->so_is_open_owner)
1108 release_stateid(stp, OPEN_STATE); 1125 release_stateid(stp, OPEN_STATE);
1109 else 1126 else
@@ -1125,14 +1142,14 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
1125 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); 1142 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
1126 1143
1127 INIT_LIST_HEAD(&stp->st_hash); 1144 INIT_LIST_HEAD(&stp->st_hash);
1128 INIT_LIST_HEAD(&stp->st_perfilestate); 1145 INIT_LIST_HEAD(&stp->st_perstateowner);
1129 INIT_LIST_HEAD(&stp->st_perlockowner); 1146 INIT_LIST_HEAD(&stp->st_lockowners);
1130 INIT_LIST_HEAD(&stp->st_perfile); 1147 INIT_LIST_HEAD(&stp->st_perfile);
1131 list_add(&stp->st_hash, &stateid_hashtbl[hashval]); 1148 list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
1132 list_add(&stp->st_perfilestate, &sop->so_perfilestate); 1149 list_add(&stp->st_perstateowner, &sop->so_stateids);
1133 list_add_perfile++; 1150 list_add(&stp->st_perfile, &fp->fi_stateids);
1134 list_add(&stp->st_perfile, &fp->fi_perfile);
1135 stp->st_stateowner = sop; 1151 stp->st_stateowner = sop;
1152 get_nfs4_file(fp);
1136 stp->st_file = fp; 1153 stp->st_file = fp;
1137 stp->st_stateid.si_boot = boot_time; 1154 stp->st_stateid.si_boot = boot_time;
1138 stp->st_stateid.si_stateownerid = sop->so_id; 1155 stp->st_stateid.si_stateownerid = sop->so_id;
@@ -1150,30 +1167,20 @@ release_stateid(struct nfs4_stateid *stp, int flags)
1150 struct file *filp = stp->st_vfs_file; 1167 struct file *filp = stp->st_vfs_file;
1151 1168
1152 list_del(&stp->st_hash); 1169 list_del(&stp->st_hash);
1153 list_del_perfile++;
1154 list_del(&stp->st_perfile); 1170 list_del(&stp->st_perfile);
1155 list_del(&stp->st_perfilestate); 1171 list_del(&stp->st_perstateowner);
1156 if (flags & OPEN_STATE) { 1172 if (flags & OPEN_STATE) {
1157 release_stateid_lockowners(stp); 1173 release_stateid_lockowners(stp);
1158 stp->st_vfs_file = NULL; 1174 stp->st_vfs_file = NULL;
1159 nfsd_close(filp); 1175 nfsd_close(filp);
1160 vfsclose++;
1161 } else if (flags & LOCK_STATE) 1176 } else if (flags & LOCK_STATE)
1162 locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner); 1177 locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
1163 kfree(stp); 1178 put_nfs4_file(stp->st_file);
1179 kmem_cache_free(stateid_slab, stp);
1164 stp = NULL; 1180 stp = NULL;
1165} 1181}
1166 1182
1167static void 1183static void
1168release_file(struct nfs4_file *fp)
1169{
1170 free_file++;
1171 list_del(&fp->fi_hash);
1172 iput(fp->fi_inode);
1173 kfree(fp);
1174}
1175
1176void
1177move_to_close_lru(struct nfs4_stateowner *sop) 1184move_to_close_lru(struct nfs4_stateowner *sop)
1178{ 1185{
1179 dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop); 1186 dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
@@ -1183,11 +1190,10 @@ move_to_close_lru(struct nfs4_stateowner *sop)
1183 sop->so_time = get_seconds(); 1190 sop->so_time = get_seconds();
1184} 1191}
1185 1192
1186void 1193static void
1187release_state_owner(struct nfs4_stateid *stp, int flag) 1194release_state_owner(struct nfs4_stateid *stp, int flag)
1188{ 1195{
1189 struct nfs4_stateowner *sop = stp->st_stateowner; 1196 struct nfs4_stateowner *sop = stp->st_stateowner;
1190 struct nfs4_file *fp = stp->st_file;
1191 1197
1192 dprintk("NFSD: release_state_owner\n"); 1198 dprintk("NFSD: release_state_owner\n");
1193 release_stateid(stp, flag); 1199 release_stateid(stp, flag);
@@ -1196,12 +1202,8 @@ release_state_owner(struct nfs4_stateid *stp, int flag)
1196 * released by the laundromat service after the lease period 1202 * released by the laundromat service after the lease period
1197 * to enable us to handle CLOSE replay 1203 * to enable us to handle CLOSE replay
1198 */ 1204 */
1199 if (sop->so_confirmed && list_empty(&sop->so_perfilestate)) 1205 if (sop->so_confirmed && list_empty(&sop->so_stateids))
1200 move_to_close_lru(sop); 1206 move_to_close_lru(sop);
1201 /* unused nfs4_file's are releseed. XXX slab cache? */
1202 if (list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile)) {
1203 release_file(fp);
1204 }
1205} 1207}
1206 1208
1207static int 1209static int
@@ -1231,8 +1233,10 @@ find_file(struct inode *ino)
1231 struct nfs4_file *fp; 1233 struct nfs4_file *fp;
1232 1234
1233 list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) { 1235 list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
1234 if (fp->fi_inode == ino) 1236 if (fp->fi_inode == ino) {
1237 get_nfs4_file(fp);
1235 return fp; 1238 return fp;
1239 }
1236 } 1240 }
1237 return NULL; 1241 return NULL;
1238} 1242}
@@ -1240,7 +1244,7 @@ find_file(struct inode *ino)
1240#define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0) 1244#define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
1241#define TEST_DENY(x) ((x >= 0 || x < 5)?1:0) 1245#define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
1242 1246
1243void 1247static void
1244set_access(unsigned int *access, unsigned long bmap) { 1248set_access(unsigned int *access, unsigned long bmap) {
1245 int i; 1249 int i;
1246 1250
@@ -1251,7 +1255,7 @@ set_access(unsigned int *access, unsigned long bmap) {
1251 } 1255 }
1252} 1256}
1253 1257
1254void 1258static void
1255set_deny(unsigned int *deny, unsigned long bmap) { 1259set_deny(unsigned int *deny, unsigned long bmap) {
1256 int i; 1260 int i;
1257 1261
@@ -1277,25 +1281,30 @@ test_share(struct nfs4_stateid *stp, struct nfsd4_open *open) {
1277 * Called to check deny when READ with all zero stateid or 1281 * Called to check deny when READ with all zero stateid or
1278 * WRITE with all zero or all one stateid 1282 * WRITE with all zero or all one stateid
1279 */ 1283 */
1280int 1284static int
1281nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) 1285nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1282{ 1286{
1283 struct inode *ino = current_fh->fh_dentry->d_inode; 1287 struct inode *ino = current_fh->fh_dentry->d_inode;
1284 struct nfs4_file *fp; 1288 struct nfs4_file *fp;
1285 struct nfs4_stateid *stp; 1289 struct nfs4_stateid *stp;
1290 int ret;
1286 1291
1287 dprintk("NFSD: nfs4_share_conflict\n"); 1292 dprintk("NFSD: nfs4_share_conflict\n");
1288 1293
1289 fp = find_file(ino); 1294 fp = find_file(ino);
1290 if (fp) { 1295 if (!fp)
1296 return nfs_ok;
1297 ret = nfserr_share_denied;
1291 /* Search for conflicting share reservations */ 1298 /* Search for conflicting share reservations */
1292 list_for_each_entry(stp, &fp->fi_perfile, st_perfile) { 1299 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
1293 if (test_bit(deny_type, &stp->st_deny_bmap) || 1300 if (test_bit(deny_type, &stp->st_deny_bmap) ||
1294 test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap)) 1301 test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
1295 return nfserr_share_denied; 1302 goto out;
1296 }
1297 } 1303 }
1298 return nfs_ok; 1304 ret = nfs_ok;
1305out:
1306 put_nfs4_file(fp);
1307 return ret;
1299} 1308}
1300 1309
1301static inline void 1310static inline void
@@ -1427,7 +1436,7 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
1427 return -EAGAIN; 1436 return -EAGAIN;
1428} 1437}
1429 1438
1430struct lock_manager_operations nfsd_lease_mng_ops = { 1439static struct lock_manager_operations nfsd_lease_mng_ops = {
1431 .fl_break = nfsd_break_deleg_cb, 1440 .fl_break = nfsd_break_deleg_cb,
1432 .fl_release_private = nfsd_release_deleg_cb, 1441 .fl_release_private = nfsd_release_deleg_cb,
1433 .fl_copy_lock = nfsd_copy_lock_deleg_cb, 1442 .fl_copy_lock = nfsd_copy_lock_deleg_cb,
@@ -1526,6 +1535,51 @@ out:
1526 return status; 1535 return status;
1527} 1536}
1528 1537
1538static inline int
1539nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
1540{
1541 if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
1542 return nfserr_openmode;
1543 else
1544 return nfs_ok;
1545}
1546
1547static struct nfs4_delegation *
1548find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
1549{
1550 struct nfs4_delegation *dp;
1551
1552 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) {
1553 if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid)
1554 return dp;
1555 }
1556 return NULL;
1557}
1558
1559static int
1560nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
1561 struct nfs4_delegation **dp)
1562{
1563 int flags;
1564 int status = nfserr_bad_stateid;
1565
1566 *dp = find_delegation_file(fp, &open->op_delegate_stateid);
1567 if (*dp == NULL)
1568 goto out;
1569 flags = open->op_share_access == NFS4_SHARE_ACCESS_READ ?
1570 RD_STATE : WR_STATE;
1571 status = nfs4_check_delegmode(*dp, flags);
1572 if (status)
1573 *dp = NULL;
1574out:
1575 if (open->op_claim_type != NFS4_OPEN_CLAIM_DELEGATE_CUR)
1576 return nfs_ok;
1577 if (status)
1578 return status;
1579 open->op_stateowner->so_confirmed = 1;
1580 return nfs_ok;
1581}
1582
1529static int 1583static int
1530nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp) 1584nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp)
1531{ 1585{
@@ -1533,7 +1587,7 @@ nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_state
1533 int status = nfserr_share_denied; 1587 int status = nfserr_share_denied;
1534 struct nfs4_stateowner *sop = open->op_stateowner; 1588 struct nfs4_stateowner *sop = open->op_stateowner;
1535 1589
1536 list_for_each_entry(local, &fp->fi_perfile, st_perfile) { 1590 list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
1537 /* ignore lock owners */ 1591 /* ignore lock owners */
1538 if (local->st_stateowner->so_is_open_owner == 0) 1592 if (local->st_stateowner->so_is_open_owner == 0)
1539 continue; 1593 continue;
@@ -1549,25 +1603,37 @@ out:
1549 return status; 1603 return status;
1550} 1604}
1551 1605
1606static inline struct nfs4_stateid *
1607nfs4_alloc_stateid(void)
1608{
1609 return kmem_cache_alloc(stateid_slab, GFP_KERNEL);
1610}
1611
1552static int 1612static int
1553nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, 1613nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
1614 struct nfs4_delegation *dp,
1554 struct svc_fh *cur_fh, int flags) 1615 struct svc_fh *cur_fh, int flags)
1555{ 1616{
1556 struct nfs4_stateid *stp; 1617 struct nfs4_stateid *stp;
1557 int status;
1558 1618
1559 stp = kmalloc(sizeof(struct nfs4_stateid), GFP_KERNEL); 1619 stp = nfs4_alloc_stateid();
1560 if (stp == NULL) 1620 if (stp == NULL)
1561 return nfserr_resource; 1621 return nfserr_resource;
1562 1622
1563 status = nfsd_open(rqstp, cur_fh, S_IFREG, flags, &stp->st_vfs_file); 1623 if (dp) {
1564 if (status) { 1624 get_file(dp->dl_vfs_file);
1565 if (status == nfserr_dropit) 1625 stp->st_vfs_file = dp->dl_vfs_file;
1566 status = nfserr_jukebox; 1626 } else {
1567 kfree(stp); 1627 int status;
1568 return status; 1628 status = nfsd_open(rqstp, cur_fh, S_IFREG, flags,
1629 &stp->st_vfs_file);
1630 if (status) {
1631 if (status == nfserr_dropit)
1632 status = nfserr_jukebox;
1633 kmem_cache_free(stateid_slab, stp);
1634 return status;
1635 }
1569 } 1636 }
1570 vfsopen++;
1571 *stpp = stp; 1637 *stpp = stp;
1572 return 0; 1638 return 0;
1573} 1639}
@@ -1628,6 +1694,7 @@ nfs4_set_claim_prev(struct nfsd4_open *open, int *status)
1628 *status = nfserr_reclaim_bad; 1694 *status = nfserr_reclaim_bad;
1629 else { 1695 else {
1630 open->op_stateowner->so_confirmed = 1; 1696 open->op_stateowner->so_confirmed = 1;
1697 open->op_stateowner->so_client->cl_firststate = 1;
1631 open->op_stateowner->so_seqid--; 1698 open->op_stateowner->so_seqid--;
1632 } 1699 }
1633 } 1700 }
@@ -1646,14 +1713,30 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
1646 int status, flag = 0; 1713 int status, flag = 0;
1647 1714
1648 flag = NFS4_OPEN_DELEGATE_NONE; 1715 flag = NFS4_OPEN_DELEGATE_NONE;
1649 if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL 1716 open->op_recall = 0;
1650 || !atomic_read(&cb->cb_set) || !sop->so_confirmed) 1717 switch (open->op_claim_type) {
1651 goto out; 1718 case NFS4_OPEN_CLAIM_PREVIOUS:
1652 1719 if (!atomic_read(&cb->cb_set))
1653 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 1720 open->op_recall = 1;
1654 flag = NFS4_OPEN_DELEGATE_WRITE; 1721 flag = open->op_delegate_type;
1655 else 1722 if (flag == NFS4_OPEN_DELEGATE_NONE)
1656 flag = NFS4_OPEN_DELEGATE_READ; 1723 goto out;
1724 break;
1725 case NFS4_OPEN_CLAIM_NULL:
1726 /* Let's not give out any delegations till everyone's
1727 * had the chance to reclaim theirs.... */
1728 if (nfs4_in_grace())
1729 goto out;
1730 if (!atomic_read(&cb->cb_set) || !sop->so_confirmed)
1731 goto out;
1732 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
1733 flag = NFS4_OPEN_DELEGATE_WRITE;
1734 else
1735 flag = NFS4_OPEN_DELEGATE_READ;
1736 break;
1737 default:
1738 goto out;
1739 }
1657 1740
1658 dp = alloc_init_deleg(sop->so_client, stp, fh, flag); 1741 dp = alloc_init_deleg(sop->so_client, stp, fh, flag);
1659 if (dp == NULL) { 1742 if (dp == NULL) {
@@ -1687,6 +1770,10 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
1687 dp->dl_stateid.si_fileid, 1770 dp->dl_stateid.si_fileid,
1688 dp->dl_stateid.si_generation); 1771 dp->dl_stateid.si_generation);
1689out: 1772out:
1773 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
1774 && flag == NFS4_OPEN_DELEGATE_NONE
1775 && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
1776 printk("NFSD: WARNING: refusing delegation reclaim\n");
1690 open->op_delegate_type = flag; 1777 open->op_delegate_type = flag;
1691} 1778}
1692 1779
@@ -1699,6 +1786,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1699 struct nfs4_file *fp = NULL; 1786 struct nfs4_file *fp = NULL;
1700 struct inode *ino = current_fh->fh_dentry->d_inode; 1787 struct inode *ino = current_fh->fh_dentry->d_inode;
1701 struct nfs4_stateid *stp = NULL; 1788 struct nfs4_stateid *stp = NULL;
1789 struct nfs4_delegation *dp = NULL;
1702 int status; 1790 int status;
1703 1791
1704 status = nfserr_inval; 1792 status = nfserr_inval;
@@ -1713,7 +1801,13 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1713 if (fp) { 1801 if (fp) {
1714 if ((status = nfs4_check_open(fp, open, &stp))) 1802 if ((status = nfs4_check_open(fp, open, &stp)))
1715 goto out; 1803 goto out;
1804 status = nfs4_check_deleg(fp, open, &dp);
1805 if (status)
1806 goto out;
1716 } else { 1807 } else {
1808 status = nfserr_bad_stateid;
1809 if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
1810 goto out;
1717 status = nfserr_resource; 1811 status = nfserr_resource;
1718 fp = alloc_init_file(ino); 1812 fp = alloc_init_file(ino);
1719 if (fp == NULL) 1813 if (fp == NULL)
@@ -1736,7 +1830,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1736 flags = MAY_WRITE; 1830 flags = MAY_WRITE;
1737 else 1831 else
1738 flags = MAY_READ; 1832 flags = MAY_READ;
1739 if ((status = nfs4_new_open(rqstp, &stp, current_fh, flags))) 1833 status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags);
1834 if (status)
1740 goto out; 1835 goto out;
1741 init_stateid(stp, fp, open); 1836 init_stateid(stp, fp, open);
1742 status = nfsd4_truncate(rqstp, current_fh, open); 1837 status = nfsd4_truncate(rqstp, current_fh, open);
@@ -1759,10 +1854,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1759 stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid, 1854 stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
1760 stp->st_stateid.si_fileid, stp->st_stateid.si_generation); 1855 stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
1761out: 1856out:
1762 /* take the opportunity to clean up unused state */ 1857 if (fp)
1763 if (fp && list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile)) 1858 put_nfs4_file(fp);
1764 release_file(fp);
1765
1766 /* CLAIM_PREVIOUS has different error returns */ 1859 /* CLAIM_PREVIOUS has different error returns */
1767 nfs4_set_claim_prev(open, &status); 1860 nfs4_set_claim_prev(open, &status);
1768 /* 1861 /*
@@ -1775,6 +1868,7 @@ out:
1775 return status; 1868 return status;
1776} 1869}
1777 1870
1871static struct workqueue_struct *laundry_wq;
1778static struct work_struct laundromat_work; 1872static struct work_struct laundromat_work;
1779static void laundromat_main(void *); 1873static void laundromat_main(void *);
1780static DECLARE_WORK(laundromat_work, laundromat_main, NULL); 1874static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
@@ -1800,7 +1894,7 @@ nfsd4_renew(clientid_t *clid)
1800 } 1894 }
1801 renew_client(clp); 1895 renew_client(clp);
1802 status = nfserr_cb_path_down; 1896 status = nfserr_cb_path_down;
1803 if (!list_empty(&clp->cl_del_perclnt) 1897 if (!list_empty(&clp->cl_delegations)
1804 && !atomic_read(&clp->cl_callback.cb_set)) 1898 && !atomic_read(&clp->cl_callback.cb_set))
1805 goto out; 1899 goto out;
1806 status = nfs_ok; 1900 status = nfs_ok;
@@ -1809,7 +1903,15 @@ out:
1809 return status; 1903 return status;
1810} 1904}
1811 1905
1812time_t 1906static void
1907end_grace(void)
1908{
1909 dprintk("NFSD: end of grace period\n");
1910 nfsd4_recdir_purge_old();
1911 in_grace = 0;
1912}
1913
1914static time_t
1813nfs4_laundromat(void) 1915nfs4_laundromat(void)
1814{ 1916{
1815 struct nfs4_client *clp; 1917 struct nfs4_client *clp;
@@ -1823,6 +1925,8 @@ nfs4_laundromat(void)
1823 nfs4_lock_state(); 1925 nfs4_lock_state();
1824 1926
1825 dprintk("NFSD: laundromat service - starting\n"); 1927 dprintk("NFSD: laundromat service - starting\n");
1928 if (in_grace)
1929 end_grace();
1826 list_for_each_safe(pos, next, &client_lru) { 1930 list_for_each_safe(pos, next, &client_lru) {
1827 clp = list_entry(pos, struct nfs4_client, cl_lru); 1931 clp = list_entry(pos, struct nfs4_client, cl_lru);
1828 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { 1932 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
@@ -1833,6 +1937,7 @@ nfs4_laundromat(void)
1833 } 1937 }
1834 dprintk("NFSD: purging unused client (clientid %08x)\n", 1938 dprintk("NFSD: purging unused client (clientid %08x)\n",
1835 clp->cl_clientid.cl_id); 1939 clp->cl_clientid.cl_id);
1940 nfsd4_remove_clid_dir(clp);
1836 expire_client(clp); 1941 expire_client(clp);
1837 } 1942 }
1838 INIT_LIST_HEAD(&reaplist); 1943 INIT_LIST_HEAD(&reaplist);
@@ -1882,13 +1987,13 @@ laundromat_main(void *not_used)
1882 1987
1883 t = nfs4_laundromat(); 1988 t = nfs4_laundromat();
1884 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t); 1989 dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
1885 schedule_delayed_work(&laundromat_work, t*HZ); 1990 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
1886} 1991}
1887 1992
1888/* search ownerid_hashtbl[] and close_lru for stateid owner 1993/* search ownerid_hashtbl[] and close_lru for stateid owner
1889 * (stateid->si_stateownerid) 1994 * (stateid->si_stateownerid)
1890 */ 1995 */
1891struct nfs4_stateowner * 1996static struct nfs4_stateowner *
1892find_openstateowner_id(u32 st_id, int flags) { 1997find_openstateowner_id(u32 st_id, int flags) {
1893 struct nfs4_stateowner *local = NULL; 1998 struct nfs4_stateowner *local = NULL;
1894 1999
@@ -1949,15 +2054,6 @@ out:
1949} 2054}
1950 2055
1951static inline int 2056static inline int
1952nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
1953{
1954 if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
1955 return nfserr_openmode;
1956 else
1957 return nfs_ok;
1958}
1959
1960static inline int
1961check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags) 2057check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
1962{ 2058{
1963 /* Trying to call delegreturn with a special stateid? Yuch: */ 2059 /* Trying to call delegreturn with a special stateid? Yuch: */
@@ -2071,7 +2167,7 @@ out:
2071/* 2167/*
2072 * Checks for sequence id mutating operations. 2168 * Checks for sequence id mutating operations.
2073 */ 2169 */
2074int 2170static int
2075nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, clientid_t *lockclid) 2171nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, clientid_t *lockclid)
2076{ 2172{
2077 int status; 2173 int status;
@@ -2230,6 +2326,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
2230 stp->st_stateid.si_stateownerid, 2326 stp->st_stateid.si_stateownerid,
2231 stp->st_stateid.si_fileid, 2327 stp->st_stateid.si_fileid,
2232 stp->st_stateid.si_generation); 2328 stp->st_stateid.si_generation);
2329
2330 nfsd4_create_clid_dir(sop->so_client);
2233out: 2331out:
2234 if (oc->oc_stateowner) 2332 if (oc->oc_stateowner)
2235 nfs4_get_stateowner(oc->oc_stateowner); 2333 nfs4_get_stateowner(oc->oc_stateowner);
@@ -2387,7 +2485,7 @@ static struct list_head lock_ownerid_hashtbl[LOCK_HASH_SIZE];
2387static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE]; 2485static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
2388static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE]; 2486static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
2389 2487
2390struct nfs4_stateid * 2488static struct nfs4_stateid *
2391find_stateid(stateid_t *stid, int flags) 2489find_stateid(stateid_t *stid, int flags)
2392{ 2490{
2393 struct nfs4_stateid *local = NULL; 2491 struct nfs4_stateid *local = NULL;
@@ -2419,25 +2517,19 @@ find_stateid(stateid_t *stid, int flags)
2419static struct nfs4_delegation * 2517static struct nfs4_delegation *
2420find_delegation_stateid(struct inode *ino, stateid_t *stid) 2518find_delegation_stateid(struct inode *ino, stateid_t *stid)
2421{ 2519{
2422 struct nfs4_delegation *dp = NULL; 2520 struct nfs4_file *fp;
2423 struct nfs4_file *fp = NULL; 2521 struct nfs4_delegation *dl;
2424 u32 st_id;
2425 2522
2426 dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n", 2523 dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n",
2427 stid->si_boot, stid->si_stateownerid, 2524 stid->si_boot, stid->si_stateownerid,
2428 stid->si_fileid, stid->si_generation); 2525 stid->si_fileid, stid->si_generation);
2429 2526
2430 st_id = stid->si_stateownerid;
2431 fp = find_file(ino); 2527 fp = find_file(ino);
2432 if (fp) { 2528 if (!fp)
2433 list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) { 2529 return NULL;
2434 if(dp->dl_stateid.si_stateownerid == st_id) { 2530 dl = find_delegation_file(fp, stid);
2435 dprintk("NFSD: find_delegation dp %p\n",dp); 2531 put_nfs4_file(fp);
2436 return dp; 2532 return dl;
2437 }
2438 }
2439 }
2440 return NULL;
2441} 2533}
2442 2534
2443/* 2535/*
@@ -2457,7 +2549,7 @@ nfs4_transform_lock_offset(struct file_lock *lock)
2457 lock->fl_end = OFFSET_MAX; 2549 lock->fl_end = OFFSET_MAX;
2458} 2550}
2459 2551
2460int 2552static int
2461nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval) 2553nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
2462{ 2554{
2463 struct nfs4_stateowner *local = NULL; 2555 struct nfs4_stateowner *local = NULL;
@@ -2498,22 +2590,6 @@ nfs4_set_lock_denied(struct file_lock *fl, struct nfsd4_lock_denied *deny)
2498} 2590}
2499 2591
2500static struct nfs4_stateowner * 2592static struct nfs4_stateowner *
2501find_lockstateowner(struct xdr_netobj *owner, clientid_t *clid)
2502{
2503 struct nfs4_stateowner *local = NULL;
2504 int i;
2505
2506 for (i = 0; i < LOCK_HASH_SIZE; i++) {
2507 list_for_each_entry(local, &lock_ownerid_hashtbl[i], so_idhash) {
2508 if (!cmp_owner_str(local, owner, clid))
2509 continue;
2510 return local;
2511 }
2512 }
2513 return NULL;
2514}
2515
2516static struct nfs4_stateowner *
2517find_lockstateowner_str(struct inode *inode, clientid_t *clid, 2593find_lockstateowner_str(struct inode *inode, clientid_t *clid,
2518 struct xdr_netobj *owner) 2594 struct xdr_netobj *owner)
2519{ 2595{
@@ -2548,13 +2624,13 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
2548 INIT_LIST_HEAD(&sop->so_idhash); 2624 INIT_LIST_HEAD(&sop->so_idhash);
2549 INIT_LIST_HEAD(&sop->so_strhash); 2625 INIT_LIST_HEAD(&sop->so_strhash);
2550 INIT_LIST_HEAD(&sop->so_perclient); 2626 INIT_LIST_HEAD(&sop->so_perclient);
2551 INIT_LIST_HEAD(&sop->so_perfilestate); 2627 INIT_LIST_HEAD(&sop->so_stateids);
2552 INIT_LIST_HEAD(&sop->so_perlockowner); 2628 INIT_LIST_HEAD(&sop->so_perstateid);
2553 INIT_LIST_HEAD(&sop->so_close_lru); /* not used */ 2629 INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
2554 sop->so_time = 0; 2630 sop->so_time = 0;
2555 list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]); 2631 list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
2556 list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]); 2632 list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
2557 list_add(&sop->so_perlockowner, &open_stp->st_perlockowner); 2633 list_add(&sop->so_perstateid, &open_stp->st_lockowners);
2558 sop->so_is_open_owner = 0; 2634 sop->so_is_open_owner = 0;
2559 sop->so_id = current_ownerid++; 2635 sop->so_id = current_ownerid++;
2560 sop->so_client = clp; 2636 sop->so_client = clp;
@@ -2567,24 +2643,24 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
2567 return sop; 2643 return sop;
2568} 2644}
2569 2645
2570struct nfs4_stateid * 2646static struct nfs4_stateid *
2571alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp) 2647alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
2572{ 2648{
2573 struct nfs4_stateid *stp; 2649 struct nfs4_stateid *stp;
2574 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id); 2650 unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
2575 2651
2576 if ((stp = kmalloc(sizeof(struct nfs4_stateid), 2652 stp = nfs4_alloc_stateid();
2577 GFP_KERNEL)) == NULL) 2653 if (stp == NULL)
2578 goto out; 2654 goto out;
2579 INIT_LIST_HEAD(&stp->st_hash); 2655 INIT_LIST_HEAD(&stp->st_hash);
2580 INIT_LIST_HEAD(&stp->st_perfile); 2656 INIT_LIST_HEAD(&stp->st_perfile);
2581 INIT_LIST_HEAD(&stp->st_perfilestate); 2657 INIT_LIST_HEAD(&stp->st_perstateowner);
2582 INIT_LIST_HEAD(&stp->st_perlockowner); /* not used */ 2658 INIT_LIST_HEAD(&stp->st_lockowners); /* not used */
2583 list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]); 2659 list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
2584 list_add(&stp->st_perfile, &fp->fi_perfile); 2660 list_add(&stp->st_perfile, &fp->fi_stateids);
2585 list_add_perfile++; 2661 list_add(&stp->st_perstateowner, &sop->so_stateids);
2586 list_add(&stp->st_perfilestate, &sop->so_perfilestate);
2587 stp->st_stateowner = sop; 2662 stp->st_stateowner = sop;
2663 get_nfs4_file(fp);
2588 stp->st_file = fp; 2664 stp->st_file = fp;
2589 stp->st_stateid.si_boot = boot_time; 2665 stp->st_stateid.si_boot = boot_time;
2590 stp->st_stateid.si_stateownerid = sop->so_id; 2666 stp->st_stateid.si_stateownerid = sop->so_id;
@@ -2598,7 +2674,7 @@ out:
2598 return stp; 2674 return stp;
2599} 2675}
2600 2676
2601int 2677static int
2602check_lock_length(u64 offset, u64 length) 2678check_lock_length(u64 offset, u64 length)
2603{ 2679{
2604 return ((length == 0) || ((length != ~(u64)0) && 2680 return ((length == 0) || ((length != ~(u64)0) &&
@@ -2611,7 +2687,7 @@ check_lock_length(u64 offset, u64 length)
2611int 2687int
2612nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock) 2688nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
2613{ 2689{
2614 struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL; 2690 struct nfs4_stateowner *open_sop = NULL;
2615 struct nfs4_stateid *lock_stp; 2691 struct nfs4_stateid *lock_stp;
2616 struct file *filp; 2692 struct file *filp;
2617 struct file_lock file_lock; 2693 struct file_lock file_lock;
@@ -2670,16 +2746,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2670 strhashval = lock_ownerstr_hashval(fp->fi_inode, 2746 strhashval = lock_ownerstr_hashval(fp->fi_inode,
2671 open_sop->so_client->cl_clientid.cl_id, 2747 open_sop->so_client->cl_clientid.cl_id,
2672 &lock->v.new.owner); 2748 &lock->v.new.owner);
2673 /* 2749 /* XXX: Do we need to check for duplicate stateowners on
2674 * If we already have this lock owner, the client is in 2750 * the same file, or should they just be allowed (and
2675 * error (or our bookeeping is wrong!) 2751 * create new stateids)? */
2676 * for asking for a 'new lock'.
2677 */
2678 status = nfserr_bad_stateid;
2679 lock_sop = find_lockstateowner(&lock->v.new.owner,
2680 &lock->v.new.clientid);
2681 if (lock_sop)
2682 goto out;
2683 status = nfserr_resource; 2752 status = nfserr_resource;
2684 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock))) 2753 if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
2685 goto out; 2754 goto out;
@@ -2970,8 +3039,11 @@ int
2970nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner) 3039nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
2971{ 3040{
2972 clientid_t *clid = &rlockowner->rl_clientid; 3041 clientid_t *clid = &rlockowner->rl_clientid;
2973 struct nfs4_stateowner *local = NULL; 3042 struct nfs4_stateowner *sop;
3043 struct nfs4_stateid *stp;
2974 struct xdr_netobj *owner = &rlockowner->rl_owner; 3044 struct xdr_netobj *owner = &rlockowner->rl_owner;
3045 struct list_head matches;
3046 int i;
2975 int status; 3047 int status;
2976 3048
2977 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n", 3049 dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
@@ -2987,22 +3059,32 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
2987 3059
2988 nfs4_lock_state(); 3060 nfs4_lock_state();
2989 3061
2990 status = nfs_ok; 3062 status = nfserr_locks_held;
2991 local = find_lockstateowner(owner, clid); 3063 /* XXX: we're doing a linear search through all the lockowners.
2992 if (local) { 3064 * Yipes! For now we'll just hope clients aren't really using
2993 struct nfs4_stateid *stp; 3065 * release_lockowner much, but eventually we have to fix these
2994 3066 * data structures. */
2995 /* check for any locks held by any stateid 3067 INIT_LIST_HEAD(&matches);
2996 * associated with the (lock) stateowner */ 3068 for (i = 0; i < LOCK_HASH_SIZE; i++) {
2997 status = nfserr_locks_held; 3069 list_for_each_entry(sop, &lock_ownerid_hashtbl[i], so_idhash) {
2998 list_for_each_entry(stp, &local->so_perfilestate, 3070 if (!cmp_owner_str(sop, owner, clid))
2999 st_perfilestate) { 3071 continue;
3000 if (check_for_locks(stp->st_vfs_file, local)) 3072 list_for_each_entry(stp, &sop->so_stateids,
3001 goto out; 3073 st_perstateowner) {
3074 if (check_for_locks(stp->st_vfs_file, sop))
3075 goto out;
3076 /* Note: so_perclient unused for lockowners,
3077 * so it's OK to fool with here. */
3078 list_add(&sop->so_perclient, &matches);
3079 }
3002 } 3080 }
3003 /* no locks held by (lock) stateowner */ 3081 }
3004 status = nfs_ok; 3082 /* Clients probably won't expect us to return with some (but not all)
3005 release_stateowner(local); 3083 * of the lockowner state released; so don't release any until all
3084 * have been checked. */
3085 status = nfs_ok;
3086 list_for_each_entry(sop, &matches, so_perclient) {
3087 release_stateowner(sop);
3006 } 3088 }
3007out: 3089out:
3008 nfs4_unlock_state(); 3090 nfs4_unlock_state();
@@ -3010,39 +3092,38 @@ out:
3010} 3092}
3011 3093
3012static inline struct nfs4_client_reclaim * 3094static inline struct nfs4_client_reclaim *
3013alloc_reclaim(int namelen) 3095alloc_reclaim(void)
3014{ 3096{
3015 struct nfs4_client_reclaim *crp = NULL; 3097 return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
3098}
3016 3099
3017 crp = kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL); 3100int
3018 if (!crp) 3101nfs4_has_reclaimed_state(const char *name)
3019 return NULL; 3102{
3020 crp->cr_name.data = kmalloc(namelen, GFP_KERNEL); 3103 unsigned int strhashval = clientstr_hashval(name);
3021 if (!crp->cr_name.data) { 3104 struct nfs4_client *clp;
3022 kfree(crp); 3105
3023 return NULL; 3106 clp = find_confirmed_client_by_str(name, strhashval);
3024 } 3107 return clp ? 1 : 0;
3025 return crp;
3026} 3108}
3027 3109
3028/* 3110/*
3029 * failure => all reset bets are off, nfserr_no_grace... 3111 * failure => all reset bets are off, nfserr_no_grace...
3030 */ 3112 */
3031static int 3113int
3032nfs4_client_to_reclaim(char *name, int namlen) 3114nfs4_client_to_reclaim(const char *name)
3033{ 3115{
3034 unsigned int strhashval; 3116 unsigned int strhashval;
3035 struct nfs4_client_reclaim *crp = NULL; 3117 struct nfs4_client_reclaim *crp = NULL;
3036 3118
3037 dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", namlen, name); 3119 dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name);
3038 crp = alloc_reclaim(namlen); 3120 crp = alloc_reclaim();
3039 if (!crp) 3121 if (!crp)
3040 return 0; 3122 return 0;
3041 strhashval = clientstr_hashval(name, namlen); 3123 strhashval = clientstr_hashval(name);
3042 INIT_LIST_HEAD(&crp->cr_strhash); 3124 INIT_LIST_HEAD(&crp->cr_strhash);
3043 list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]); 3125 list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]);
3044 memcpy(crp->cr_name.data, name, namlen); 3126 memcpy(crp->cr_recdir, name, HEXDIR_LEN);
3045 crp->cr_name.len = namlen;
3046 reclaim_str_hashtbl_size++; 3127 reclaim_str_hashtbl_size++;
3047 return 1; 3128 return 1;
3048} 3129}
@@ -3053,13 +3134,11 @@ nfs4_release_reclaim(void)
3053 struct nfs4_client_reclaim *crp = NULL; 3134 struct nfs4_client_reclaim *crp = NULL;
3054 int i; 3135 int i;
3055 3136
3056 BUG_ON(!nfs4_reclaim_init);
3057 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 3137 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
3058 while (!list_empty(&reclaim_str_hashtbl[i])) { 3138 while (!list_empty(&reclaim_str_hashtbl[i])) {
3059 crp = list_entry(reclaim_str_hashtbl[i].next, 3139 crp = list_entry(reclaim_str_hashtbl[i].next,
3060 struct nfs4_client_reclaim, cr_strhash); 3140 struct nfs4_client_reclaim, cr_strhash);
3061 list_del(&crp->cr_strhash); 3141 list_del(&crp->cr_strhash);
3062 kfree(crp->cr_name.data);
3063 kfree(crp); 3142 kfree(crp);
3064 reclaim_str_hashtbl_size--; 3143 reclaim_str_hashtbl_size--;
3065 } 3144 }
@@ -3069,7 +3148,7 @@ nfs4_release_reclaim(void)
3069 3148
3070/* 3149/*
3071 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */ 3150 * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
3072struct nfs4_client_reclaim * 3151static struct nfs4_client_reclaim *
3073nfs4_find_reclaim_client(clientid_t *clid) 3152nfs4_find_reclaim_client(clientid_t *clid)
3074{ 3153{
3075 unsigned int strhashval; 3154 unsigned int strhashval;
@@ -3082,13 +3161,14 @@ nfs4_find_reclaim_client(clientid_t *clid)
3082 if (clp == NULL) 3161 if (clp == NULL)
3083 return NULL; 3162 return NULL;
3084 3163
3085 dprintk("NFSD: nfs4_find_reclaim_client for %.*s\n", 3164 dprintk("NFSD: nfs4_find_reclaim_client for %.*s with recdir %s\n",
3086 clp->cl_name.len, clp->cl_name.data); 3165 clp->cl_name.len, clp->cl_name.data,
3166 clp->cl_recdir);
3087 3167
3088 /* find clp->cl_name in reclaim_str_hashtbl */ 3168 /* find clp->cl_name in reclaim_str_hashtbl */
3089 strhashval = clientstr_hashval(clp->cl_name.data, clp->cl_name.len); 3169 strhashval = clientstr_hashval(clp->cl_recdir);
3090 list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) { 3170 list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) {
3091 if (cmp_name(&crp->cr_name, &clp->cl_name)) { 3171 if (same_name(crp->cr_recdir, clp->cl_recdir)) {
3092 return crp; 3172 return crp;
3093 } 3173 }
3094 } 3174 }
@@ -3101,30 +3181,16 @@ nfs4_find_reclaim_client(clientid_t *clid)
3101int 3181int
3102nfs4_check_open_reclaim(clientid_t *clid) 3182nfs4_check_open_reclaim(clientid_t *clid)
3103{ 3183{
3104 struct nfs4_client_reclaim *crp; 3184 return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad;
3105
3106 if ((crp = nfs4_find_reclaim_client(clid)) == NULL)
3107 return nfserr_reclaim_bad;
3108 return nfs_ok;
3109} 3185}
3110 3186
3187/* initialization to perform at module load time: */
3111 3188
3112/* 3189void
3113 * Start and stop routines 3190nfs4_state_init(void)
3114 */
3115
3116static void
3117__nfs4_state_init(void)
3118{ 3191{
3119 int i; 3192 int i;
3120 time_t grace_time;
3121 3193
3122 if (!nfs4_reclaim_init) {
3123 for (i = 0; i < CLIENT_HASH_SIZE; i++)
3124 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
3125 reclaim_str_hashtbl_size = 0;
3126 nfs4_reclaim_init = 1;
3127 }
3128 for (i = 0; i < CLIENT_HASH_SIZE; i++) { 3194 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
3129 INIT_LIST_HEAD(&conf_id_hashtbl[i]); 3195 INIT_LIST_HEAD(&conf_id_hashtbl[i]);
3130 INIT_LIST_HEAD(&conf_str_hashtbl[i]); 3196 INIT_LIST_HEAD(&conf_str_hashtbl[i]);
@@ -3146,26 +3212,46 @@ __nfs4_state_init(void)
3146 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]); 3212 INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
3147 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]); 3213 INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
3148 } 3214 }
3149 memset(&zerostateid, 0, sizeof(stateid_t));
3150 memset(&onestateid, ~0, sizeof(stateid_t)); 3215 memset(&onestateid, ~0, sizeof(stateid_t));
3151
3152 INIT_LIST_HEAD(&close_lru); 3216 INIT_LIST_HEAD(&close_lru);
3153 INIT_LIST_HEAD(&client_lru); 3217 INIT_LIST_HEAD(&client_lru);
3154 INIT_LIST_HEAD(&del_recall_lru); 3218 INIT_LIST_HEAD(&del_recall_lru);
3155 spin_lock_init(&recall_lock); 3219 for (i = 0; i < CLIENT_HASH_SIZE; i++)
3220 INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
3221 reclaim_str_hashtbl_size = 0;
3222}
3223
3224static void
3225nfsd4_load_reboot_recovery_data(void)
3226{
3227 int status;
3228
3229 nfs4_lock_state();
3230 nfsd4_init_recdir(user_recovery_dirname);
3231 status = nfsd4_recdir_load();
3232 nfs4_unlock_state();
3233 if (status)
3234 printk("NFSD: Failure reading reboot recovery data\n");
3235}
3236
3237/* initialization to perform when the nfsd service is started: */
3238
3239static void
3240__nfs4_state_start(void)
3241{
3242 time_t grace_time;
3243
3156 boot_time = get_seconds(); 3244 boot_time = get_seconds();
3157 grace_time = max(old_lease_time, lease_time); 3245 grace_time = max(user_lease_time, lease_time);
3158 if (reclaim_str_hashtbl_size == 0) 3246 lease_time = user_lease_time;
3159 grace_time = 0; 3247 in_grace = 1;
3160 if (grace_time) 3248 printk("NFSD: starting %ld-second grace period\n", grace_time);
3161 printk("NFSD: starting %ld-second grace period\n", grace_time); 3249 laundry_wq = create_singlethread_workqueue("nfsd4");
3162 grace_end = boot_time + grace_time; 3250 queue_delayed_work(laundry_wq, &laundromat_work, grace_time*HZ);
3163 INIT_WORK(&laundromat_work,laundromat_main, NULL);
3164 schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
3165} 3251}
3166 3252
3167int 3253int
3168nfs4_state_init(void) 3254nfs4_state_start(void)
3169{ 3255{
3170 int status; 3256 int status;
3171 3257
@@ -3174,7 +3260,8 @@ nfs4_state_init(void)
3174 status = nfsd4_init_slabs(); 3260 status = nfsd4_init_slabs();
3175 if (status) 3261 if (status)
3176 return status; 3262 return status;
3177 __nfs4_state_init(); 3263 nfsd4_load_reboot_recovery_data();
3264 __nfs4_state_start();
3178 nfs4_init = 1; 3265 nfs4_init = 1;
3179 return 0; 3266 return 0;
3180} 3267}
@@ -3182,14 +3269,7 @@ nfs4_state_init(void)
3182int 3269int
3183nfs4_in_grace(void) 3270nfs4_in_grace(void)
3184{ 3271{
3185 return get_seconds() < grace_end; 3272 return in_grace;
3186}
3187
3188void
3189set_no_grace(void)
3190{
3191 printk("NFSD: ERROR in reboot recovery. State reclaims will fail.\n");
3192 grace_end = get_seconds();
3193} 3273}
3194 3274
3195time_t 3275time_t
@@ -3236,21 +3316,11 @@ __nfs4_state_shutdown(void)
3236 unhash_delegation(dp); 3316 unhash_delegation(dp);
3237 } 3317 }
3238 3318
3239 release_all_files();
3240 cancel_delayed_work(&laundromat_work); 3319 cancel_delayed_work(&laundromat_work);
3241 flush_scheduled_work(); 3320 flush_workqueue(laundry_wq);
3321 destroy_workqueue(laundry_wq);
3322 nfsd4_shutdown_recdir();
3242 nfs4_init = 0; 3323 nfs4_init = 0;
3243 dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
3244 list_add_perfile, list_del_perfile);
3245 dprintk("NFSD: add_perclient %d del_perclient %d\n",
3246 add_perclient, del_perclient);
3247 dprintk("NFSD: alloc_file %d free_file %d\n",
3248 alloc_file, free_file);
3249 dprintk("NFSD: vfsopen %d vfsclose %d\n",
3250 vfsopen, vfsclose);
3251 dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
3252 alloc_delegation, free_delegation);
3253
3254} 3324}
3255 3325
3256void 3326void
@@ -3263,56 +3333,48 @@ nfs4_state_shutdown(void)
3263 nfs4_unlock_state(); 3333 nfs4_unlock_state();
3264} 3334}
3265 3335
3336static void
3337nfs4_set_recdir(char *recdir)
3338{
3339 nfs4_lock_state();
3340 strcpy(user_recovery_dirname, recdir);
3341 nfs4_unlock_state();
3342}
3343
3344/*
3345 * Change the NFSv4 recovery directory to recdir.
3346 */
3347int
3348nfs4_reset_recoverydir(char *recdir)
3349{
3350 int status;
3351 struct nameidata nd;
3352
3353 status = path_lookup(recdir, LOOKUP_FOLLOW, &nd);
3354 if (status)
3355 return status;
3356 status = -ENOTDIR;
3357 if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
3358 nfs4_set_recdir(recdir);
3359 status = 0;
3360 }
3361 path_release(&nd);
3362 return status;
3363}
3364
3266/* 3365/*
3267 * Called when leasetime is changed. 3366 * Called when leasetime is changed.
3268 * 3367 *
3269 * if nfsd is not started, simply set the global lease. 3368 * The only way the protocol gives us to handle on-the-fly lease changes is to
3270 * 3369 * simulate a reboot. Instead of doing that, we just wait till the next time
3271 * if nfsd(s) are running, lease change requires nfsv4 state to be reset. 3370 * we start to register any changes in lease time. If the administrator
3272 * e.g: boot_time is reset, existing nfs4_client structs are 3371 * really wants to change the lease time *now*, they can go ahead and bring
3273 * used to fill reclaim_str_hashtbl, then all state (except for the 3372 * nfsd down and then back up again after changing the lease time.
3274 * reclaim_str_hashtbl) is re-initialized.
3275 *
3276 * if the old lease time is greater than the new lease time, the grace
3277 * period needs to be set to the old lease time to allow clients to reclaim
3278 * their state. XXX - we may want to set the grace period == lease time
3279 * after an initial grace period == old lease time
3280 *
3281 * if an error occurs in this process, the new lease is set, but the server
3282 * will not honor OPEN or LOCK reclaims, and will return nfserr_no_grace
3283 * which means OPEN/LOCK/READ/WRITE will fail during grace period.
3284 *
3285 * clients will attempt to reset all state with SETCLIENTID/CONFIRM, and
3286 * OPEN and LOCK reclaims.
3287 */ 3373 */
3288void 3374void
3289nfs4_reset_lease(time_t leasetime) 3375nfs4_reset_lease(time_t leasetime)
3290{ 3376{
3291 struct nfs4_client *clp; 3377 lock_kernel();
3292 int i; 3378 user_lease_time = leasetime;
3293 3379 unlock_kernel();
3294 printk("NFSD: New leasetime %ld\n",leasetime);
3295 if (!nfs4_init)
3296 return;
3297 nfs4_lock_state();
3298 old_lease_time = lease_time;
3299 lease_time = leasetime;
3300
3301 nfs4_release_reclaim();
3302
3303 /* populate reclaim_str_hashtbl with current confirmed nfs4_clientid */
3304 for (i = 0; i < CLIENT_HASH_SIZE; i++) {
3305 list_for_each_entry(clp, &conf_id_hashtbl[i], cl_idhash) {
3306 if (!nfs4_client_to_reclaim(clp->cl_name.data,
3307 clp->cl_name.len)) {
3308 nfs4_release_reclaim();
3309 goto init_state;
3310 }
3311 }
3312 }
3313init_state:
3314 __nfs4_state_shutdown();
3315 __nfs4_state_init();
3316 nfs4_unlock_state();
3317} 3380}
3318
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 36a058a112d5..91fb171d2ace 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -136,7 +136,7 @@ xdr_error: \
136 } \ 136 } \
137} while (0) 137} while (0)
138 138
139u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes) 139static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
140{ 140{
141 /* We want more bytes than seem to be available. 141 /* We want more bytes than seem to be available.
142 * Maybe we need a new page, maybe we have just run out 142 * Maybe we need a new page, maybe we have just run out
@@ -190,7 +190,7 @@ defer_free(struct nfsd4_compoundargs *argp,
190 return 0; 190 return 0;
191} 191}
192 192
193char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes) 193static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
194{ 194{
195 void *new = NULL; 195 void *new = NULL;
196 if (p == argp->tmp) { 196 if (p == argp->tmp) {
@@ -1366,7 +1366,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1366 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) { 1366 if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
1367 if ((buflen -= 4) < 0) 1367 if ((buflen -= 4) < 0)
1368 goto out_resource; 1368 goto out_resource;
1369 WRITE32( NFS4_FH_NOEXPIRE_WITH_OPEN | NFS4_FH_VOL_RENAME ); 1369 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
1370 WRITE32(NFS4_FH_VOLATILE_ANY);
1371 else
1372 WRITE32(NFS4_FH_VOLATILE_ANY|NFS4_FH_VOL_RENAME);
1370 } 1373 }
1371 if (bmval0 & FATTR4_WORD0_CHANGE) { 1374 if (bmval0 & FATTR4_WORD0_CHANGE) {
1372 /* 1375 /*
@@ -1969,7 +1972,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open
1969 case NFS4_OPEN_DELEGATE_READ: 1972 case NFS4_OPEN_DELEGATE_READ:
1970 RESERVE_SPACE(20 + sizeof(stateid_t)); 1973 RESERVE_SPACE(20 + sizeof(stateid_t));
1971 WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t)); 1974 WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));
1972 WRITE32(0); 1975 WRITE32(open->op_recall);
1973 1976
1974 /* 1977 /*
1975 * TODO: ACE's in delegations 1978 * TODO: ACE's in delegations
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 161afdcb8f7d..841c562991e8 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -51,6 +51,7 @@ enum {
51 NFSD_Fh, 51 NFSD_Fh,
52 NFSD_Threads, 52 NFSD_Threads,
53 NFSD_Leasetime, 53 NFSD_Leasetime,
54 NFSD_RecoveryDir,
54}; 55};
55 56
56/* 57/*
@@ -66,6 +67,7 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size);
66static ssize_t write_filehandle(struct file *file, char *buf, size_t size); 67static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
67static ssize_t write_threads(struct file *file, char *buf, size_t size); 68static ssize_t write_threads(struct file *file, char *buf, size_t size);
68static ssize_t write_leasetime(struct file *file, char *buf, size_t size); 69static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
70static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
69 71
70static ssize_t (*write_op[])(struct file *, char *, size_t) = { 72static ssize_t (*write_op[])(struct file *, char *, size_t) = {
71 [NFSD_Svc] = write_svc, 73 [NFSD_Svc] = write_svc,
@@ -78,6 +80,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
78 [NFSD_Fh] = write_filehandle, 80 [NFSD_Fh] = write_filehandle,
79 [NFSD_Threads] = write_threads, 81 [NFSD_Threads] = write_threads,
80 [NFSD_Leasetime] = write_leasetime, 82 [NFSD_Leasetime] = write_leasetime,
83 [NFSD_RecoveryDir] = write_recoverydir,
81}; 84};
82 85
83static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) 86static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -349,6 +352,25 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
349 return strlen(buf); 352 return strlen(buf);
350} 353}
351 354
355static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
356{
357 char *mesg = buf;
358 char *recdir;
359 int len, status;
360
361 if (size > PATH_MAX || buf[size-1] != '\n')
362 return -EINVAL;
363 buf[size-1] = 0;
364
365 recdir = mesg;
366 len = qword_get(&mesg, recdir, size);
367 if (len <= 0)
368 return -EINVAL;
369
370 status = nfs4_reset_recoverydir(recdir);
371 return strlen(buf);
372}
373
352/*----------------------------------------------------------------------------*/ 374/*----------------------------------------------------------------------------*/
353/* 375/*
354 * populating the filesystem. 376 * populating the filesystem.
@@ -369,6 +391,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
369 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, 391 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
370#ifdef CONFIG_NFSD_V4 392#ifdef CONFIG_NFSD_V4
371 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, 393 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
394 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
372#endif 395#endif
373 /* last one */ {""} 396 /* last one */ {""}
374 }; 397 };
@@ -397,9 +420,8 @@ static int __init init_nfsd(void)
397 nfsd_cache_init(); /* RPC reply cache */ 420 nfsd_cache_init(); /* RPC reply cache */
398 nfsd_export_init(); /* Exports table */ 421 nfsd_export_init(); /* Exports table */
399 nfsd_lockd_init(); /* lockd->nfsd callbacks */ 422 nfsd_lockd_init(); /* lockd->nfsd callbacks */
400#ifdef CONFIG_NFSD_V4 423 nfs4_state_init(); /* NFSv4 locking state */
401 nfsd_idmap_init(); /* Name to ID mapping */ 424 nfsd_idmap_init(); /* Name to ID mapping */
402#endif /* CONFIG_NFSD_V4 */
403 if (proc_mkdir("fs/nfs", NULL)) { 425 if (proc_mkdir("fs/nfs", NULL)) {
404 struct proc_dir_entry *entry; 426 struct proc_dir_entry *entry;
405 entry = create_proc_entry("fs/nfs/exports", 0, NULL); 427 entry = create_proc_entry("fs/nfs/exports", 0, NULL);
@@ -426,9 +448,7 @@ static void __exit exit_nfsd(void)
426 remove_proc_entry("fs/nfs", NULL); 448 remove_proc_entry("fs/nfs", NULL);
427 nfsd_stat_shutdown(); 449 nfsd_stat_shutdown();
428 nfsd_lockd_shutdown(); 450 nfsd_lockd_shutdown();
429#ifdef CONFIG_NFSD_V4
430 nfsd_idmap_shutdown(); 451 nfsd_idmap_shutdown();
431#endif /* CONFIG_NFSD_V4 */
432 unregister_filesystem(&nfsd_fs_type); 452 unregister_filesystem(&nfsd_fs_type);
433} 453}
434 454
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 904df604e86b..07b9a065e9da 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -95,7 +95,7 @@ nfsd_svc(unsigned short port, int nrservs)
95 error = nfsd_racache_init(2*nrservs); 95 error = nfsd_racache_init(2*nrservs);
96 if (error<0) 96 if (error<0)
97 goto out; 97 goto out;
98 error = nfs4_state_init(); 98 error = nfs4_state_start();
99 if (error<0) 99 if (error<0)
100 goto out; 100 goto out;
101 if (!nfsd_serv) { 101 if (!nfsd_serv) {
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index ae3940dc85cc..de340ffd33c3 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -50,7 +50,6 @@
50#include <linux/posix_acl.h> 50#include <linux/posix_acl.h>
51#ifdef CONFIG_NFSD_V4 51#ifdef CONFIG_NFSD_V4
52#include <linux/posix_acl_xattr.h> 52#include <linux/posix_acl_xattr.h>
53#include <linux/xattr_acl.h>
54#include <linux/xattr.h> 53#include <linux/xattr.h>
55#include <linux/nfs4.h> 54#include <linux/nfs4.h>
56#include <linux/nfs4_acl.h> 55#include <linux/nfs4_acl.h>
@@ -425,13 +424,13 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
425 goto out_nfserr; 424 goto out_nfserr;
426 425
427 if (pacl) { 426 if (pacl) {
428 error = set_nfsv4_acl_one(dentry, pacl, XATTR_NAME_ACL_ACCESS); 427 error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
429 if (error < 0) 428 if (error < 0)
430 goto out_nfserr; 429 goto out_nfserr;
431 } 430 }
432 431
433 if (dpacl) { 432 if (dpacl) {
434 error = set_nfsv4_acl_one(dentry, dpacl, XATTR_NAME_ACL_DEFAULT); 433 error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
435 if (error < 0) 434 if (error < 0)
436 goto out_nfserr; 435 goto out_nfserr;
437 } 436 }
@@ -498,7 +497,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_ac
498 struct posix_acl *pacl = NULL, *dpacl = NULL; 497 struct posix_acl *pacl = NULL, *dpacl = NULL;
499 unsigned int flags = 0; 498 unsigned int flags = 0;
500 499
501 pacl = _get_posix_acl(dentry, XATTR_NAME_ACL_ACCESS); 500 pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS);
502 if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA) 501 if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA)
503 pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); 502 pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
504 if (IS_ERR(pacl)) { 503 if (IS_ERR(pacl)) {
@@ -508,7 +507,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_ac
508 } 507 }
509 508
510 if (S_ISDIR(inode->i_mode)) { 509 if (S_ISDIR(inode->i_mode)) {
511 dpacl = _get_posix_acl(dentry, XATTR_NAME_ACL_DEFAULT); 510 dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT);
512 if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA) 511 if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA)
513 dpacl = NULL; 512 dpacl = NULL;
514 else if (IS_ERR(dpacl)) { 513 else if (IS_ERR(dpacl)) {
diff --git a/fs/open.c b/fs/open.c
index 963bd81a44c8..3f4a4286fdc4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -21,6 +21,7 @@
21#include <linux/vfs.h> 21#include <linux/vfs.h>
22#include <asm/uaccess.h> 22#include <asm/uaccess.h>
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/personality.h>
24#include <linux/pagemap.h> 25#include <linux/pagemap.h>
25#include <linux/syscalls.h> 26#include <linux/syscalls.h>
26 27
@@ -807,7 +808,9 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
807 808
808 /* NB: we're sure to have correct a_ops only after f_op->open */ 809 /* NB: we're sure to have correct a_ops only after f_op->open */
809 if (f->f_flags & O_DIRECT) { 810 if (f->f_flags & O_DIRECT) {
810 if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) { 811 if (!f->f_mapping->a_ops ||
812 ((!f->f_mapping->a_ops->direct_IO) &&
813 (!f->f_mapping->a_ops->get_xip_page))) {
811 fput(f); 814 fput(f);
812 f = ERR_PTR(-EINVAL); 815 f = ERR_PTR(-EINVAL);
813 } 816 }
@@ -933,31 +936,27 @@ EXPORT_SYMBOL(fd_install);
933asmlinkage long sys_open(const char __user * filename, int flags, int mode) 936asmlinkage long sys_open(const char __user * filename, int flags, int mode)
934{ 937{
935 char * tmp; 938 char * tmp;
936 int fd, error; 939 int fd;
940
941 if (force_o_largefile())
942 flags |= O_LARGEFILE;
937 943
938#if BITS_PER_LONG != 32
939 flags |= O_LARGEFILE;
940#endif
941 tmp = getname(filename); 944 tmp = getname(filename);
942 fd = PTR_ERR(tmp); 945 fd = PTR_ERR(tmp);
943 if (!IS_ERR(tmp)) { 946 if (!IS_ERR(tmp)) {
944 fd = get_unused_fd(); 947 fd = get_unused_fd();
945 if (fd >= 0) { 948 if (fd >= 0) {
946 struct file *f = filp_open(tmp, flags, mode); 949 struct file *f = filp_open(tmp, flags, mode);
947 error = PTR_ERR(f); 950 if (IS_ERR(f)) {
948 if (IS_ERR(f)) 951 put_unused_fd(fd);
949 goto out_error; 952 fd = PTR_ERR(f);
950 fd_install(fd, f); 953 } else {
954 fd_install(fd, f);
955 }
951 } 956 }
952out:
953 putname(tmp); 957 putname(tmp);
954 } 958 }
955 return fd; 959 return fd;
956
957out_error:
958 put_unused_fd(fd);
959 fd = error;
960 goto out;
961} 960}
962EXPORT_SYMBOL_GPL(sys_open); 961EXPORT_SYMBOL_GPL(sys_open);
963 962
@@ -980,23 +979,15 @@ asmlinkage long sys_creat(const char __user * pathname, int mode)
980 */ 979 */
981int filp_close(struct file *filp, fl_owner_t id) 980int filp_close(struct file *filp, fl_owner_t id)
982{ 981{
983 int retval; 982 int retval = 0;
984
985 /* Report and clear outstanding errors */
986 retval = filp->f_error;
987 if (retval)
988 filp->f_error = 0;
989 983
990 if (!file_count(filp)) { 984 if (!file_count(filp)) {
991 printk(KERN_ERR "VFS: Close: file count is 0\n"); 985 printk(KERN_ERR "VFS: Close: file count is 0\n");
992 return retval; 986 return 0;
993 } 987 }
994 988
995 if (filp->f_op && filp->f_op->flush) { 989 if (filp->f_op && filp->f_op->flush)
996 int err = filp->f_op->flush(filp); 990 retval = filp->f_op->flush(filp);
997 if (!retval)
998 retval = err;
999 }
1000 991
1001 dnotify_flush(filp, id); 992 dnotify_flush(filp, id);
1002 locks_remove_posix(filp, id); 993 locks_remove_posix(filp, id);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index e31903aadd96..ace151fa4878 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -314,7 +314,7 @@ static int may_ptrace_attach(struct task_struct *task)
314 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) 314 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
315 goto out; 315 goto out;
316 rmb(); 316 rmb();
317 if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE)) 317 if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE))
318 goto out; 318 goto out;
319 if (security_ptrace(current, task)) 319 if (security_ptrace(current, task))
320 goto out; 320 goto out;
@@ -1113,7 +1113,9 @@ static int task_dumpable(struct task_struct *task)
1113 if (mm) 1113 if (mm)
1114 dumpable = mm->dumpable; 1114 dumpable = mm->dumpable;
1115 task_unlock(task); 1115 task_unlock(task);
1116 return dumpable; 1116 if(dumpable == 1)
1117 return 1;
1118 return 0;
1117} 1119}
1118 1120
1119 1121
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 63a9fbf1ac51..94b570ad037d 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -451,7 +451,7 @@ static int devices_read_proc(char *page, char **start, off_t off,
451 int count, int *eof, void *data) 451 int count, int *eof, void *data)
452{ 452{
453 int len = get_chrdev_list(page); 453 int len = get_chrdev_list(page);
454 len += get_blkdev_list(page+len); 454 len += get_blkdev_list(page+len, len);
455 return proc_calc_metrics(page, start, off, count, eof, len); 455 return proc_calc_metrics(page, start, off, count, eof, len);
456} 456}
457 457
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c
index cd66147cca04..7a8f5595c26f 100644
--- a/fs/qnx4/dir.c
+++ b/fs/qnx4/dir.c
@@ -61,7 +61,7 @@ static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir)
61 ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1; 61 ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1;
62 else { 62 else {
63 le = (struct qnx4_link_info*)de; 63 le = (struct qnx4_link_info*)de;
64 ino = ( le->dl_inode_blk - 1 ) * 64 ino = ( le32_to_cpu(le->dl_inode_blk) - 1 ) *
65 QNX4_INODES_PER_BLOCK + 65 QNX4_INODES_PER_BLOCK +
66 le->dl_inode_ndx; 66 le->dl_inode_ndx;
67 } 67 }
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index aa92d6b76a9a..b79162a35478 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -236,7 +236,7 @@ unsigned long qnx4_block_map( struct inode *inode, long iblock )
236 struct buffer_head *bh = NULL; 236 struct buffer_head *bh = NULL;
237 struct qnx4_xblk *xblk = NULL; 237 struct qnx4_xblk *xblk = NULL;
238 struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode); 238 struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
239 qnx4_nxtnt_t nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts); 239 u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);
240 240
241 if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) { 241 if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) {
242 // iblock is in the first extent. This is easy. 242 // iblock is in the first extent. This is easy.
@@ -372,7 +372,7 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
372 printk("qnx4: unable to read the superblock\n"); 372 printk("qnx4: unable to read the superblock\n");
373 goto outnobh; 373 goto outnobh;
374 } 374 }
375 if ( le32_to_cpu( *(__u32*)bh->b_data ) != QNX4_SUPER_MAGIC ) { 375 if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) {
376 if (!silent) 376 if (!silent)
377 printk("qnx4: wrong fsid in superblock.\n"); 377 printk("qnx4: wrong fsid in superblock.\n");
378 goto out; 378 goto out;
diff --git a/fs/quota.c b/fs/quota.c
index 3f0333a51a23..f5d1cff55196 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -149,36 +149,6 @@ static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t
149 return error; 149 return error;
150} 150}
151 151
152static struct super_block *get_super_to_sync(int type)
153{
154 struct list_head *head;
155 int cnt, dirty;
156
157restart:
158 spin_lock(&sb_lock);
159 list_for_each(head, &super_blocks) {
160 struct super_block *sb = list_entry(head, struct super_block, s_list);
161
162 /* This test just improves performance so it needn't be reliable... */
163 for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
164 if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
165 && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
166 dirty = 1;
167 if (!dirty)
168 continue;
169 sb->s_count++;
170 spin_unlock(&sb_lock);
171 down_read(&sb->s_umount);
172 if (!sb->s_root) {
173 drop_super(sb);
174 goto restart;
175 }
176 return sb;
177 }
178 spin_unlock(&sb_lock);
179 return NULL;
180}
181
182static void quota_sync_sb(struct super_block *sb, int type) 152static void quota_sync_sb(struct super_block *sb, int type)
183{ 153{
184 int cnt; 154 int cnt;
@@ -219,17 +189,35 @@ static void quota_sync_sb(struct super_block *sb, int type)
219 189
220void sync_dquots(struct super_block *sb, int type) 190void sync_dquots(struct super_block *sb, int type)
221{ 191{
192 int cnt, dirty;
193
222 if (sb) { 194 if (sb) {
223 if (sb->s_qcop->quota_sync) 195 if (sb->s_qcop->quota_sync)
224 quota_sync_sb(sb, type); 196 quota_sync_sb(sb, type);
197 return;
225 } 198 }
226 else { 199
227 while ((sb = get_super_to_sync(type)) != NULL) { 200 spin_lock(&sb_lock);
228 if (sb->s_qcop->quota_sync) 201restart:
229 quota_sync_sb(sb, type); 202 list_for_each_entry(sb, &super_blocks, s_list) {
230 drop_super(sb); 203 /* This test just improves performance so it needn't be reliable... */
231 } 204 for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
205 if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
206 && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
207 dirty = 1;
208 if (!dirty)
209 continue;
210 sb->s_count++;
211 spin_unlock(&sb_lock);
212 down_read(&sb->s_umount);
213 if (sb->s_root && sb->s_qcop->quota_sync)
214 quota_sync_sb(sb, type);
215 up_read(&sb->s_umount);
216 spin_lock(&sb_lock);
217 if (__put_super_and_need_restart(sb))
218 goto restart;
232 } 219 }
220 spin_unlock(&sb_lock);
233} 221}
234 222
235/* Copy parameters and call proper function */ 223/* Copy parameters and call proper function */
diff --git a/fs/read_write.c b/fs/read_write.c
index c4c2bee373ed..9292f5fa4d62 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -203,6 +203,16 @@ Einval:
203 return -EINVAL; 203 return -EINVAL;
204} 204}
205 205
206static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
207{
208 set_current_state(TASK_UNINTERRUPTIBLE);
209 if (!kiocbIsKicked(iocb))
210 schedule();
211 else
212 kiocbClearKicked(iocb);
213 __set_current_state(TASK_RUNNING);
214}
215
206ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) 216ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
207{ 217{
208 struct kiocb kiocb; 218 struct kiocb kiocb;
@@ -210,7 +220,10 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
210 220
211 init_sync_kiocb(&kiocb, filp); 221 init_sync_kiocb(&kiocb, filp);
212 kiocb.ki_pos = *ppos; 222 kiocb.ki_pos = *ppos;
213 ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos); 223 while (-EIOCBRETRY ==
224 (ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos)))
225 wait_on_retry_sync_kiocb(&kiocb);
226
214 if (-EIOCBQUEUED == ret) 227 if (-EIOCBQUEUED == ret)
215 ret = wait_on_sync_kiocb(&kiocb); 228 ret = wait_on_sync_kiocb(&kiocb);
216 *ppos = kiocb.ki_pos; 229 *ppos = kiocb.ki_pos;
@@ -258,7 +271,10 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
258 271
259 init_sync_kiocb(&kiocb, filp); 272 init_sync_kiocb(&kiocb, filp);
260 kiocb.ki_pos = *ppos; 273 kiocb.ki_pos = *ppos;
261 ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos); 274 while (-EIOCBRETRY ==
275 (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos)))
276 wait_on_retry_sync_kiocb(&kiocb);
277
262 if (-EIOCBQUEUED == ret) 278 if (-EIOCBQUEUED == ret)
263 ret = wait_on_sync_kiocb(&kiocb); 279 ret = wait_on_sync_kiocb(&kiocb);
264 *ppos = kiocb.ki_pos; 280 *ppos = kiocb.ki_pos;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 2230afff1870..12e91209544e 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -201,7 +201,7 @@ static int reiserfs_allocate_blocks_for_region(
201 /* If we came here, it means we absolutely need to open a transaction, 201 /* If we came here, it means we absolutely need to open a transaction,
202 since we need to allocate some blocks */ 202 since we need to allocate some blocks */
203 reiserfs_write_lock(inode->i_sb); // Journaling stuff and we need that. 203 reiserfs_write_lock(inode->i_sb); // Journaling stuff and we need that.
204 res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS); // Wish I know if this number enough 204 res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb)); // Wish I know if this number enough
205 if (res) 205 if (res)
206 goto error_exit; 206 goto error_exit;
207 reiserfs_update_inode_transaction(inode) ; 207 reiserfs_update_inode_transaction(inode) ;
@@ -576,7 +576,7 @@ error_exit:
576 int err; 576 int err;
577 // update any changes we made to blk count 577 // update any changes we made to blk count
578 reiserfs_update_sd(th, inode); 578 reiserfs_update_sd(th, inode);
579 err = journal_end(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS); 579 err = journal_end(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb));
580 if (err) 580 if (err)
581 res = err; 581 res = err;
582 } 582 }
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 2711dff1b7b4..0d5817f81972 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -28,7 +28,7 @@ static int reiserfs_prepare_write(struct file *f, struct page *page,
28void reiserfs_delete_inode (struct inode * inode) 28void reiserfs_delete_inode (struct inode * inode)
29{ 29{
30 /* We need blocks for transaction + (user+group) quota update (possibly delete) */ 30 /* We need blocks for transaction + (user+group) quota update (possibly delete) */
31 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS; 31 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
32 struct reiserfs_transaction_handle th ; 32 struct reiserfs_transaction_handle th ;
33 33
34 reiserfs_write_lock(inode->i_sb); 34 reiserfs_write_lock(inode->i_sb);
@@ -591,7 +591,7 @@ int reiserfs_get_block (struct inode * inode, sector_t block,
591 XXX in practically impossible worst case direct2indirect() 591 XXX in practically impossible worst case direct2indirect()
592 can incur (much) more than 3 balancings. 592 can incur (much) more than 3 balancings.
593 quota update for user, group */ 593 quota update for user, group */
594 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS; 594 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb);
595 int version; 595 int version;
596 int dangle = 1; 596 int dangle = 1;
597 loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ; 597 loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ;
@@ -2796,12 +2796,15 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
2796 2796
2797 if (!error) { 2797 if (!error) {
2798 struct reiserfs_transaction_handle th; 2798 struct reiserfs_transaction_handle th;
2799 int jbegin_count = 2*(REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)+REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb))+2;
2799 2800
2800 /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */ 2801 /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
2801 journal_begin(&th, inode->i_sb, 4*REISERFS_QUOTA_INIT_BLOCKS+2); 2802 error = journal_begin(&th, inode->i_sb, jbegin_count);
2803 if (error)
2804 goto out;
2802 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; 2805 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
2803 if (error) { 2806 if (error) {
2804 journal_end(&th, inode->i_sb, 4*REISERFS_QUOTA_INIT_BLOCKS+2); 2807 journal_end(&th, inode->i_sb, jbegin_count);
2805 goto out; 2808 goto out;
2806 } 2809 }
2807 /* Update corresponding info in inode so that everything is in 2810 /* Update corresponding info in inode so that everything is in
@@ -2811,7 +2814,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
2811 if (attr->ia_valid & ATTR_GID) 2814 if (attr->ia_valid & ATTR_GID)
2812 inode->i_gid = attr->ia_gid; 2815 inode->i_gid = attr->ia_gid;
2813 mark_inode_dirty(inode); 2816 mark_inode_dirty(inode);
2814 journal_end(&th, inode->i_sb, 4*REISERFS_QUOTA_INIT_BLOCKS+2); 2817 error = journal_end(&th, inode->i_sb, jbegin_count);
2815 } 2818 }
2816 } 2819 }
2817 if (!error) 2820 if (!error)
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 3072cfdee959..7b87707acc36 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2631,6 +2631,8 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th, struct sup
2631 int retval; 2631 int retval;
2632 2632
2633 reiserfs_check_lock_depth(p_s_sb, "journal_begin") ; 2633 reiserfs_check_lock_depth(p_s_sb, "journal_begin") ;
2634 if (nblocks > journal->j_trans_max)
2635 BUG();
2634 2636
2635 PROC_INFO_INC( p_s_sb, journal.journal_being ); 2637 PROC_INFO_INC( p_s_sb, journal.journal_being );
2636 /* set here for journal_join */ 2638 /* set here for journal_join */
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 7d4dc5f5aa8b..4a333255f27a 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -586,7 +586,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode,
586 int retval; 586 int retval;
587 struct inode * inode; 587 struct inode * inode;
588 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ 588 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
589 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); 589 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
590 struct reiserfs_transaction_handle th ; 590 struct reiserfs_transaction_handle th ;
591 int locked; 591 int locked;
592 592
@@ -653,7 +653,7 @@ static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode,
653 struct inode * inode; 653 struct inode * inode;
654 struct reiserfs_transaction_handle th ; 654 struct reiserfs_transaction_handle th ;
655 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ 655 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
656 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); 656 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
657 int locked; 657 int locked;
658 658
659 if (!new_valid_dev(rdev)) 659 if (!new_valid_dev(rdev))
@@ -727,7 +727,7 @@ static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
727 struct inode * inode; 727 struct inode * inode;
728 struct reiserfs_transaction_handle th ; 728 struct reiserfs_transaction_handle th ;
729 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ 729 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
730 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); 730 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
731 int locked; 731 int locked;
732 732
733#ifdef DISPLACE_NEW_PACKING_LOCALITIES 733#ifdef DISPLACE_NEW_PACKING_LOCALITIES
@@ -829,8 +829,10 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
829 829
830 830
831 /* we will be doing 2 balancings and update 2 stat data, we change quotas 831 /* we will be doing 2 balancings and update 2 stat data, we change quotas
832 * of the owner of the directory and of the owner of the parent directory */ 832 * of the owner of the directory and of the owner of the parent directory.
833 jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); 833 * The quota structure is possibly deleted only on last iput => outside
834 * of this transaction */
835 jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
834 836
835 reiserfs_write_lock(dir->i_sb); 837 reiserfs_write_lock(dir->i_sb);
836 retval = journal_begin(&th, dir->i_sb, jbegin_count) ; 838 retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
@@ -913,9 +915,10 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
913 inode = dentry->d_inode; 915 inode = dentry->d_inode;
914 916
915 /* in this transaction we can be doing at max two balancings and update 917 /* in this transaction we can be doing at max two balancings and update
916 two stat datas, we change quotas of the owner of the directory and of 918 * two stat datas, we change quotas of the owner of the directory and of
917 the owner of the parent directory */ 919 * the owner of the parent directory. The quota structure is possibly
918 jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); 920 * deleted only on iput => outside of this transaction */
921 jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
919 922
920 reiserfs_write_lock(dir->i_sb); 923 reiserfs_write_lock(dir->i_sb);
921 retval = journal_begin(&th, dir->i_sb, jbegin_count) ; 924 retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
@@ -1000,7 +1003,7 @@ static int reiserfs_symlink (struct inode * parent_dir,
1000 struct reiserfs_transaction_handle th ; 1003 struct reiserfs_transaction_handle th ;
1001 int mode = S_IFLNK | S_IRWXUGO; 1004 int mode = S_IFLNK | S_IRWXUGO;
1002 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ 1005 /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
1003 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS); 1006 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb)+REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb));
1004 1007
1005 if (!(inode = new_inode(parent_dir->i_sb))) { 1008 if (!(inode = new_inode(parent_dir->i_sb))) {
1006 return -ENOMEM ; 1009 return -ENOMEM ;
@@ -1076,7 +1079,7 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
1076 struct inode *inode = old_dentry->d_inode; 1079 struct inode *inode = old_dentry->d_inode;
1077 struct reiserfs_transaction_handle th ; 1080 struct reiserfs_transaction_handle th ;
1078 /* We need blocks for transaction + update of quotas for the owners of the directory */ 1081 /* We need blocks for transaction + update of quotas for the owners of the directory */
1079 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * REISERFS_QUOTA_TRANS_BLOCKS; 1082 int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
1080 1083
1081 reiserfs_write_lock(dir->i_sb); 1084 reiserfs_write_lock(dir->i_sb);
1082 if (inode->i_nlink >= REISERFS_LINK_MAX) { 1085 if (inode->i_nlink >= REISERFS_LINK_MAX) {
@@ -1196,7 +1199,7 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
1196 pointed initially and (5) maybe block containing ".." of 1199 pointed initially and (5) maybe block containing ".." of
1197 renamed directory 1200 renamed directory
1198 quota updates: two parent directories */ 1201 quota updates: two parent directories */
1199 jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 5 + 4 * REISERFS_QUOTA_TRANS_BLOCKS; 1202 jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 5 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb);
1200 1203
1201 old_inode = old_dentry->d_inode; 1204 old_inode = old_dentry->d_inode;
1202 new_dentry_inode = new_dentry->d_inode; 1205 new_dentry_inode = new_dentry->d_inode;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index c47f8fd31a2d..63158491e152 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -223,7 +223,7 @@ extern struct tree_balance * cur_tb;
223const struct reiserfs_key MIN_KEY = {0, 0, {{0, 0},}}; 223const struct reiserfs_key MIN_KEY = {0, 0, {{0, 0},}};
224 224
225/* Maximal possible key. It is never in the tree. */ 225/* Maximal possible key. It is never in the tree. */
226const struct reiserfs_key MAX_KEY = { 226static const struct reiserfs_key MAX_KEY = {
227 __constant_cpu_to_le32(0xffffffff), 227 __constant_cpu_to_le32(0xffffffff),
228 __constant_cpu_to_le32(0xffffffff), 228 __constant_cpu_to_le32(0xffffffff),
229 {{__constant_cpu_to_le32(0xffffffff), 229 {{__constant_cpu_to_le32(0xffffffff),
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index b35b87744983..660aefca1fd2 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -866,8 +866,9 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st
866 {"jdev", .arg_required = 'j', .values = NULL}, 866 {"jdev", .arg_required = 'j', .values = NULL},
867 {"nolargeio", .arg_required = 'w', .values = NULL}, 867 {"nolargeio", .arg_required = 'w', .values = NULL},
868 {"commit", .arg_required = 'c', .values = NULL}, 868 {"commit", .arg_required = 'c', .values = NULL},
869 {"usrquota",}, 869 {"usrquota", .setmask = 1<<REISERFS_QUOTA},
870 {"grpquota",}, 870 {"grpquota", .setmask = 1<<REISERFS_QUOTA},
871 {"noquota", .clrmask = 1<<REISERFS_QUOTA},
871 {"errors", .arg_required = 'e', .values = error_actions}, 872 {"errors", .arg_required = 'e', .values = error_actions},
872 {"usrjquota", .arg_required = 'u'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL}, 873 {"usrjquota", .arg_required = 'u'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL},
873 {"grpjquota", .arg_required = 'g'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL}, 874 {"grpjquota", .arg_required = 'g'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL},
@@ -964,6 +965,7 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st
964 return 0; 965 return 0;
965 } 966 }
966 strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg); 967 strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
968 *mount_options |= 1<<REISERFS_QUOTA;
967 } 969 }
968 else { 970 else {
969 if (REISERFS_SB(s)->s_qf_names[qtype]) { 971 if (REISERFS_SB(s)->s_qf_names[qtype]) {
@@ -995,7 +997,13 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st
995 reiserfs_warning(s, "reiserfs_parse_options: journalled quota format not specified."); 997 reiserfs_warning(s, "reiserfs_parse_options: journalled quota format not specified.");
996 return 0; 998 return 0;
997 } 999 }
1000 /* This checking is not precise wrt the quota type but for our purposes it is sufficient */
1001 if (!(*mount_options & (1<<REISERFS_QUOTA)) && sb_any_quota_enabled(s)) {
1002 reiserfs_warning(s, "reiserfs_parse_options: quota options must be present when quota is turned on.");
1003 return 0;
1004 }
998#endif 1005#endif
1006
999 return 1; 1007 return 1;
1000} 1008}
1001 1009
@@ -1105,6 +1113,7 @@ static int reiserfs_remount (struct super_block * s, int * mount_flags, char * a
1105 safe_mask |= 1 << REISERFS_ERROR_RO; 1113 safe_mask |= 1 << REISERFS_ERROR_RO;
1106 safe_mask |= 1 << REISERFS_ERROR_CONTINUE; 1114 safe_mask |= 1 << REISERFS_ERROR_CONTINUE;
1107 safe_mask |= 1 << REISERFS_ERROR_PANIC; 1115 safe_mask |= 1 << REISERFS_ERROR_PANIC;
1116 safe_mask |= 1 << REISERFS_QUOTA;
1108 1117
1109 /* Update the bitmask, taking care to keep 1118 /* Update the bitmask, taking care to keep
1110 * the bits we're not allowed to change here */ 1119 * the bits we're not allowed to change here */
@@ -1841,13 +1850,18 @@ static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf)
1841static int reiserfs_dquot_initialize(struct inode *inode, int type) 1850static int reiserfs_dquot_initialize(struct inode *inode, int type)
1842{ 1851{
1843 struct reiserfs_transaction_handle th; 1852 struct reiserfs_transaction_handle th;
1844 int ret; 1853 int ret, err;
1845 1854
1846 /* We may create quota structure so we need to reserve enough blocks */ 1855 /* We may create quota structure so we need to reserve enough blocks */
1847 reiserfs_write_lock(inode->i_sb); 1856 reiserfs_write_lock(inode->i_sb);
1848 journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); 1857 ret = journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
1858 if (ret)
1859 goto out;
1849 ret = dquot_initialize(inode, type); 1860 ret = dquot_initialize(inode, type);
1850 journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); 1861 err = journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
1862 if (!ret && err)
1863 ret = err;
1864out:
1851 reiserfs_write_unlock(inode->i_sb); 1865 reiserfs_write_unlock(inode->i_sb);
1852 return ret; 1866 return ret;
1853} 1867}
@@ -1855,13 +1869,18 @@ static int reiserfs_dquot_initialize(struct inode *inode, int type)
1855static int reiserfs_dquot_drop(struct inode *inode) 1869static int reiserfs_dquot_drop(struct inode *inode)
1856{ 1870{
1857 struct reiserfs_transaction_handle th; 1871 struct reiserfs_transaction_handle th;
1858 int ret; 1872 int ret, err;
1859 1873
1860 /* We may delete quota structure so we need to reserve enough blocks */ 1874 /* We may delete quota structure so we need to reserve enough blocks */
1861 reiserfs_write_lock(inode->i_sb); 1875 reiserfs_write_lock(inode->i_sb);
1862 journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); 1876 ret = journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
1877 if (ret)
1878 goto out;
1863 ret = dquot_drop(inode); 1879 ret = dquot_drop(inode);
1864 journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS); 1880 err = journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
1881 if (!ret && err)
1882 ret = err;
1883out:
1865 reiserfs_write_unlock(inode->i_sb); 1884 reiserfs_write_unlock(inode->i_sb);
1866 return ret; 1885 return ret;
1867} 1886}
@@ -1869,12 +1888,17 @@ static int reiserfs_dquot_drop(struct inode *inode)
1869static int reiserfs_write_dquot(struct dquot *dquot) 1888static int reiserfs_write_dquot(struct dquot *dquot)
1870{ 1889{
1871 struct reiserfs_transaction_handle th; 1890 struct reiserfs_transaction_handle th;
1872 int ret; 1891 int ret, err;
1873 1892
1874 reiserfs_write_lock(dquot->dq_sb); 1893 reiserfs_write_lock(dquot->dq_sb);
1875 journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS); 1894 ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
1895 if (ret)
1896 goto out;
1876 ret = dquot_commit(dquot); 1897 ret = dquot_commit(dquot);
1877 journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS); 1898 err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
1899 if (!ret && err)
1900 ret = err;
1901out:
1878 reiserfs_write_unlock(dquot->dq_sb); 1902 reiserfs_write_unlock(dquot->dq_sb);
1879 return ret; 1903 return ret;
1880} 1904}
@@ -1882,12 +1906,17 @@ static int reiserfs_write_dquot(struct dquot *dquot)
1882static int reiserfs_acquire_dquot(struct dquot *dquot) 1906static int reiserfs_acquire_dquot(struct dquot *dquot)
1883{ 1907{
1884 struct reiserfs_transaction_handle th; 1908 struct reiserfs_transaction_handle th;
1885 int ret; 1909 int ret, err;
1886 1910
1887 reiserfs_write_lock(dquot->dq_sb); 1911 reiserfs_write_lock(dquot->dq_sb);
1888 journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); 1912 ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
1913 if (ret)
1914 goto out;
1889 ret = dquot_acquire(dquot); 1915 ret = dquot_acquire(dquot);
1890 journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); 1916 err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
1917 if (!ret && err)
1918 ret = err;
1919out:
1891 reiserfs_write_unlock(dquot->dq_sb); 1920 reiserfs_write_unlock(dquot->dq_sb);
1892 return ret; 1921 return ret;
1893} 1922}
@@ -1895,12 +1924,17 @@ static int reiserfs_acquire_dquot(struct dquot *dquot)
1895static int reiserfs_release_dquot(struct dquot *dquot) 1924static int reiserfs_release_dquot(struct dquot *dquot)
1896{ 1925{
1897 struct reiserfs_transaction_handle th; 1926 struct reiserfs_transaction_handle th;
1898 int ret; 1927 int ret, err;
1899 1928
1900 reiserfs_write_lock(dquot->dq_sb); 1929 reiserfs_write_lock(dquot->dq_sb);
1901 journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); 1930 ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
1931 if (ret)
1932 goto out;
1902 ret = dquot_release(dquot); 1933 ret = dquot_release(dquot);
1903 journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS); 1934 err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
1935 if (!ret && err)
1936 ret = err;
1937out:
1904 reiserfs_write_unlock(dquot->dq_sb); 1938 reiserfs_write_unlock(dquot->dq_sb);
1905 return ret; 1939 return ret;
1906} 1940}
@@ -1920,39 +1954,29 @@ static int reiserfs_mark_dquot_dirty(struct dquot *dquot)
1920static int reiserfs_write_info(struct super_block *sb, int type) 1954static int reiserfs_write_info(struct super_block *sb, int type)
1921{ 1955{
1922 struct reiserfs_transaction_handle th; 1956 struct reiserfs_transaction_handle th;
1923 int ret; 1957 int ret, err;
1924 1958
1925 /* Data block + inode block */ 1959 /* Data block + inode block */
1926 reiserfs_write_lock(sb); 1960 reiserfs_write_lock(sb);
1927 journal_begin(&th, sb, 2); 1961 ret = journal_begin(&th, sb, 2);
1962 if (ret)
1963 goto out;
1928 ret = dquot_commit_info(sb, type); 1964 ret = dquot_commit_info(sb, type);
1929 journal_end(&th, sb, 2); 1965 err = journal_end(&th, sb, 2);
1966 if (!ret && err)
1967 ret = err;
1968out:
1930 reiserfs_write_unlock(sb); 1969 reiserfs_write_unlock(sb);
1931 return ret; 1970 return ret;
1932} 1971}
1933 1972
1934/* 1973/*
1935 * Turn on quotas during mount time - we need to find 1974 * Turn on quotas during mount time - we need to find the quota file and such...
1936 * the quota file and such...
1937 */ 1975 */
1938static int reiserfs_quota_on_mount(struct super_block *sb, int type) 1976static int reiserfs_quota_on_mount(struct super_block *sb, int type)
1939{ 1977{
1940 int err; 1978 return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
1941 struct dentry *dentry; 1979 REISERFS_SB(sb)->s_jquota_fmt, type);
1942 struct qstr name = { .name = REISERFS_SB(sb)->s_qf_names[type],
1943 .hash = 0,
1944 .len = strlen(REISERFS_SB(sb)->s_qf_names[type])};
1945
1946 dentry = lookup_hash(&name, sb->s_root);
1947 if (IS_ERR(dentry))
1948 return PTR_ERR(dentry);
1949 err = vfs_quota_on_mount(type, REISERFS_SB(sb)->s_jquota_fmt, dentry);
1950 /* Now invalidate and put the dentry - quota got its own reference
1951 * to inode and dentry has at least wrong hash so we had better
1952 * throw it away */
1953 d_invalidate(dentry);
1954 dput(dentry);
1955 return err;
1956} 1980}
1957 1981
1958/* 1982/*
@@ -1963,6 +1987,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, ch
1963 int err; 1987 int err;
1964 struct nameidata nd; 1988 struct nameidata nd;
1965 1989
1990 if (!(REISERFS_SB(sb)->s_mount_opt & (1<<REISERFS_QUOTA)))
1991 return -EINVAL;
1966 err = path_lookup(path, LOOKUP_FOLLOW, &nd); 1992 err = path_lookup(path, LOOKUP_FOLLOW, &nd);
1967 if (err) 1993 if (err)
1968 return err; 1994 return err;
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index e302071903a1..c312881c5f53 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -4,7 +4,7 @@
4#include <linux/errno.h> 4#include <linux/errno.h>
5#include <linux/pagemap.h> 5#include <linux/pagemap.h>
6#include <linux/xattr.h> 6#include <linux/xattr.h>
7#include <linux/xattr_acl.h> 7#include <linux/posix_acl_xattr.h>
8#include <linux/reiserfs_xattr.h> 8#include <linux/reiserfs_xattr.h>
9#include <linux/reiserfs_acl.h> 9#include <linux/reiserfs_acl.h>
10#include <asm/uaccess.h> 10#include <asm/uaccess.h>
@@ -192,11 +192,11 @@ reiserfs_get_acl(struct inode *inode, int type)
192 192
193 switch (type) { 193 switch (type) {
194 case ACL_TYPE_ACCESS: 194 case ACL_TYPE_ACCESS:
195 name = XATTR_NAME_ACL_ACCESS; 195 name = POSIX_ACL_XATTR_ACCESS;
196 p_acl = &reiserfs_i->i_acl_access; 196 p_acl = &reiserfs_i->i_acl_access;
197 break; 197 break;
198 case ACL_TYPE_DEFAULT: 198 case ACL_TYPE_DEFAULT:
199 name = XATTR_NAME_ACL_DEFAULT; 199 name = POSIX_ACL_XATTR_DEFAULT;
200 p_acl = &reiserfs_i->i_acl_default; 200 p_acl = &reiserfs_i->i_acl_default;
201 break; 201 break;
202 default: 202 default:
@@ -260,7 +260,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
260 260
261 switch (type) { 261 switch (type) {
262 case ACL_TYPE_ACCESS: 262 case ACL_TYPE_ACCESS:
263 name = XATTR_NAME_ACL_ACCESS; 263 name = POSIX_ACL_XATTR_ACCESS;
264 p_acl = &reiserfs_i->i_acl_access; 264 p_acl = &reiserfs_i->i_acl_access;
265 if (acl) { 265 if (acl) {
266 mode_t mode = inode->i_mode; 266 mode_t mode = inode->i_mode;
@@ -275,7 +275,7 @@ reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
275 } 275 }
276 break; 276 break;
277 case ACL_TYPE_DEFAULT: 277 case ACL_TYPE_DEFAULT:
278 name = XATTR_NAME_ACL_DEFAULT; 278 name = POSIX_ACL_XATTR_DEFAULT;
279 p_acl = &reiserfs_i->i_acl_default; 279 p_acl = &reiserfs_i->i_acl_default;
280 if (!S_ISDIR (inode->i_mode)) 280 if (!S_ISDIR (inode->i_mode))
281 return acl ? -EACCES : 0; 281 return acl ? -EACCES : 0;
@@ -468,7 +468,7 @@ static int
468posix_acl_access_get(struct inode *inode, const char *name, 468posix_acl_access_get(struct inode *inode, const char *name,
469 void *buffer, size_t size) 469 void *buffer, size_t size)
470{ 470{
471 if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1) 471 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS)-1)
472 return -EINVAL; 472 return -EINVAL;
473 return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); 473 return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
474} 474}
@@ -477,7 +477,7 @@ static int
477posix_acl_access_set(struct inode *inode, const char *name, 477posix_acl_access_set(struct inode *inode, const char *name,
478 const void *value, size_t size, int flags) 478 const void *value, size_t size, int flags)
479{ 479{
480 if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1) 480 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS)-1)
481 return -EINVAL; 481 return -EINVAL;
482 return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); 482 return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
483} 483}
@@ -487,7 +487,7 @@ posix_acl_access_del (struct inode *inode, const char *name)
487{ 487{
488 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 488 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
489 struct posix_acl **acl = &reiserfs_i->i_acl_access; 489 struct posix_acl **acl = &reiserfs_i->i_acl_access;
490 if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1) 490 if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS)-1)
491 return -EINVAL; 491 return -EINVAL;
492 if (!IS_ERR (*acl) && *acl) { 492 if (!IS_ERR (*acl) && *acl) {
493 posix_acl_release (*acl); 493 posix_acl_release (*acl);
@@ -510,7 +510,7 @@ posix_acl_access_list (struct inode *inode, const char *name, int namelen, char
510} 510}
511 511
512struct reiserfs_xattr_handler posix_acl_access_handler = { 512struct reiserfs_xattr_handler posix_acl_access_handler = {
513 .prefix = XATTR_NAME_ACL_ACCESS, 513 .prefix = POSIX_ACL_XATTR_ACCESS,
514 .get = posix_acl_access_get, 514 .get = posix_acl_access_get,
515 .set = posix_acl_access_set, 515 .set = posix_acl_access_set,
516 .del = posix_acl_access_del, 516 .del = posix_acl_access_del,
@@ -521,7 +521,7 @@ static int
521posix_acl_default_get (struct inode *inode, const char *name, 521posix_acl_default_get (struct inode *inode, const char *name,
522 void *buffer, size_t size) 522 void *buffer, size_t size)
523{ 523{
524 if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1) 524 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT)-1)
525 return -EINVAL; 525 return -EINVAL;
526 return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); 526 return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
527} 527}
@@ -530,7 +530,7 @@ static int
530posix_acl_default_set(struct inode *inode, const char *name, 530posix_acl_default_set(struct inode *inode, const char *name,
531 const void *value, size_t size, int flags) 531 const void *value, size_t size, int flags)
532{ 532{
533 if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1) 533 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT)-1)
534 return -EINVAL; 534 return -EINVAL;
535 return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); 535 return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
536} 536}
@@ -540,7 +540,7 @@ posix_acl_default_del (struct inode *inode, const char *name)
540{ 540{
541 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 541 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
542 struct posix_acl **acl = &reiserfs_i->i_acl_default; 542 struct posix_acl **acl = &reiserfs_i->i_acl_default;
543 if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1) 543 if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT)-1)
544 return -EINVAL; 544 return -EINVAL;
545 if (!IS_ERR (*acl) && *acl) { 545 if (!IS_ERR (*acl) && *acl) {
546 posix_acl_release (*acl); 546 posix_acl_release (*acl);
@@ -563,7 +563,7 @@ posix_acl_default_list (struct inode *inode, const char *name, int namelen, char
563} 563}
564 564
565struct reiserfs_xattr_handler posix_acl_default_handler = { 565struct reiserfs_xattr_handler posix_acl_default_handler = {
566 .prefix = XATTR_NAME_ACL_DEFAULT, 566 .prefix = POSIX_ACL_XATTR_DEFAULT,
567 .get = posix_acl_default_get, 567 .get = posix_acl_default_get,
568 .set = posix_acl_default_set, 568 .set = posix_acl_default_set,
569 .del = posix_acl_default_del, 569 .del = posix_acl_default_del,
diff --git a/fs/super.c b/fs/super.c
index 573bcc81bb82..25bc1ec6bc5d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -341,20 +341,22 @@ static inline void write_super(struct super_block *sb)
341 */ 341 */
342void sync_supers(void) 342void sync_supers(void)
343{ 343{
344 struct super_block * sb; 344 struct super_block *sb;
345restart: 345
346 spin_lock(&sb_lock); 346 spin_lock(&sb_lock);
347 sb = sb_entry(super_blocks.next); 347restart:
348 while (sb != sb_entry(&super_blocks)) 348 list_for_each_entry(sb, &super_blocks, s_list) {
349 if (sb->s_dirt) { 349 if (sb->s_dirt) {
350 sb->s_count++; 350 sb->s_count++;
351 spin_unlock(&sb_lock); 351 spin_unlock(&sb_lock);
352 down_read(&sb->s_umount); 352 down_read(&sb->s_umount);
353 write_super(sb); 353 write_super(sb);
354 drop_super(sb); 354 up_read(&sb->s_umount);
355 goto restart; 355 spin_lock(&sb_lock);
356 } else 356 if (__put_super_and_need_restart(sb))
357 sb = sb_entry(sb->s_list.next); 357 goto restart;
358 }
359 }
358 spin_unlock(&sb_lock); 360 spin_unlock(&sb_lock);
359} 361}
360 362
@@ -381,20 +383,16 @@ void sync_filesystems(int wait)
381 383
382 down(&mutex); /* Could be down_interruptible */ 384 down(&mutex); /* Could be down_interruptible */
383 spin_lock(&sb_lock); 385 spin_lock(&sb_lock);
384 for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks); 386 list_for_each_entry(sb, &super_blocks, s_list) {
385 sb = sb_entry(sb->s_list.next)) {
386 if (!sb->s_op->sync_fs) 387 if (!sb->s_op->sync_fs)
387 continue; 388 continue;
388 if (sb->s_flags & MS_RDONLY) 389 if (sb->s_flags & MS_RDONLY)
389 continue; 390 continue;
390 sb->s_need_sync_fs = 1; 391 sb->s_need_sync_fs = 1;
391 } 392 }
392 spin_unlock(&sb_lock);
393 393
394restart: 394restart:
395 spin_lock(&sb_lock); 395 list_for_each_entry(sb, &super_blocks, s_list) {
396 for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
397 sb = sb_entry(sb->s_list.next)) {
398 if (!sb->s_need_sync_fs) 396 if (!sb->s_need_sync_fs)
399 continue; 397 continue;
400 sb->s_need_sync_fs = 0; 398 sb->s_need_sync_fs = 0;
@@ -405,8 +403,11 @@ restart:
405 down_read(&sb->s_umount); 403 down_read(&sb->s_umount);
406 if (sb->s_root && (wait || sb->s_dirt)) 404 if (sb->s_root && (wait || sb->s_dirt))
407 sb->s_op->sync_fs(sb, wait); 405 sb->s_op->sync_fs(sb, wait);
408 drop_super(sb); 406 up_read(&sb->s_umount);
409 goto restart; 407 /* restart only when sb is no longer on the list */
408 spin_lock(&sb_lock);
409 if (__put_super_and_need_restart(sb))
410 goto restart;
410 } 411 }
411 spin_unlock(&sb_lock); 412 spin_unlock(&sb_lock);
412 up(&mutex); 413 up(&mutex);
@@ -422,21 +423,25 @@ restart:
422 423
423struct super_block * get_super(struct block_device *bdev) 424struct super_block * get_super(struct block_device *bdev)
424{ 425{
425 struct list_head *p; 426 struct super_block *sb;
427
426 if (!bdev) 428 if (!bdev)
427 return NULL; 429 return NULL;
428rescan: 430
429 spin_lock(&sb_lock); 431 spin_lock(&sb_lock);
430 list_for_each(p, &super_blocks) { 432rescan:
431 struct super_block *s = sb_entry(p); 433 list_for_each_entry(sb, &super_blocks, s_list) {
432 if (s->s_bdev == bdev) { 434 if (sb->s_bdev == bdev) {
433 s->s_count++; 435 sb->s_count++;
434 spin_unlock(&sb_lock); 436 spin_unlock(&sb_lock);
435 down_read(&s->s_umount); 437 down_read(&sb->s_umount);
436 if (s->s_root) 438 if (sb->s_root)
437 return s; 439 return sb;
438 drop_super(s); 440 up_read(&sb->s_umount);
439 goto rescan; 441 /* restart only when sb is no longer on the list */
442 spin_lock(&sb_lock);
443 if (__put_super_and_need_restart(sb))
444 goto rescan;
440 } 445 }
441 } 446 }
442 spin_unlock(&sb_lock); 447 spin_unlock(&sb_lock);
@@ -447,20 +452,22 @@ EXPORT_SYMBOL(get_super);
447 452
448struct super_block * user_get_super(dev_t dev) 453struct super_block * user_get_super(dev_t dev)
449{ 454{
450 struct list_head *p; 455 struct super_block *sb;
451 456
452rescan:
453 spin_lock(&sb_lock); 457 spin_lock(&sb_lock);
454 list_for_each(p, &super_blocks) { 458rescan:
455 struct super_block *s = sb_entry(p); 459 list_for_each_entry(sb, &super_blocks, s_list) {
456 if (s->s_dev == dev) { 460 if (sb->s_dev == dev) {
457 s->s_count++; 461 sb->s_count++;
458 spin_unlock(&sb_lock); 462 spin_unlock(&sb_lock);
459 down_read(&s->s_umount); 463 down_read(&sb->s_umount);
460 if (s->s_root) 464 if (sb->s_root)
461 return s; 465 return sb;
462 drop_super(s); 466 up_read(&sb->s_umount);
463 goto rescan; 467 /* restart only when sb is no longer on the list */
468 spin_lock(&sb_lock);
469 if (__put_super_and_need_restart(sb))
470 goto rescan;
464 } 471 }
465 } 472 }
466 spin_unlock(&sb_lock); 473 spin_unlock(&sb_lock);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 37d7a6875d86..59734ba1ee60 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -8,6 +8,7 @@
8#include <linux/mount.h> 8#include <linux/mount.h>
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/kobject.h> 10#include <linux/kobject.h>
11#include <linux/namei.h>
11#include "sysfs.h" 12#include "sysfs.h"
12 13
13DECLARE_RWSEM(sysfs_rename_sem); 14DECLARE_RWSEM(sysfs_rename_sem);
@@ -99,7 +100,7 @@ static int create_dir(struct kobject * k, struct dentry * p,
99 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 100 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
100 101
101 down(&p->d_inode->i_sem); 102 down(&p->d_inode->i_sem);
102 *d = sysfs_get_dentry(p,n); 103 *d = lookup_one_len(n, p, strlen(n));
103 if (!IS_ERR(*d)) { 104 if (!IS_ERR(*d)) {
104 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); 105 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
105 if (!error) { 106 if (!error) {
@@ -315,7 +316,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
315 316
316 down(&parent->d_inode->i_sem); 317 down(&parent->d_inode->i_sem);
317 318
318 new_dentry = sysfs_get_dentry(parent, new_name); 319 new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
319 if (!IS_ERR(new_dentry)) { 320 if (!IS_ERR(new_dentry)) {
320 if (!new_dentry->d_inode) { 321 if (!new_dentry->d_inode) {
321 error = kobject_set_name(kobj, "%s", new_name); 322 error = kobject_set_name(kobj, "%s", new_name);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 849aac115460..d72c1ce48559 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -5,6 +5,7 @@
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/dnotify.h> 6#include <linux/dnotify.h>
7#include <linux/kobject.h> 7#include <linux/kobject.h>
8#include <linux/namei.h>
8#include <asm/uaccess.h> 9#include <asm/uaccess.h>
9#include <asm/semaphore.h> 10#include <asm/semaphore.h>
10 11
@@ -13,7 +14,7 @@
13#define to_subsys(k) container_of(k,struct subsystem,kset.kobj) 14#define to_subsys(k) container_of(k,struct subsystem,kset.kobj)
14#define to_sattr(a) container_of(a,struct subsys_attribute,attr) 15#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
15 16
16/** 17/*
17 * Subsystem file operations. 18 * Subsystem file operations.
18 * These operations allow subsystems to have files that can be 19 * These operations allow subsystems to have files that can be
19 * read/written. 20 * read/written.
@@ -191,8 +192,9 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
191 192
192/** 193/**
193 * flush_write_buffer - push buffer to kobject. 194 * flush_write_buffer - push buffer to kobject.
194 * @file: file pointer. 195 * @dentry: dentry to the attribute
195 * @buffer: data buffer for file. 196 * @buffer: data buffer for file.
197 * @count: number of bytes
196 * 198 *
197 * Get the correct pointers for the kobject and the attribute we're 199 * Get the correct pointers for the kobject and the attribute we're
198 * dealing with, then call the store() method for the attribute, 200 * dealing with, then call the store() method for the attribute,
@@ -400,7 +402,7 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
400 int res = -ENOENT; 402 int res = -ENOENT;
401 403
402 down(&dir->d_inode->i_sem); 404 down(&dir->d_inode->i_sem);
403 victim = sysfs_get_dentry(dir, attr->name); 405 victim = lookup_one_len(attr->name, dir, strlen(attr->name));
404 if (!IS_ERR(victim)) { 406 if (!IS_ERR(victim)) {
405 /* make sure dentry is really there */ 407 /* make sure dentry is really there */
406 if (victim->d_inode && 408 if (victim->d_inode &&
@@ -443,7 +445,7 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
443 int res = -ENOENT; 445 int res = -ENOENT;
444 446
445 down(&dir->d_inode->i_sem); 447 down(&dir->d_inode->i_sem);
446 victim = sysfs_get_dentry(dir, attr->name); 448 victim = lookup_one_len(attr->name, dir, strlen(attr->name));
447 if (!IS_ERR(victim)) { 449 if (!IS_ERR(victim)) {
448 if (victim->d_inode && 450 if (victim->d_inode &&
449 (victim->d_parent->d_inode == dir->d_inode)) { 451 (victim->d_parent->d_inode == dir->d_inode)) {
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index f11ac5ea7021..122145b0895c 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -11,6 +11,7 @@
11#include <linux/kobject.h> 11#include <linux/kobject.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/dcache.h> 13#include <linux/dcache.h>
14#include <linux/namei.h>
14#include <linux/err.h> 15#include <linux/err.h>
15#include "sysfs.h" 16#include "sysfs.h"
16 17
@@ -68,7 +69,8 @@ void sysfs_remove_group(struct kobject * kobj,
68 struct dentry * dir; 69 struct dentry * dir;
69 70
70 if (grp->name) 71 if (grp->name)
71 dir = sysfs_get_dentry(kobj->dentry,grp->name); 72 dir = lookup_one_len(grp->name, kobj->dentry,
73 strlen(grp->name));
72 else 74 else
73 dir = dget(kobj->dentry); 75 dir = dget(kobj->dentry);
74 76
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 565cac1d4200..8de13bafaa76 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -166,16 +166,6 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
166 return error; 166 return error;
167} 167}
168 168
169struct dentry * sysfs_get_dentry(struct dentry * parent, const char * name)
170{
171 struct qstr qstr;
172
173 qstr.name = name;
174 qstr.len = strlen(name);
175 qstr.hash = full_name_hash(name,qstr.len);
176 return lookup_hash(&qstr,parent);
177}
178
179/* 169/*
180 * Get the name for corresponding element represented by the given sysfs_dirent 170 * Get the name for corresponding element represented by the given sysfs_dirent
181 */ 171 */
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 29da6f5f07c8..3f8953e0e5d0 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -7,7 +7,6 @@ extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
7 7
8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, 8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
9 umode_t, int); 9 umode_t, int);
10extern struct dentry * sysfs_get_dentry(struct dentry *, const char *);
11 10
12extern int sysfs_add_file(struct dentry *, const struct attribute *, int); 11extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
13extern void sysfs_hash_and_remove(struct dentry * dir, const char * name); 12extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 93ce257cd149..a3a4b5aaf5d9 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -149,11 +149,12 @@ linvfs_unwritten_convert(
149 */ 149 */
150STATIC void 150STATIC void
151linvfs_unwritten_convert_direct( 151linvfs_unwritten_convert_direct(
152 struct inode *inode, 152 struct kiocb *iocb,
153 loff_t offset, 153 loff_t offset,
154 ssize_t size, 154 ssize_t size,
155 void *private) 155 void *private)
156{ 156{
157 struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
157 ASSERT(!private || inode == (struct inode *)private); 158 ASSERT(!private || inode == (struct inode *)private);
158 159
159 /* private indicates an unwritten extent lay beneath this IO */ 160 /* private indicates an unwritten extent lay beneath this IO */
diff --git a/include/asm-alpha/mmzone.h b/include/asm-alpha/mmzone.h
index 726c150dcbe4..a011ef4cf3d3 100644
--- a/include/asm-alpha/mmzone.h
+++ b/include/asm-alpha/mmzone.h
@@ -57,7 +57,6 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
57 * Given a kernel address, find the home node of the underlying memory. 57 * Given a kernel address, find the home node of the underlying memory.
58 */ 58 */
59#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr)) 59#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
60#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
61#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 60#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
62 61
63#define local_mapnr(kvaddr) \ 62#define local_mapnr(kvaddr) \
@@ -108,7 +107,7 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
108#define pfn_to_page(pfn) \ 107#define pfn_to_page(pfn) \
109({ \ 108({ \
110 unsigned long kaddr = (unsigned long)__va((pfn) << PAGE_SHIFT); \ 109 unsigned long kaddr = (unsigned long)__va((pfn) << PAGE_SHIFT); \
111 (node_mem_map(kvaddr_to_nid(kaddr)) + local_mapnr(kaddr)); \ 110 (NODE_DATA(kvaddr_to_nid(kaddr))->node_mem_map + local_mapnr(kaddr)); \
112}) 111})
113 112
114#define page_to_pfn(page) \ 113#define page_to_pfn(page) \
diff --git a/include/asm-arm/arch-ixp2000/gpio.h b/include/asm-arm/arch-ixp2000/gpio.h
index 84634af5cc64..03cbbe1fd9d8 100644
--- a/include/asm-arm/arch-ixp2000/gpio.h
+++ b/include/asm-arm/arch-ixp2000/gpio.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-ixp2000/ixp2000-gpio.h 2 * include/asm-arm/arch-ixp2000/gpio.h
3 * 3 *
4 * Copyright (C) 2002 Intel Corporation. 4 * Copyright (C) 2002 Intel Corporation.
5 * 5 *
@@ -16,26 +16,18 @@
16 * Use this instead of directly setting the GPIO registers. 16 * Use this instead of directly setting the GPIO registers.
17 * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb) 17 * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
18 */ 18 */
19#ifndef _ASM_ARCH_IXP2000_GPIO_H_ 19#ifndef __ASM_ARCH_GPIO_H
20#define _ASM_ARCH_IXP2000_GPIO_H_ 20#define __ASM_ARCH_GPIO_H
21 21
22#ifndef __ASSEMBLY__ 22#ifndef __ASSEMBLY__
23#define GPIO_OUT 0x0 23
24#define GPIO_IN 0x80 24#define GPIO_IN 0
25#define GPIO_OUT 1
25 26
26#define IXP2000_GPIO_LOW 0 27#define IXP2000_GPIO_LOW 0
27#define IXP2000_GPIO_HIGH 1 28#define IXP2000_GPIO_HIGH 1
28 29
29#define GPIO_NO_EDGES 0 30extern void gpio_line_config(int line, int direction);
30#define GPIO_FALLING_EDGE 1
31#define GPIO_RISING_EDGE 2
32#define GPIO_BOTH_EDGES 3
33#define GPIO_LEVEL_LOW 4
34#define GPIO_LEVEL_HIGH 8
35
36extern void set_GPIO_IRQ_edge(int gpio_nr, int edge);
37extern void set_GPIO_IRQ_level(int gpio_nr, int level);
38extern void gpio_line_config(int line, int style);
39 31
40static inline int gpio_line_get(int line) 32static inline int gpio_line_get(int line)
41{ 33{
@@ -45,11 +37,12 @@ static inline int gpio_line_get(int line)
45static inline void gpio_line_set(int line, int value) 37static inline void gpio_line_set(int line, int value)
46{ 38{
47 if (value == IXP2000_GPIO_HIGH) { 39 if (value == IXP2000_GPIO_HIGH) {
48 ixp_reg_write(IXP2000_GPIO_POSR, BIT(line)); 40 ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line);
49 } else if (value == IXP2000_GPIO_LOW) 41 } else if (value == IXP2000_GPIO_LOW) {
50 ixp_reg_write(IXP2000_GPIO_POCR, BIT(line)); 42 ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line);
43 }
51} 44}
52 45
53#endif /* !__ASSEMBLY__ */ 46#endif /* !__ASSEMBLY__ */
54#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
55 47
48#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
index 083462668e18..5e56b47446e0 100644
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -27,8 +27,8 @@
27 * since that isn't available on the A? revisions we just keep doing 27 * since that isn't available on the A? revisions we just keep doing
28 * things manually. 28 * things manually.
29 */ 29 */
30#define alignb(addr) (void __iomem *)((unsigned long)addr ^ 3) 30#define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3)
31#define alignw(addr) (void __iomem *)((unsigned long)addr ^ 2) 31#define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2)
32 32
33#define outb(v,p) __raw_writeb((v),alignb(___io(p))) 33#define outb(v,p) __raw_writeb((v),alignb(___io(p)))
34#define outw(v,p) __raw_writew((v),alignw(___io(p))) 34#define outw(v,p) __raw_writew((v),alignw(___io(p)))
@@ -48,6 +48,78 @@
48#define insw(p,d,l) __raw_readsw(alignw(___io(p)),d,l) 48#define insw(p,d,l) __raw_readsw(alignw(___io(p)),d,l)
49#define insl(p,d,l) __raw_readsl(___io(p),d,l) 49#define insl(p,d,l) __raw_readsl(___io(p),d,l)
50 50
51#define __is_io_address(p) ((((unsigned long)(p)) & ~(IXP2000_PCI_IO_SIZE - 1)) == IXP2000_PCI_IO_VIRT_BASE)
52
53#define ioread8(p) \
54 ({ \
55 unsigned int __v; \
56 \
57 if (__is_io_address(p)) { \
58 __v = __raw_readb(alignb(p)); \
59 } else { \
60 __v = __raw_readb(p); \
61 } \
62 \
63 __v; \
64 }) \
65
66#define ioread16(p) \
67 ({ \
68 unsigned int __v; \
69 \
70 if (__is_io_address(p)) { \
71 __v = __raw_readw(alignw(p)); \
72 } else { \
73 __v = le16_to_cpu(__raw_readw(p)); \
74 } \
75 \
76 __v; \
77 })
78
79#define ioread32(p) \
80 ({ \
81 unsigned int __v; \
82 \
83 if (__is_io_address(p)) { \
84 __v = __raw_readl(p); \
85 } else { \
86 __v = le32_to_cpu(__raw_readl(p)); \
87 } \
88 \
89 __v; \
90 })
91
92#define iowrite8(v,p) \
93 ({ \
94 if (__is_io_address(p)) { \
95 __raw_writeb((v), alignb(p)); \
96 } else { \
97 __raw_writeb((v), p); \
98 } \
99 })
100
101#define iowrite16(v,p) \
102 ({ \
103 if (__is_io_address(p)) { \
104 __raw_writew((v), alignw(p)); \
105 } else { \
106 __raw_writew(cpu_to_le16(v), p); \
107 } \
108 })
109
110#define iowrite32(v,p) \
111 ({ \
112 if (__is_io_address(p)) { \
113 __raw_writel((v), p); \
114 } else { \
115 __raw_writel(cpu_to_le32(v), p); \
116 } \
117 })
118
119#define ioport_map(port, nr) ___io(port)
120
121#define ioport_unmap(addr)
122
51 123
52#ifdef CONFIG_ARCH_IXDP2X01 124#ifdef CONFIG_ARCH_IXDP2X01
53/* 125/*
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h
index 901bba6d02b4..52ded516ea5c 100644
--- a/include/asm-arm/arch-ixp2000/platform.h
+++ b/include/asm-arm/arch-ixp2000/platform.h
@@ -138,30 +138,10 @@ struct ixp2000_flash_data {
138 unsigned long (*bank_setup)(unsigned long); 138 unsigned long (*bank_setup)(unsigned long);
139}; 139};
140 140
141/*
142 * GPIO helper functions
143 */
144#define GPIO_IN 0
145#define GPIO_OUT 1
146
147extern void gpio_line_config(int line, int style);
148
149static inline int gpio_line_get(int line)
150{
151 return (((*IXP2000_GPIO_PLR) >> line) & 1);
152}
153
154static inline void gpio_line_set(int line, int value)
155{
156 if (value)
157 ixp2000_reg_write(IXP2000_GPIO_POSR, (1 << line));
158 else
159 ixp2000_reg_write(IXP2000_GPIO_POCR, (1 << line));
160}
161
162struct ixp2000_i2c_pins { 141struct ixp2000_i2c_pins {
163 unsigned long sda_pin; 142 unsigned long sda_pin;
164 unsigned long scl_pin; 143 unsigned long scl_pin;
165}; 144};
166 145
146
167#endif /* !__ASSEMBLY__ */ 147#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-arm/arch-ixp4xx/debug-macro.S b/include/asm-arm/arch-ixp4xx/debug-macro.S
index 4499ae8e4b44..45a6c6cc29d5 100644
--- a/include/asm-arm/arch-ixp4xx/debug-macro.S
+++ b/include/asm-arm/arch-ixp4xx/debug-macro.S
@@ -14,6 +14,7 @@
14 mrc p15, 0, \rx, c1, c0 14 mrc p15, 0, \rx, c1, c0
15 tst \rx, #1 @ MMU enabled? 15 tst \rx, #1 @ MMU enabled?
16 moveq \rx, #0xc8000000 16 moveq \rx, #0xc8000000
17 orrne \rx, \rx, #0x00b00000
17 movne \rx, #0xff000000 18 movne \rx, #0xff000000
18 add \rx,\rx,#3 @ Uart regs are at off set of 3 if 19 add \rx,\rx,#3 @ Uart regs are at off set of 3 if
19 @ byte writes used - Big Endian. 20 @ byte writes used - Big Endian.
diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
index 8eeb1db6309d..004696a95bdb 100644
--- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
@@ -69,6 +69,16 @@
69#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBF2000) 69#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBF2000)
70#define IXP4XX_PERIPHERAL_REGION_SIZE (0x0000C000) 70#define IXP4XX_PERIPHERAL_REGION_SIZE (0x0000C000)
71 71
72/*
73 * Debug UART
74 *
75 * This is basically a remap of UART1 into a region that is section
76 * aligned so that it * can be used with the low-level debug code.
77 */
78#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000)
79#define IXP4XX_DEBUG_UART_BASE_VIRT (0xffb00000)
80#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
81
72#define IXP4XX_EXP_CS0_OFFSET 0x00 82#define IXP4XX_EXP_CS0_OFFSET 0x00
73#define IXP4XX_EXP_CS1_OFFSET 0x04 83#define IXP4XX_EXP_CS1_OFFSET 0x04
74#define IXP4XX_EXP_CS2_OFFSET 0x08 84#define IXP4XX_EXP_CS2_OFFSET 0x08
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 08a46302d265..cc4b5f5dbfcf 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -275,6 +275,7 @@ extern void __iounmap(void __iomem *addr);
275/* 275/*
276 * io{read,write}{8,16,32} macros 276 * io{read,write}{8,16,32} macros
277 */ 277 */
278#ifndef ioread8
278#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; }) 279#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; })
279#define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; }) 280#define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
280#define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; }) 281#define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
@@ -293,6 +294,7 @@ extern void __iounmap(void __iomem *addr);
293 294
294extern void __iomem *ioport_map(unsigned long port, unsigned int nr); 295extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
295extern void ioport_unmap(void __iomem *addr); 296extern void ioport_unmap(void __iomem *addr);
297#endif
296 298
297struct pci_dev; 299struct pci_dev;
298 300
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index 66c585c50cf9..8252a4cd860f 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -49,7 +49,7 @@ struct cpu_context_save {
49 */ 49 */
50struct thread_info { 50struct thread_info {
51 unsigned long flags; /* low level flags */ 51 unsigned long flags; /* low level flags */
52 __s32 preempt_count; /* 0 => preemptable, <0 => bug */ 52 int preempt_count; /* 0 => preemptable, <0 => bug */
53 mm_segment_t addr_limit; /* address limit */ 53 mm_segment_t addr_limit; /* address limit */
54 struct task_struct *task; /* main task structure */ 54 struct task_struct *task; /* main task structure */
55 struct exec_domain *exec_domain; /* execution domain */ 55 struct exec_domain *exec_domain; /* execution domain */
diff --git a/include/asm-arm26/thread_info.h b/include/asm-arm26/thread_info.h
index 50f41b50268a..aff3e5699c64 100644
--- a/include/asm-arm26/thread_info.h
+++ b/include/asm-arm26/thread_info.h
@@ -44,7 +44,7 @@ struct cpu_context_save {
44 */ 44 */
45struct thread_info { 45struct thread_info {
46 unsigned long flags; /* low level flags */ 46 unsigned long flags; /* low level flags */
47 __s32 preempt_count; /* 0 => preemptable, <0 => bug */ 47 int preempt_count; /* 0 => preemptable, <0 => bug */
48 mm_segment_t addr_limit; /* address limit */ 48 mm_segment_t addr_limit; /* address limit */
49 struct task_struct *task; /* main task structure */ 49 struct task_struct *task; /* main task structure */
50 struct exec_domain *exec_domain; /* execution domain */ 50 struct exec_domain *exec_domain; /* execution domain */
diff --git a/include/asm-cris/thread_info.h b/include/asm-cris/thread_info.h
index 53193feb0826..5ba4b7865cc5 100644
--- a/include/asm-cris/thread_info.h
+++ b/include/asm-cris/thread_info.h
@@ -31,7 +31,7 @@ struct thread_info {
31 struct exec_domain *exec_domain; /* execution domain */ 31 struct exec_domain *exec_domain; /* execution domain */
32 unsigned long flags; /* low level flags */ 32 unsigned long flags; /* low level flags */
33 __u32 cpu; /* current CPU */ 33 __u32 cpu; /* current CPU */
34 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 34 int preempt_count; /* 0 => preemptable, <0 => BUG */
35 35
36 mm_segment_t addr_limit; /* thread address space: 36 mm_segment_t addr_limit; /* thread address space:
37 0-0xBFFFFFFF for user-thead 37 0-0xBFFFFFFF for user-thead
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index b80a97f50af6..c8cba7836f0d 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -33,7 +33,7 @@ struct thread_info {
33 unsigned long flags; /* low level flags */ 33 unsigned long flags; /* low level flags */
34 unsigned long status; /* thread-synchronous flags */ 34 unsigned long status; /* thread-synchronous flags */
35 __u32 cpu; /* current CPU */ 35 __u32 cpu; /* current CPU */
36 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 36 int preempt_count; /* 0 => preemptable, <0 => BUG */
37 37
38 mm_segment_t addr_limit; /* thread address space: 38 mm_segment_t addr_limit; /* thread address space:
39 0-0xBFFFFFFF for user-thead 39 0-0xBFFFFFFF for user-thead
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 3b709b84934f..9044aeb37828 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -29,7 +29,7 @@ do { \
29#define DEFINE_PER_CPU(type, name) \ 29#define DEFINE_PER_CPU(type, name) \
30 __typeof__(type) per_cpu__##name 30 __typeof__(type) per_cpu__##name
31 31
32#define per_cpu(var, cpu) (*((void)cpu, &per_cpu__##var)) 32#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
33#define __get_cpu_var(var) per_cpu__##var 33#define __get_cpu_var(var) per_cpu__##var
34 34
35#endif /* SMP */ 35#endif /* SMP */
diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h
index ec96e8b0f190..5d9d70cd17fc 100644
--- a/include/asm-generic/topology.h
+++ b/include/asm-generic/topology.h
@@ -41,8 +41,15 @@
41#ifndef node_to_first_cpu 41#ifndef node_to_first_cpu
42#define node_to_first_cpu(node) (0) 42#define node_to_first_cpu(node) (0)
43#endif 43#endif
44#ifndef pcibus_to_node
45#define pcibus_to_node(node) (-1)
46#endif
47
44#ifndef pcibus_to_cpumask 48#ifndef pcibus_to_cpumask
45#define pcibus_to_cpumask(bus) (cpu_online_map) 49#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
50 CPU_MASK_ALL : \
51 node_to_cpumask(pcibus_to_node(bus)) \
52 )
46#endif 53#endif
47 54
48#endif /* _ASM_GENERIC_TOPOLOGY_H */ 55#endif /* _ASM_GENERIC_TOPOLOGY_H */
diff --git a/include/asm-h8300/thread_info.h b/include/asm-h8300/thread_info.h
index b07c9344776f..bfcc755c3bb1 100644
--- a/include/asm-h8300/thread_info.h
+++ b/include/asm-h8300/thread_info.h
@@ -23,7 +23,7 @@ struct thread_info {
23 struct exec_domain *exec_domain; /* execution domain */ 23 struct exec_domain *exec_domain; /* execution domain */
24 unsigned long flags; /* low level flags */ 24 unsigned long flags; /* low level flags */
25 int cpu; /* cpu we're on */ 25 int cpu; /* cpu we're on */
26 int preempt_count; /* 0 => preemptable, <0 => BUG*/ 26 int preempt_count; /* 0 => preemptable, <0 => BUG */
27 struct restart_block restart_block; 27 struct restart_block restart_block;
28}; 28};
29 29
diff --git a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h
index 641342002bcd..f949e44c2a35 100644
--- a/include/asm-i386/checksum.h
+++ b/include/asm-i386/checksum.h
@@ -3,6 +3,8 @@
3 3
4#include <linux/in6.h> 4#include <linux/in6.h>
5 5
6#include <asm/uaccess.h>
7
6/* 8/*
7 * computes the checksum of a memory block at buff, length len, 9 * computes the checksum of a memory block at buff, length len,
8 * and adds in "sum" (32-bit) 10 * and adds in "sum" (32-bit)
diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h
index fc813b2e8274..b3783a32abee 100644
--- a/include/asm-i386/genapic.h
+++ b/include/asm-i386/genapic.h
@@ -78,7 +78,6 @@ struct genapic {
78 .int_delivery_mode = INT_DELIVERY_MODE, \ 78 .int_delivery_mode = INT_DELIVERY_MODE, \
79 .int_dest_mode = INT_DEST_MODE, \ 79 .int_dest_mode = INT_DEST_MODE, \
80 .no_balance_irq = NO_BALANCE_IRQ, \ 80 .no_balance_irq = NO_BALANCE_IRQ, \
81 .no_ioapic_check = NO_IOAPIC_CHECK, \
82 .ESR_DISABLE = esr_disable, \ 81 .ESR_DISABLE = esr_disable, \
83 .apic_destination_logical = APIC_DEST_LOGICAL, \ 82 .apic_destination_logical = APIC_DEST_LOGICAL, \
84 APICFUNC(apic_id_registered), \ 83 APICFUNC(apic_id_registered), \
diff --git a/include/asm-i386/kprobes.h b/include/asm-i386/kprobes.h
index 4092f68d123a..8b6d3a90cd78 100644
--- a/include/asm-i386/kprobes.h
+++ b/include/asm-i386/kprobes.h
@@ -39,6 +39,9 @@ typedef u8 kprobe_opcode_t;
39 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) 39 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
40 40
41#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry 41#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
42#define ARCH_SUPPORTS_KRETPROBES
43
44void kretprobe_trampoline(void);
42 45
43/* Architecture specific copy of original instruction*/ 46/* Architecture specific copy of original instruction*/
44struct arch_specific_insn { 47struct arch_specific_insn {
diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h
index 2339868270ef..ba936d4daedb 100644
--- a/include/asm-i386/mach-bigsmp/mach_apic.h
+++ b/include/asm-i386/mach-bigsmp/mach_apic.h
@@ -14,8 +14,6 @@
14#define NO_BALANCE_IRQ (1) 14#define NO_BALANCE_IRQ (1)
15#define esr_disable (1) 15#define esr_disable (1)
16 16
17#define NO_IOAPIC_CHECK (0)
18
19static inline int apic_id_registered(void) 17static inline int apic_id_registered(void)
20{ 18{
21 return (1); 19 return (1);
diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h
index 627f1cd084ba..3ef6292db780 100644
--- a/include/asm-i386/mach-default/mach_apic.h
+++ b/include/asm-i386/mach-default/mach_apic.h
@@ -19,8 +19,6 @@ static inline cpumask_t target_cpus(void)
19#define NO_BALANCE_IRQ (0) 19#define NO_BALANCE_IRQ (0)
20#define esr_disable (0) 20#define esr_disable (0)
21 21
22#define NO_IOAPIC_CHECK (0)
23
24#define INT_DELIVERY_MODE dest_LowestPrio 22#define INT_DELIVERY_MODE dest_LowestPrio
25#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ 23#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
26 24
diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h
index ceab2c464b13..b5f3f0d0b2bc 100644
--- a/include/asm-i386/mach-es7000/mach_apic.h
+++ b/include/asm-i386/mach-es7000/mach_apic.h
@@ -38,8 +38,6 @@ static inline cpumask_t target_cpus(void)
38#define WAKE_SECONDARY_VIA_INIT 38#define WAKE_SECONDARY_VIA_INIT
39#endif 39#endif
40 40
41#define NO_IOAPIC_CHECK (1)
42
43static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid) 41static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
44{ 42{
45 return 0; 43 return 0;
diff --git a/include/asm-i386/mach-generic/mach_apic.h b/include/asm-i386/mach-generic/mach_apic.h
index ab36d02ebede..b13767a4e934 100644
--- a/include/asm-i386/mach-generic/mach_apic.h
+++ b/include/asm-i386/mach-generic/mach_apic.h
@@ -5,7 +5,6 @@
5 5
6#define esr_disable (genapic->ESR_DISABLE) 6#define esr_disable (genapic->ESR_DISABLE)
7#define NO_BALANCE_IRQ (genapic->no_balance_irq) 7#define NO_BALANCE_IRQ (genapic->no_balance_irq)
8#define NO_IOAPIC_CHECK (genapic->no_ioapic_check)
9#define INT_DELIVERY_MODE (genapic->int_delivery_mode) 8#define INT_DELIVERY_MODE (genapic->int_delivery_mode)
10#define INT_DEST_MODE (genapic->int_dest_mode) 9#define INT_DEST_MODE (genapic->int_dest_mode)
11#undef APIC_DEST_LOGICAL 10#undef APIC_DEST_LOGICAL
diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h
index e1a04494764a..9d158095da82 100644
--- a/include/asm-i386/mach-numaq/mach_apic.h
+++ b/include/asm-i386/mach-numaq/mach_apic.h
@@ -17,8 +17,6 @@ static inline cpumask_t target_cpus(void)
17#define NO_BALANCE_IRQ (1) 17#define NO_BALANCE_IRQ (1)
18#define esr_disable (1) 18#define esr_disable (1)
19 19
20#define NO_IOAPIC_CHECK (0)
21
22#define INT_DELIVERY_MODE dest_LowestPrio 20#define INT_DELIVERY_MODE dest_LowestPrio
23#define INT_DEST_MODE 0 /* physical delivery on LOCAL quad */ 21#define INT_DEST_MODE 0 /* physical delivery on LOCAL quad */
24 22
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
index 74e9cbc8c01b..3d6d12937e1f 100644
--- a/include/asm-i386/mach-summit/mach_apic.h
+++ b/include/asm-i386/mach-summit/mach_apic.h
@@ -7,8 +7,6 @@
7#define esr_disable (1) 7#define esr_disable (1)
8#define NO_BALANCE_IRQ (0) 8#define NO_BALANCE_IRQ (0)
9 9
10#define NO_IOAPIC_CHECK (1) /* Don't check I/O APIC ID for xAPIC */
11
12/* In clustered mode, the high nibble of APIC ID is a cluster number. 10/* In clustered mode, the high nibble of APIC ID is a cluster number.
13 * The low nibble is a 4-bit bitmap. */ 11 * The low nibble is a 4-bit bitmap. */
14#define XAPIC_DEST_CPUS_SHIFT 4 12#define XAPIC_DEST_CPUS_SHIFT 4
diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h
index 4e6cdfb8b091..de438c7147a8 100644
--- a/include/asm-i386/mach-visws/mach_apic.h
+++ b/include/asm-i386/mach-visws/mach_apic.h
@@ -9,8 +9,6 @@
9#define no_balance_irq (0) 9#define no_balance_irq (0)
10#define esr_disable (0) 10#define esr_disable (0)
11 11
12#define NO_IOAPIC_CHECK (0)
13
14#define INT_DELIVERY_MODE dest_LowestPrio 12#define INT_DELIVERY_MODE dest_LowestPrio
15#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ 13#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
16 14
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 13830ae67cac..33ce5d37e894 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -8,7 +8,9 @@
8 8
9#include <asm/smp.h> 9#include <asm/smp.h>
10 10
11#ifdef CONFIG_DISCONTIGMEM 11#if CONFIG_NUMA
12extern struct pglist_data *node_data[];
13#define NODE_DATA(nid) (node_data[nid])
12 14
13#ifdef CONFIG_NUMA 15#ifdef CONFIG_NUMA
14 #ifdef CONFIG_X86_NUMAQ 16 #ifdef CONFIG_X86_NUMAQ
@@ -21,8 +23,28 @@
21 #define get_zholes_size(n) (0) 23 #define get_zholes_size(n) (0)
22#endif /* CONFIG_NUMA */ 24#endif /* CONFIG_NUMA */
23 25
24extern struct pglist_data *node_data[]; 26extern int get_memcfg_numa_flat(void );
25#define NODE_DATA(nid) (node_data[nid]) 27/*
28 * This allows any one NUMA architecture to be compiled
29 * for, and still fall back to the flat function if it
30 * fails.
31 */
32static inline void get_memcfg_numa(void)
33{
34#ifdef CONFIG_X86_NUMAQ
35 if (get_memcfg_numaq())
36 return;
37#elif CONFIG_ACPI_SRAT
38 if (get_memcfg_from_srat())
39 return;
40#endif
41
42 get_memcfg_numa_flat();
43}
44
45#endif /* CONFIG_NUMA */
46
47#ifdef CONFIG_DISCONTIGMEM
26 48
27/* 49/*
28 * generic node memory support, the following assumptions apply: 50 * generic node memory support, the following assumptions apply:
@@ -48,26 +70,6 @@ static inline int pfn_to_nid(unsigned long pfn)
48#endif 70#endif
49} 71}
50 72
51/*
52 * Following are macros that are specific to this numa platform.
53 */
54#define reserve_bootmem(addr, size) \
55 reserve_bootmem_node(NODE_DATA(0), (addr), (size))
56#define alloc_bootmem(x) \
57 __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
58#define alloc_bootmem_low(x) \
59 __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, 0)
60#define alloc_bootmem_pages(x) \
61 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
62#define alloc_bootmem_low_pages(x) \
63 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
64#define alloc_bootmem_node(ignore, x) \
65 __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
66#define alloc_bootmem_pages_node(ignore, x) \
67 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
68#define alloc_bootmem_low_pages_node(ignore, x) \
69 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
70
71#define node_localnr(pfn, nid) ((pfn) - node_data[nid]->node_start_pfn) 73#define node_localnr(pfn, nid) ((pfn) - node_data[nid]->node_start_pfn)
72 74
73/* 75/*
@@ -79,7 +81,6 @@ static inline int pfn_to_nid(unsigned long pfn)
79 */ 81 */
80#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT) 82#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
81 83
82#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
83#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 84#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
84#define node_end_pfn(nid) \ 85#define node_end_pfn(nid) \
85({ \ 86({ \
@@ -100,7 +101,7 @@ static inline int pfn_to_nid(unsigned long pfn)
100({ \ 101({ \
101 unsigned long __pfn = pfn; \ 102 unsigned long __pfn = pfn; \
102 int __node = pfn_to_nid(__pfn); \ 103 int __node = pfn_to_nid(__pfn); \
103 &node_mem_map(__node)[node_localnr(__pfn,__node)]; \ 104 &NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)]; \
104}) 105})
105 106
106#define page_to_pfn(pg) \ 107#define page_to_pfn(pg) \
@@ -122,26 +123,34 @@ static inline int pfn_valid(int pfn)
122 return (pfn < node_end_pfn(nid)); 123 return (pfn < node_end_pfn(nid));
123 return 0; 124 return 0;
124} 125}
125#endif 126#endif /* CONFIG_X86_NUMAQ */
127
128#endif /* CONFIG_DISCONTIGMEM */
129
130#ifdef CONFIG_NEED_MULTIPLE_NODES
126 131
127extern int get_memcfg_numa_flat(void );
128/* 132/*
129 * This allows any one NUMA architecture to be compiled 133 * Following are macros that are specific to this numa platform.
130 * for, and still fall back to the flat function if it
131 * fails.
132 */ 134 */
133static inline void get_memcfg_numa(void) 135#define reserve_bootmem(addr, size) \
134{ 136 reserve_bootmem_node(NODE_DATA(0), (addr), (size))
135#ifdef CONFIG_X86_NUMAQ 137#define alloc_bootmem(x) \
136 if (get_memcfg_numaq()) 138 __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
137 return; 139#define alloc_bootmem_low(x) \
138#elif CONFIG_ACPI_SRAT 140 __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, 0)
139 if (get_memcfg_from_srat()) 141#define alloc_bootmem_pages(x) \
140 return; 142 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
141#endif 143#define alloc_bootmem_low_pages(x) \
144 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
145#define alloc_bootmem_node(ignore, x) \
146 __alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
147#define alloc_bootmem_pages_node(ignore, x) \
148 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
149#define alloc_bootmem_low_pages_node(ignore, x) \
150 __alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
142 151
143 get_memcfg_numa_flat(); 152#endif /* CONFIG_NEED_MULTIPLE_NODES */
144} 153
154extern int early_pfn_to_nid(unsigned long pfn);
145 155
146#endif /* CONFIG_DISCONTIGMEM */
147#endif /* _ASM_MMZONE_H_ */ 156#endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 41400d342d44..dea8f8e6d86e 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -120,6 +120,8 @@ static __inline__ int get_order(unsigned long size)
120 120
121extern int sysctl_legacy_va_layout; 121extern int sysctl_legacy_va_layout;
122 122
123extern int page_is_ram(unsigned long pagenr);
124
123#endif /* __ASSEMBLY__ */ 125#endif /* __ASSEMBLY__ */
124 126
125#ifdef __ASSEMBLY__ 127#ifdef __ASSEMBLY__
@@ -135,11 +137,11 @@ extern int sysctl_legacy_va_layout;
135#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) 137#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
136#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 138#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
137#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 139#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
138#ifndef CONFIG_DISCONTIGMEM 140#ifdef CONFIG_FLATMEM
139#define pfn_to_page(pfn) (mem_map + (pfn)) 141#define pfn_to_page(pfn) (mem_map + (pfn))
140#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) 142#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
141#define pfn_valid(pfn) ((pfn) < max_mapnr) 143#define pfn_valid(pfn) ((pfn) < max_mapnr)
142#endif /* !CONFIG_DISCONTIGMEM */ 144#endif /* CONFIG_FLATMEM */
143#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 145#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
144 146
145#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 147#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h
index b6440526e42a..fa02e67ea86b 100644
--- a/include/asm-i386/param.h
+++ b/include/asm-i386/param.h
@@ -1,8 +1,10 @@
1#include <linux/config.h>
2
1#ifndef _ASMi386_PARAM_H 3#ifndef _ASMi386_PARAM_H
2#define _ASMi386_PARAM_H 4#define _ASMi386_PARAM_H
3 5
4#ifdef __KERNEL__ 6#ifdef __KERNEL__
5# define HZ 1000 /* Internal kernel timer frequency */ 7# define HZ CONFIG_HZ /* Internal kernel timer frequency */
6# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ 8# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
7# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ 9# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
8#endif 10#endif
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index e9efe148fdf7..77c6497f416e 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -398,9 +398,9 @@ extern void noexec_setup(const char *str);
398 398
399#endif /* !__ASSEMBLY__ */ 399#endif /* !__ASSEMBLY__ */
400 400
401#ifndef CONFIG_DISCONTIGMEM 401#ifdef CONFIG_FLATMEM
402#define kern_addr_valid(addr) (1) 402#define kern_addr_valid(addr) (1)
403#endif /* !CONFIG_DISCONTIGMEM */ 403#endif /* CONFIG_FLATMEM */
404 404
405#define io_remap_page_range(vma, vaddr, paddr, size, prot) \ 405#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
406 remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) 406 remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 359bb0151742..c76c50e96225 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -501,12 +501,16 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa
501} while (0) 501} while (0)
502 502
503/* 503/*
504 * This special macro can be used to load a debugging register 504 * These special macros can be used to get or set a debugging register
505 */ 505 */
506#define loaddebug(thread,register) \ 506#define get_debugreg(var, register) \
507 __asm__("movl %0,%%db" #register \ 507 __asm__("movl %%db" #register ", %0" \
508 : /* no output */ \ 508 :"=r" (var))
509 :"r" ((thread)->debugreg[register])) 509#define set_debugreg(value, register) \
510 __asm__("movl %0,%%db" #register \
511 : /* no output */ \
512 :"r" (value))
513
510 514
511/* Forward declaration, a strange C thing */ 515/* Forward declaration, a strange C thing */
512struct task_struct; 516struct task_struct;
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
index 8618914b3521..eef9f93870d4 100644
--- a/include/asm-i386/ptrace.h
+++ b/include/asm-i386/ptrace.h
@@ -57,7 +57,8 @@ struct pt_regs {
57#ifdef __KERNEL__ 57#ifdef __KERNEL__
58struct task_struct; 58struct task_struct;
59extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); 59extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
60#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) 60#define user_mode(regs) (3 & (regs)->xcs)
61#define user_mode_vm(regs) ((VM_MASK & (regs)->eflags) || user_mode(regs))
61#define instruction_pointer(regs) ((regs)->eip) 62#define instruction_pointer(regs) ((regs)->eip)
62#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) 63#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
63extern unsigned long profile_pc(struct pt_regs *regs); 64extern unsigned long profile_pc(struct pt_regs *regs);
diff --git a/include/asm-i386/sparsemem.h b/include/asm-i386/sparsemem.h
new file mode 100644
index 000000000000..cfeed990585f
--- /dev/null
+++ b/include/asm-i386/sparsemem.h
@@ -0,0 +1,31 @@
1#ifndef _I386_SPARSEMEM_H
2#define _I386_SPARSEMEM_H
3#ifdef CONFIG_SPARSEMEM
4
5/*
6 * generic non-linear memory support:
7 *
8 * 1) we will not split memory into more chunks than will fit into the
9 * flags field of the struct page
10 */
11
12/*
13 * SECTION_SIZE_BITS 2^N: how big each section will be
14 * MAX_PHYSADDR_BITS 2^N: how much physical address space we have
15 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
16 */
17#ifdef CONFIG_X86_PAE
18#define SECTION_SIZE_BITS 30
19#define MAX_PHYSADDR_BITS 36
20#define MAX_PHYSMEM_BITS 36
21#else
22#define SECTION_SIZE_BITS 26
23#define MAX_PHYSADDR_BITS 32
24#define MAX_PHYSMEM_BITS 32
25#endif
26
27/* XXX: FIXME -- wli */
28#define kern_addr_valid(kaddr) (0)
29
30#endif /* CONFIG_SPARSEMEM */
31#endif /* _I386_SPARSEMEM_H */
diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h
index 6a78ac58c194..02c8f5d22065 100644
--- a/include/asm-i386/string.h
+++ b/include/asm-i386/string.h
@@ -116,7 +116,8 @@ __asm__ __volatile__(
116 "orb $1,%%al\n" 116 "orb $1,%%al\n"
117 "3:" 117 "3:"
118 :"=a" (__res), "=&S" (d0), "=&D" (d1) 118 :"=a" (__res), "=&S" (d0), "=&D" (d1)
119 :"1" (cs),"2" (ct)); 119 :"1" (cs),"2" (ct)
120 :"memory");
120return __res; 121return __res;
121} 122}
122 123
@@ -138,8 +139,9 @@ __asm__ __volatile__(
138 "3:\tsbbl %%eax,%%eax\n\t" 139 "3:\tsbbl %%eax,%%eax\n\t"
139 "orb $1,%%al\n" 140 "orb $1,%%al\n"
140 "4:" 141 "4:"
141 :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) 142 :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
142 :"1" (cs),"2" (ct),"3" (count)); 143 :"1" (cs),"2" (ct),"3" (count)
144 :"memory");
143return __res; 145return __res;
144} 146}
145 147
@@ -158,7 +160,9 @@ __asm__ __volatile__(
158 "movl $1,%1\n" 160 "movl $1,%1\n"
159 "2:\tmovl %1,%0\n\t" 161 "2:\tmovl %1,%0\n\t"
160 "decl %0" 162 "decl %0"
161 :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c)); 163 :"=a" (__res), "=&S" (d0)
164 :"1" (s),"0" (c)
165 :"memory");
162return __res; 166return __res;
163} 167}
164 168
@@ -175,7 +179,9 @@ __asm__ __volatile__(
175 "leal -1(%%esi),%0\n" 179 "leal -1(%%esi),%0\n"
176 "2:\ttestb %%al,%%al\n\t" 180 "2:\ttestb %%al,%%al\n\t"
177 "jne 1b" 181 "jne 1b"
178 :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); 182 :"=g" (__res), "=&S" (d0), "=&a" (d1)
183 :"0" (0),"1" (s),"2" (c)
184 :"memory");
179return __res; 185return __res;
180} 186}
181 187
@@ -189,7 +195,9 @@ __asm__ __volatile__(
189 "scasb\n\t" 195 "scasb\n\t"
190 "notl %0\n\t" 196 "notl %0\n\t"
191 "decl %0" 197 "decl %0"
192 :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffffu)); 198 :"=c" (__res), "=&D" (d0)
199 :"1" (s),"a" (0), "0" (0xffffffffu)
200 :"memory");
193return __res; 201return __res;
194} 202}
195 203
@@ -333,7 +341,9 @@ __asm__ __volatile__(
333 "je 1f\n\t" 341 "je 1f\n\t"
334 "movl $1,%0\n" 342 "movl $1,%0\n"
335 "1:\tdecl %0" 343 "1:\tdecl %0"
336 :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count)); 344 :"=D" (__res), "=&c" (d0)
345 :"a" (c),"0" (cs),"1" (count)
346 :"memory");
337return __res; 347return __res;
338} 348}
339 349
@@ -369,7 +379,7 @@ __asm__ __volatile__(
369 "je 2f\n\t" 379 "je 2f\n\t"
370 "stosb\n" 380 "stosb\n"
371 "2:" 381 "2:"
372 : "=&c" (d0), "=&D" (d1) 382 :"=&c" (d0), "=&D" (d1)
373 :"a" (c), "q" (count), "0" (count/4), "1" ((long) s) 383 :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
374 :"memory"); 384 :"memory");
375return (s); 385return (s);
@@ -392,7 +402,8 @@ __asm__ __volatile__(
392 "jne 1b\n" 402 "jne 1b\n"
393 "3:\tsubl %2,%0" 403 "3:\tsubl %2,%0"
394 :"=a" (__res), "=&d" (d0) 404 :"=a" (__res), "=&d" (d0)
395 :"c" (s),"1" (count)); 405 :"c" (s),"1" (count)
406 :"memory");
396return __res; 407return __res;
397} 408}
398/* end of additional stuff */ 409/* end of additional stuff */
@@ -473,7 +484,8 @@ static inline void * memscan(void * addr, int c, size_t size)
473 "dec %%edi\n" 484 "dec %%edi\n"
474 "1:" 485 "1:"
475 : "=D" (addr), "=c" (size) 486 : "=D" (addr), "=c" (size)
476 : "0" (addr), "1" (size), "a" (c)); 487 : "0" (addr), "1" (size), "a" (c)
488 : "memory");
477 return addr; 489 return addr;
478} 490}
479 491
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 2cd57271801d..95add81237ea 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -31,7 +31,7 @@ struct thread_info {
31 unsigned long flags; /* low level flags */ 31 unsigned long flags; /* low level flags */
32 unsigned long status; /* thread-synchronous flags */ 32 unsigned long status; /* thread-synchronous flags */
33 __u32 cpu; /* current CPU */ 33 __u32 cpu; /* current CPU */
34 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 34 int preempt_count; /* 0 => preemptable, <0 => BUG */
35 35
36 36
37 mm_segment_t addr_limit; /* thread address space: 37 mm_segment_t addr_limit; /* thread address space:
diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h
index c34709849839..dcf1e07db08a 100644
--- a/include/asm-i386/timer.h
+++ b/include/asm-i386/timer.h
@@ -22,6 +22,7 @@ struct timer_opts {
22 unsigned long (*get_offset)(void); 22 unsigned long (*get_offset)(void);
23 unsigned long long (*monotonic_clock)(void); 23 unsigned long long (*monotonic_clock)(void);
24 void (*delay)(unsigned long); 24 void (*delay)(unsigned long);
25 unsigned long (*read_timer)(void);
25}; 26};
26 27
27struct init_timer_opts { 28struct init_timer_opts {
@@ -52,6 +53,7 @@ extern struct init_timer_opts timer_cyclone_init;
52#endif 53#endif
53 54
54extern unsigned long calibrate_tsc(void); 55extern unsigned long calibrate_tsc(void);
56extern unsigned long read_timer_tsc(void);
55extern void init_cpu_khz(void); 57extern void init_cpu_khz(void);
56extern int recalibrate_cpu_khz(void); 58extern int recalibrate_cpu_khz(void);
57#ifdef CONFIG_HPET_TIMER 59#ifdef CONFIG_HPET_TIMER
diff --git a/include/asm-i386/timex.h b/include/asm-i386/timex.h
index b41e484c3445..292b5a68f627 100644
--- a/include/asm-i386/timex.h
+++ b/include/asm-i386/timex.h
@@ -47,6 +47,9 @@ static inline cycles_t get_cycles (void)
47 return ret; 47 return ret;
48} 48}
49 49
50extern unsigned long cpu_khz; 50extern unsigned int cpu_khz;
51
52extern int read_current_timer(unsigned long *timer_value);
53#define ARCH_HAS_READ_CURRENT_TIMER 1
51 54
52#endif 55#endif
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h
index 98f9e6850cba..6d0f67507b21 100644
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -60,12 +60,8 @@ static inline int node_to_first_cpu(int node)
60 return first_cpu(mask); 60 return first_cpu(mask);
61} 61}
62 62
63/* Returns the number of the node containing PCI bus number 'busnr' */ 63#define pcibus_to_node(bus) mp_bus_id_to_node[(bus)->number]
64static inline cpumask_t __pcibus_to_cpumask(int busnr) 64#define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus))
65{
66 return node_to_cpumask(mp_bus_id_to_node[busnr]);
67}
68#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus->number)
69 65
70/* sched_domains SD_NODE_INIT for NUMAQ machines */ 66/* sched_domains SD_NODE_INIT for NUMAQ machines */
71#define SD_NODE_INIT (struct sched_domain) { \ 67#define SD_NODE_INIT (struct sched_domain) { \
diff --git a/include/asm-ia64/break.h b/include/asm-ia64/break.h
index 97c7b2d79600..8167828edc4b 100644
--- a/include/asm-ia64/break.h
+++ b/include/asm-ia64/break.h
@@ -12,6 +12,8 @@
12 * OS-specific debug break numbers: 12 * OS-specific debug break numbers:
13 */ 13 */
14#define __IA64_BREAK_KDB 0x80100 14#define __IA64_BREAK_KDB 0x80100
15#define __IA64_BREAK_KPROBE 0x80200
16#define __IA64_BREAK_JPROBE 0x80300
15 17
16/* 18/*
17 * OS-specific break numbers: 19 * OS-specific break numbers:
diff --git a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h
index cc0ff0a4bdd0..0c05e5bad8a0 100644
--- a/include/asm-ia64/compat.h
+++ b/include/asm-ia64/compat.h
@@ -27,6 +27,7 @@ typedef u16 compat_ipc_pid_t;
27typedef s32 compat_daddr_t; 27typedef s32 compat_daddr_t;
28typedef u32 compat_caddr_t; 28typedef u32 compat_caddr_t;
29typedef __kernel_fsid_t compat_fsid_t; 29typedef __kernel_fsid_t compat_fsid_t;
30typedef s32 compat_timer_t;
30 31
31typedef s32 compat_int_t; 32typedef s32 compat_int_t;
32typedef s32 compat_long_t; 33typedef s32 compat_long_t;
diff --git a/include/asm-ia64/fcntl.h b/include/asm-ia64/fcntl.h
index d193981bb1d8..c9f8d835d0cc 100644
--- a/include/asm-ia64/fcntl.h
+++ b/include/asm-ia64/fcntl.h
@@ -81,4 +81,6 @@ struct flock {
81 81
82#define F_LINUX_SPECIFIC_BASE 1024 82#define F_LINUX_SPECIFIC_BASE 1024
83 83
84#define force_o_largefile() ( ! (current->personality & PER_LINUX32) )
85
84#endif /* _ASM_IA64_FCNTL_H */ 86#endif /* _ASM_IA64_FCNTL_H */
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
new file mode 100644
index 000000000000..4d376e1663f7
--- /dev/null
+++ b/include/asm-ia64/kdebug.h
@@ -0,0 +1,61 @@
1#ifndef _IA64_KDEBUG_H
2#define _IA64_KDEBUG_H 1
3/*
4 * include/asm-ia64/kdebug.h
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 * Copyright (C) Intel Corporation, 2005
21 *
22 * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
23 * <anil.s.keshavamurthy@intel.com> adopted from
24 * include/asm-x86_64/kdebug.h
25 */
26#include <linux/notifier.h>
27
28struct pt_regs;
29
30struct die_args {
31 struct pt_regs *regs;
32 const char *str;
33 long err;
34 int trapnr;
35 int signr;
36};
37
38int register_die_notifier(struct notifier_block *nb);
39extern struct notifier_block *ia64die_chain;
40
41enum die_val {
42 DIE_BREAK = 1,
43 DIE_SS,
44 DIE_PAGE_FAULT,
45};
46
47static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
48 long err, int trap, int sig)
49{
50 struct die_args args = {
51 .regs = regs,
52 .str = str,
53 .err = err,
54 .trapnr = trap,
55 .signr = sig
56 };
57
58 return notifier_call_chain(&ia64die_chain, val, &args);
59}
60
61#endif
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
new file mode 100644
index 000000000000..7b700035e36d
--- /dev/null
+++ b/include/asm-ia64/kprobes.h
@@ -0,0 +1,116 @@
1#ifndef _ASM_KPROBES_H
2#define _ASM_KPROBES_H
3/*
4 * Kernel Probes (KProbes)
5 * include/asm-ia64/kprobes.h
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * Copyright (C) IBM Corporation, 2002, 2004
22 * Copyright (C) Intel Corporation, 2005
23 *
24 * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
25 * <anil.s.keshavamurthy@intel.com> adapted from i386
26 */
27#include <linux/types.h>
28#include <linux/ptrace.h>
29#include <asm/break.h>
30
31#define BREAK_INST (long)(__IA64_BREAK_KPROBE << 6)
32
33typedef union cmp_inst {
34 struct {
35 unsigned long long qp : 6;
36 unsigned long long p1 : 6;
37 unsigned long long c : 1;
38 unsigned long long r2 : 7;
39 unsigned long long r3 : 7;
40 unsigned long long p2 : 6;
41 unsigned long long ta : 1;
42 unsigned long long x2 : 2;
43 unsigned long long tb : 1;
44 unsigned long long opcode : 4;
45 unsigned long long reserved : 23;
46 }f;
47 unsigned long long l;
48} cmp_inst_t;
49
50struct kprobe;
51
52typedef struct _bundle {
53 struct {
54 unsigned long long template : 5;
55 unsigned long long slot0 : 41;
56 unsigned long long slot1_p0 : 64-46;
57 } quad0;
58 struct {
59 unsigned long long slot1_p1 : 41 - (64-46);
60 unsigned long long slot2 : 41;
61 } quad1;
62} __attribute__((__aligned__(16))) bundle_t;
63
64#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
65
66#define SLOT0_OPCODE_SHIFT (37)
67#define SLOT1_p1_OPCODE_SHIFT (37 - (64-46))
68#define SLOT2_OPCODE_SHIFT (37)
69
70#define INDIRECT_CALL_OPCODE (1)
71#define IP_RELATIVE_CALL_OPCODE (5)
72#define IP_RELATIVE_BRANCH_OPCODE (4)
73#define IP_RELATIVE_PREDICT_OPCODE (7)
74#define LONG_BRANCH_OPCODE (0xC)
75#define LONG_CALL_OPCODE (0xD)
76
77typedef struct kprobe_opcode {
78 bundle_t bundle;
79} kprobe_opcode_t;
80
81struct fnptr {
82 unsigned long ip;
83 unsigned long gp;
84};
85
86/* Architecture specific copy of original instruction*/
87struct arch_specific_insn {
88 /* copy of the instruction to be emulated */
89 kprobe_opcode_t insn;
90 #define INST_FLAG_FIX_RELATIVE_IP_ADDR 1
91 #define INST_FLAG_FIX_BRANCH_REG 2
92 unsigned long inst_flag;
93 unsigned short target_br_reg;
94};
95
96/* ia64 does not need this */
97static inline void jprobe_return(void)
98{
99}
100
101/* ia64 does not need this */
102static inline void arch_copy_kprobe(struct kprobe *p)
103{
104}
105
106#ifdef CONFIG_KPROBES
107extern int kprobe_exceptions_notify(struct notifier_block *self,
108 unsigned long val, void *data);
109#else /* !CONFIG_KPROBES */
110static inline int kprobe_exceptions_notify(struct notifier_block *self,
111 unsigned long val, void *data)
112{
113 return 0;
114}
115#endif
116#endif /* _ASM_KPROBES_H */
diff --git a/include/asm-ia64/mmzone.h b/include/asm-ia64/mmzone.h
index 83ca4043fc11..d32f51e3d6c2 100644
--- a/include/asm-ia64/mmzone.h
+++ b/include/asm-ia64/mmzone.h
@@ -15,6 +15,8 @@
15#include <asm/page.h> 15#include <asm/page.h>
16#include <asm/meminit.h> 16#include <asm/meminit.h>
17 17
18#ifdef CONFIG_DISCONTIGMEM
19
18static inline int pfn_to_nid(unsigned long pfn) 20static inline int pfn_to_nid(unsigned long pfn)
19{ 21{
20#ifdef CONFIG_NUMA 22#ifdef CONFIG_NUMA
@@ -29,8 +31,6 @@ static inline int pfn_to_nid(unsigned long pfn)
29#endif 31#endif
30} 32}
31 33
32#ifdef CONFIG_DISCONTIGMEM
33
34#ifdef CONFIG_IA64_DIG /* DIG systems are small */ 34#ifdef CONFIG_IA64_DIG /* DIG systems are small */
35# define MAX_PHYSNODE_ID 8 35# define MAX_PHYSNODE_ID 8
36# define NR_NODE_MEMBLKS (MAX_NUMNODES * 8) 36# define NR_NODE_MEMBLKS (MAX_NUMNODES * 8)
diff --git a/include/asm-ia64/param.h b/include/asm-ia64/param.h
index 6c6b679b7a9e..5e1e0d2d7baf 100644
--- a/include/asm-ia64/param.h
+++ b/include/asm-ia64/param.h
@@ -27,7 +27,7 @@
27 */ 27 */
28# define HZ 32 28# define HZ 32
29# else 29# else
30# define HZ 1024 30# define HZ CONFIG_HZ
31# endif 31# endif
32# define USER_HZ HZ 32# define USER_HZ HZ
33# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */ 33# define CLOCKS_PER_SEC HZ /* frequency at which times() counts */
diff --git a/include/asm-ia64/percpu.h b/include/asm-ia64/percpu.h
index 1e87f19dad56..2b14dee29ce7 100644
--- a/include/asm-ia64/percpu.h
+++ b/include/asm-ia64/percpu.h
@@ -50,7 +50,7 @@ extern void *per_cpu_init(void);
50 50
51#else /* ! SMP */ 51#else /* ! SMP */
52 52
53#define per_cpu(var, cpu) (*((void)cpu, &per_cpu__##var)) 53#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
54#define __get_cpu_var(var) per_cpu__##var 54#define __get_cpu_var(var) per_cpu__##var
55#define per_cpu_init() (__phys_per_cpu_start) 55#define per_cpu_init() (__phys_per_cpu_start)
56 56
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
index 8d5b7e77028c..7dc8951708a3 100644
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -25,7 +25,7 @@ struct thread_info {
25 __u32 flags; /* thread_info flags (see TIF_*) */ 25 __u32 flags; /* thread_info flags (see TIF_*) */
26 __u32 cpu; /* current CPU */ 26 __u32 cpu; /* current CPU */
27 mm_segment_t addr_limit; /* user-level address space limit */ 27 mm_segment_t addr_limit; /* user-level address space limit */
28 __s32 preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ 28 int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
29 struct restart_block restart_block; 29 struct restart_block restart_block;
30 struct { 30 struct {
31 int signo; 31 int signo;
diff --git a/include/asm-m32r/mmzone.h b/include/asm-m32r/mmzone.h
index ebf0228fec42..d58878ec899e 100644
--- a/include/asm-m32r/mmzone.h
+++ b/include/asm-m32r/mmzone.h
@@ -14,7 +14,6 @@ extern struct pglist_data *node_data[];
14#define NODE_DATA(nid) (node_data[nid]) 14#define NODE_DATA(nid) (node_data[nid])
15 15
16#define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn) 16#define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn)
17#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
18#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 17#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
19#define node_end_pfn(nid) \ 18#define node_end_pfn(nid) \
20({ \ 19({ \
@@ -32,7 +31,7 @@ extern struct pglist_data *node_data[];
32({ \ 31({ \
33 unsigned long __pfn = pfn; \ 32 unsigned long __pfn = pfn; \
34 int __node = pfn_to_nid(__pfn); \ 33 int __node = pfn_to_nid(__pfn); \
35 &node_mem_map(__node)[node_localnr(__pfn,__node)]; \ 34 &NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)]; \
36}) 35})
37 36
38#define page_to_pfn(pg) \ 37#define page_to_pfn(pg) \
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
index 9f3a0fcf6e2b..7a6be7727a92 100644
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -28,7 +28,7 @@ struct thread_info {
28 unsigned long flags; /* low level flags */ 28 unsigned long flags; /* low level flags */
29 unsigned long status; /* thread-synchronous flags */ 29 unsigned long status; /* thread-synchronous flags */
30 __u32 cpu; /* current CPU */ 30 __u32 cpu; /* current CPU */
31 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 31 int preempt_count; /* 0 => preemptable, <0 => BUG */
32 32
33 mm_segment_t addr_limit; /* thread address space: 33 mm_segment_t addr_limit; /* thread address space:
34 0-0xBFFFFFFF for user-thread 34 0-0xBFFFFFFF for user-thread
diff --git a/include/asm-m32r/topology.h b/include/asm-m32r/topology.h
index 299a89d91bde..d607eb32bd7e 100644
--- a/include/asm-m32r/topology.h
+++ b/include/asm-m32r/topology.h
@@ -1,48 +1,6 @@
1/*
2 * linux/include/asm-generic/topology.h
3 *
4 * Written by: Matthew Dobson, IBM Corporation
5 *
6 * Copyright (C) 2002, IBM Corp.
7 *
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
18 * NON INFRINGEMENT. See the GNU General Public License for more
19 * details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Send feedback to <colpatch@us.ibm.com>
26 */
27#ifndef _ASM_M32R_TOPOLOGY_H 1#ifndef _ASM_M32R_TOPOLOGY_H
28#define _ASM_M32R_TOPOLOGY_H 2#define _ASM_M32R_TOPOLOGY_H
29 3
30/* Other architectures wishing to use this simple topology API should fill 4#include <asm-generic/topology.h>
31 in the below functions as appropriate in their own <asm/topology.h> file. */
32
33#define cpu_to_node(cpu) (0)
34
35#ifndef parent_node
36#define parent_node(node) (0)
37#endif
38#ifndef node_to_cpumask
39#define node_to_cpumask(node) (cpu_online_map)
40#endif
41#ifndef node_to_first_cpu
42#define node_to_first_cpu(node) (0)
43#endif
44#ifndef pcibus_to_cpumask
45#define pcibus_to_cpumask(bus) (cpu_online_map)
46#endif
47 5
48#endif /* _ASM_M32R_TOPOLOGY_H */ 6#endif /* _ASM_M32R_TOPOLOGY_H */
diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
index 5f58939c59db..2aed24f6fd2e 100644
--- a/include/asm-m68k/thread_info.h
+++ b/include/asm-m68k/thread_info.h
@@ -8,7 +8,7 @@
8struct thread_info { 8struct thread_info {
9 struct task_struct *task; /* main task structure */ 9 struct task_struct *task; /* main task structure */
10 struct exec_domain *exec_domain; /* execution domain */ 10 struct exec_domain *exec_domain; /* execution domain */
11 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 11 int preempt_count; /* 0 => preemptable, <0 => BUG */
12 __u32 cpu; /* should always be 0 on m68k */ 12 __u32 cpu; /* should always be 0 on m68k */
13 struct restart_block restart_block; 13 struct restart_block restart_block;
14 14
diff --git a/include/asm-m68knommu/thread_info.h b/include/asm-m68knommu/thread_info.h
index c8153b7c1f5c..7b9a3fa3af5d 100644
--- a/include/asm-m68knommu/thread_info.h
+++ b/include/asm-m68knommu/thread_info.h
@@ -36,7 +36,7 @@ struct thread_info {
36 struct exec_domain *exec_domain; /* execution domain */ 36 struct exec_domain *exec_domain; /* execution domain */
37 unsigned long flags; /* low level flags */ 37 unsigned long flags; /* low level flags */
38 int cpu; /* cpu we're on */ 38 int cpu; /* cpu we're on */
39 int preempt_count; /* 0 => preemptable, <0 => BUG*/ 39 int preempt_count; /* 0 => preemptable, <0 => BUG */
40 struct restart_block restart_block; 40 struct restart_block restart_block;
41}; 41};
42 42
diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
index dce92079e7fc..d78002afb1e1 100644
--- a/include/asm-mips/compat.h
+++ b/include/asm-mips/compat.h
@@ -29,6 +29,7 @@ typedef s32 compat_caddr_t;
29typedef struct { 29typedef struct {
30 s32 val[2]; 30 s32 val[2];
31} compat_fsid_t; 31} compat_fsid_t;
32typedef s32 compat_timer_t;
32 33
33typedef s32 compat_int_t; 34typedef s32 compat_int_t;
34typedef s32 compat_long_t; 35typedef s32 compat_long_t;
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index 768900305e2f..42fcd6f2c206 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -27,7 +27,7 @@ struct thread_info {
27 struct exec_domain *exec_domain; /* execution domain */ 27 struct exec_domain *exec_domain; /* execution domain */
28 unsigned long flags; /* low level flags */ 28 unsigned long flags; /* low level flags */
29 __u32 cpu; /* current CPU */ 29 __u32 cpu; /* current CPU */
30 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 30 int preempt_count; /* 0 => preemptable, <0 => BUG */
31 31
32 mm_segment_t addr_limit; /* thread address space: 32 mm_segment_t addr_limit; /* thread address space:
33 0-0xBFFFFFFF for user-thead 33 0-0xBFFFFFFF for user-thead
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
index ca0eac647a05..7630d1ad2391 100644
--- a/include/asm-parisc/compat.h
+++ b/include/asm-parisc/compat.h
@@ -24,7 +24,7 @@ typedef u16 compat_nlink_t;
24typedef u16 compat_ipc_pid_t; 24typedef u16 compat_ipc_pid_t;
25typedef s32 compat_daddr_t; 25typedef s32 compat_daddr_t;
26typedef u32 compat_caddr_t; 26typedef u32 compat_caddr_t;
27typedef u32 compat_timer_t; 27typedef s32 compat_timer_t;
28 28
29typedef s32 compat_int_t; 29typedef s32 compat_int_t;
30typedef s32 compat_long_t; 30typedef s32 compat_long_t;
diff --git a/include/asm-parisc/mmzone.h b/include/asm-parisc/mmzone.h
index 928bf50c4693..595d3dce120a 100644
--- a/include/asm-parisc/mmzone.h
+++ b/include/asm-parisc/mmzone.h
@@ -19,7 +19,6 @@ extern struct node_map_data node_data[];
19 */ 19 */
20#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT) 20#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
21 21
22#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
23#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 22#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
24#define node_end_pfn(nid) \ 23#define node_end_pfn(nid) \
25({ \ 24({ \
@@ -38,7 +37,7 @@ extern struct node_map_data node_data[];
38({ \ 37({ \
39 unsigned long __pfn = (pfn); \ 38 unsigned long __pfn = (pfn); \
40 int __node = pfn_to_nid(__pfn); \ 39 int __node = pfn_to_nid(__pfn); \
41 &node_mem_map(__node)[node_localnr(__pfn,__node)]; \ 40 &NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)]; \
42}) 41})
43 42
44#define page_to_pfn(pg) \ 43#define page_to_pfn(pg) \
diff --git a/include/asm-parisc/thread_info.h b/include/asm-parisc/thread_info.h
index fe9b7f8ae4c6..57bbb76cb6c1 100644
--- a/include/asm-parisc/thread_info.h
+++ b/include/asm-parisc/thread_info.h
@@ -12,7 +12,7 @@ struct thread_info {
12 unsigned long flags; /* thread_info flags (see TIF_*) */ 12 unsigned long flags; /* thread_info flags (see TIF_*) */
13 mm_segment_t addr_limit; /* user-level address space limit */ 13 mm_segment_t addr_limit; /* user-level address space limit */
14 __u32 cpu; /* current CPU */ 14 __u32 cpu; /* current CPU */
15 __s32 preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ 15 int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
16 struct restart_block restart_block; 16 struct restart_block restart_block;
17}; 17};
18 18
diff --git a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h
index e3b5284a6f91..27903db42efc 100644
--- a/include/asm-ppc/thread_info.h
+++ b/include/asm-ppc/thread_info.h
@@ -20,7 +20,8 @@ struct thread_info {
20 unsigned long flags; /* low level flags */ 20 unsigned long flags; /* low level flags */
21 unsigned long local_flags; /* non-racy flags */ 21 unsigned long local_flags; /* non-racy flags */
22 int cpu; /* cpu we're on */ 22 int cpu; /* cpu we're on */
23 int preempt_count; 23 int preempt_count; /* 0 => preemptable,
24 <0 => BUG */
24 struct restart_block restart_block; 25 struct restart_block restart_block;
25}; 26};
26 27
diff --git a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
index 09c28d28ce6c..12414f5fc666 100644
--- a/include/asm-ppc64/compat.h
+++ b/include/asm-ppc64/compat.h
@@ -26,6 +26,7 @@ typedef s32 compat_daddr_t;
26typedef u32 compat_caddr_t; 26typedef u32 compat_caddr_t;
27typedef __kernel_fsid_t compat_fsid_t; 27typedef __kernel_fsid_t compat_fsid_t;
28typedef s32 compat_key_t; 28typedef s32 compat_key_t;
29typedef s32 compat_timer_t;
29 30
30typedef s32 compat_int_t; 31typedef s32 compat_int_t;
31typedef s32 compat_long_t; 32typedef s32 compat_long_t;
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
index 5d3cd9d042e2..553b2ea23bed 100644
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-ppc64/machdep.h
@@ -76,6 +76,7 @@ struct machdep_calls {
76 void (*tce_flush)(struct iommu_table *tbl); 76 void (*tce_flush)(struct iommu_table *tbl);
77 void (*iommu_dev_setup)(struct pci_dev *dev); 77 void (*iommu_dev_setup)(struct pci_dev *dev);
78 void (*iommu_bus_setup)(struct pci_bus *bus); 78 void (*iommu_bus_setup)(struct pci_bus *bus);
79 void (*irq_bus_setup)(struct pci_bus *bus);
79 80
80 int (*probe)(int platform); 81 int (*probe)(int platform);
81 void (*setup_arch)(void); 82 void (*setup_arch)(void);
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
index c78282a67d8e..9d03a98a4fa3 100644
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -47,9 +47,10 @@
47#define SLB_VSID_KS ASM_CONST(0x0000000000000800) 47#define SLB_VSID_KS ASM_CONST(0x0000000000000800)
48#define SLB_VSID_KP ASM_CONST(0x0000000000000400) 48#define SLB_VSID_KP ASM_CONST(0x0000000000000400)
49#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */ 49#define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */
50#define SLB_VSID_L ASM_CONST(0x0000000000000100) /* largepage 16M */ 50#define SLB_VSID_L ASM_CONST(0x0000000000000100) /* largepage */
51#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */ 51#define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */
52 52#define SLB_VSID_LS ASM_CONST(0x0000000000000070) /* size of largepage */
53
53#define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C) 54#define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C)
54#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS) 55#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS)
55 56
diff --git a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
index 0619a41a3c9d..ed473f4b0152 100644
--- a/include/asm-ppc64/mmzone.h
+++ b/include/asm-ppc64/mmzone.h
@@ -10,9 +10,20 @@
10#include <linux/config.h> 10#include <linux/config.h>
11#include <asm/smp.h> 11#include <asm/smp.h>
12 12
13#ifdef CONFIG_DISCONTIGMEM 13/* generic non-linear memory support:
14 *
15 * 1) we will not split memory into more chunks than will fit into the
16 * flags field of the struct page
17 */
18
19
20#ifdef CONFIG_NEED_MULTIPLE_NODES
14 21
15extern struct pglist_data *node_data[]; 22extern struct pglist_data *node_data[];
23/*
24 * Return a pointer to the node data for node n.
25 */
26#define NODE_DATA(nid) (node_data[nid])
16 27
17/* 28/*
18 * Following are specific to this numa platform. 29 * Following are specific to this numa platform.
@@ -47,36 +58,32 @@ static inline int pa_to_nid(unsigned long pa)
47 return nid; 58 return nid;
48} 59}
49 60
50#define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT)
51
52/*
53 * Return a pointer to the node data for node n.
54 */
55#define NODE_DATA(nid) (node_data[nid])
56
57#define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn) 61#define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn)
58 62
59/* 63/*
60 * Following are macros that each numa implmentation must define. 64 * Following are macros that each numa implmentation must define.
61 */ 65 */
62 66
63/*
64 * Given a kernel address, find the home node of the underlying memory.
65 */
66#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
67
68#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
69#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 67#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
70#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn) 68#define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn)
71 69
72#define local_mapnr(kvaddr) \ 70#define local_mapnr(kvaddr) \
73 ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) 71 ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr))
74 72
73#ifdef CONFIG_DISCONTIGMEM
74
75/*
76 * Given a kernel address, find the home node of the underlying memory.
77 */
78#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
79
80#define pfn_to_nid(pfn) pa_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
81
75/* Written this way to avoid evaluating arguments twice */ 82/* Written this way to avoid evaluating arguments twice */
76#define discontigmem_pfn_to_page(pfn) \ 83#define discontigmem_pfn_to_page(pfn) \
77({ \ 84({ \
78 unsigned long __tmp = pfn; \ 85 unsigned long __tmp = pfn; \
79 (node_mem_map(pfn_to_nid(__tmp)) + \ 86 (NODE_DATA(pfn_to_nid(__tmp))->node_mem_map + \
80 node_localnr(__tmp, pfn_to_nid(__tmp))); \ 87 node_localnr(__tmp, pfn_to_nid(__tmp))); \
81}) 88})
82 89
@@ -91,4 +98,11 @@ static inline int pa_to_nid(unsigned long pa)
91#define discontigmem_pfn_valid(pfn) ((pfn) < num_physpages) 98#define discontigmem_pfn_valid(pfn) ((pfn) < num_physpages)
92 99
93#endif /* CONFIG_DISCONTIGMEM */ 100#endif /* CONFIG_DISCONTIGMEM */
101
102#endif /* CONFIG_NEED_MULTIPLE_NODES */
103
104#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
105#define early_pfn_to_nid(pfn) pa_to_nid(((unsigned long)pfn) << PAGE_SHIFT)
106#endif
107
94#endif /* _ASM_MMZONE_H_ */ 108#endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-ppc64/nvram.h b/include/asm-ppc64/nvram.h
index 4e6dd370d936..dfaa21566c9a 100644
--- a/include/asm-ppc64/nvram.h
+++ b/include/asm-ppc64/nvram.h
@@ -70,6 +70,7 @@ extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
70 70
71extern int pSeries_nvram_init(void); 71extern int pSeries_nvram_init(void);
72extern int pmac_nvram_init(void); 72extern int pmac_nvram_init(void);
73extern int bpa_nvram_init(void);
73 74
74/* PowerMac specific nvram stuffs */ 75/* PowerMac specific nvram stuffs */
75 76
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
index 257d87eb7c34..a5893a305a09 100644
--- a/include/asm-ppc64/page.h
+++ b/include/asm-ppc64/page.h
@@ -217,7 +217,8 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */
217#define page_to_pfn(page) discontigmem_page_to_pfn(page) 217#define page_to_pfn(page) discontigmem_page_to_pfn(page)
218#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn) 218#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
219#define pfn_valid(pfn) discontigmem_pfn_valid(pfn) 219#define pfn_valid(pfn) discontigmem_pfn_valid(pfn)
220#else 220#endif
221#ifdef CONFIG_FLATMEM
221#define pfn_to_page(pfn) (mem_map + (pfn)) 222#define pfn_to_page(pfn) (mem_map + (pfn))
222#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) 223#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
223#define pfn_valid(pfn) ((pfn) < max_mapnr) 224#define pfn_valid(pfn) ((pfn) < max_mapnr)
diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h
index 1d0404897550..6b44a8caf395 100644
--- a/include/asm-ppc64/ppc32.h
+++ b/include/asm-ppc64/ppc32.h
@@ -32,7 +32,7 @@ typedef struct compat_siginfo {
32 32
33 /* POSIX.1b timers */ 33 /* POSIX.1b timers */
34 struct { 34 struct {
35 timer_t _tid; /* timer id */ 35 compat_timer_t _tid; /* timer id */
36 int _overrun; /* overrun count */ 36 int _overrun; /* overrun count */
37 compat_sigval_t _sigval; /* same as below */ 37 compat_sigval_t _sigval; /* same as below */
38 int _sys_private; /* not to be passed to user */ 38 int _sys_private; /* not to be passed to user */
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index 3084099086a8..af28aa55d8c1 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -138,8 +138,16 @@
138#define SPRN_NIADORM 0x3F3 /* Hardware Implementation Register 2 */ 138#define SPRN_NIADORM 0x3F3 /* Hardware Implementation Register 2 */
139#define SPRN_HID4 0x3F4 /* 970 HID4 */ 139#define SPRN_HID4 0x3F4 /* 970 HID4 */
140#define SPRN_HID5 0x3F6 /* 970 HID5 */ 140#define SPRN_HID5 0x3F6 /* 970 HID5 */
141#define SPRN_TSC 0x3FD /* Thread switch control */ 141#define SPRN_HID6 0x3F9 /* BE HID 6 */
142#define SPRN_TST 0x3FC /* Thread switch timeout */ 142#define HID6_LB (0x0F<<12) /* Concurrent Large Page Modes */
143#define HID6_DLP (1<<20) /* Disable all large page modes (4K only) */
144#define SPRN_TSCR 0x399 /* Thread switch control on BE */
145#define SPRN_TTR 0x39A /* Thread switch timeout on BE */
146#define TSCR_DEC_ENABLE 0x200000 /* Decrementer Interrupt */
147#define TSCR_EE_ENABLE 0x100000 /* External Interrupt */
148#define TSCR_EE_BOOST 0x080000 /* External Interrupt Boost */
149#define SPRN_TSC 0x3FD /* Thread switch control on others */
150#define SPRN_TST 0x3FC /* Thread switch timeout on others */
143#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ 151#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */
144#define SPRN_LR 0x008 /* Link Register */ 152#define SPRN_LR 0x008 /* Link Register */
145#define SPRN_PIR 0x3FF /* Processor Identification Register */ 153#define SPRN_PIR 0x3FF /* Processor Identification Register */
@@ -259,6 +267,7 @@
259#define PV_970FX 0x003C 267#define PV_970FX 0x003C
260#define PV_630 0x0040 268#define PV_630 0x0040
261#define PV_630p 0x0041 269#define PV_630p 0x0041
270#define PV_BE 0x0070
262 271
263/* Platforms supported by PPC64 */ 272/* Platforms supported by PPC64 */
264#define PLATFORM_PSERIES 0x0100 273#define PLATFORM_PSERIES 0x0100
@@ -267,6 +276,7 @@
267#define PLATFORM_LPAR 0x0001 276#define PLATFORM_LPAR 0x0001
268#define PLATFORM_POWERMAC 0x0400 277#define PLATFORM_POWERMAC 0x0400
269#define PLATFORM_MAPLE 0x0500 278#define PLATFORM_MAPLE 0x0500
279#define PLATFORM_BPA 0x1000
270 280
271/* Compatibility with drivers coming from PPC32 world */ 281/* Compatibility with drivers coming from PPC32 world */
272#define _machine (systemcfg->platform) 282#define _machine (systemcfg->platform)
@@ -278,6 +288,7 @@
278#define IC_INVALID 0 288#define IC_INVALID 0
279#define IC_OPEN_PIC 1 289#define IC_OPEN_PIC 1
280#define IC_PPC_XIC 2 290#define IC_PPC_XIC 2
291#define IC_BPA_IIC 3
281 292
282#define XGLUE(a,b) a##b 293#define XGLUE(a,b) a##b
283#define GLUE(a,b) XGLUE(a,b) 294#define GLUE(a,b) XGLUE(a,b)
diff --git a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
index a8ab0e9db84a..e7d1b5222802 100644
--- a/include/asm-ppc64/rtas.h
+++ b/include/asm-ppc64/rtas.h
@@ -186,8 +186,14 @@ extern int rtas_get_sensor(int sensor, int index, int *state);
186extern int rtas_get_power_level(int powerdomain, int *level); 186extern int rtas_get_power_level(int powerdomain, int *level);
187extern int rtas_set_power_level(int powerdomain, int level, int *setlevel); 187extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
188extern int rtas_set_indicator(int indicator, int index, int new_value); 188extern int rtas_set_indicator(int indicator, int index, int new_value);
189extern void rtas_progress(char *s, unsigned short hex);
189extern void rtas_initialize(void); 190extern void rtas_initialize(void);
190 191
192struct rtc_time;
193extern void rtas_get_boot_time(struct rtc_time *rtc_time);
194extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
195extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
196
191/* Given an RTAS status code of 9900..9905 compute the hinted delay */ 197/* Given an RTAS status code of 9900..9905 compute the hinted delay */
192unsigned int rtas_extended_busy_delay_time(int status); 198unsigned int rtas_extended_busy_delay_time(int status);
193static inline int rtas_is_extended_busy(int status) 199static inline int rtas_is_extended_busy(int status)
diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
index 8115ecb8feee..d86f742e9a21 100644
--- a/include/asm-ppc64/smp.h
+++ b/include/asm-ppc64/smp.h
@@ -85,6 +85,14 @@ extern void smp_generic_take_timebase(void);
85 85
86extern struct smp_ops_t *smp_ops; 86extern struct smp_ops_t *smp_ops;
87 87
88#ifdef CONFIG_PPC_PSERIES
89void vpa_init(int cpu);
90#else
91static inline void vpa_init(int cpu)
92{
93}
94#endif /* CONFIG_PPC_PSERIES */
95
88#endif /* __ASSEMBLY__ */ 96#endif /* __ASSEMBLY__ */
89 97
90#endif /* !(_PPC64_SMP_H) */ 98#endif /* !(_PPC64_SMP_H) */
diff --git a/include/asm-ppc64/sparsemem.h b/include/asm-ppc64/sparsemem.h
new file mode 100644
index 000000000000..c5bd47e57f17
--- /dev/null
+++ b/include/asm-ppc64/sparsemem.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_PPC64_SPARSEMEM_H
2#define _ASM_PPC64_SPARSEMEM_H 1
3
4#ifdef CONFIG_SPARSEMEM
5/*
6 * SECTION_SIZE_BITS 2^N: how big each section will be
7 * MAX_PHYSADDR_BITS 2^N: how much physical address space we have
8 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
9 */
10#define SECTION_SIZE_BITS 24
11#define MAX_PHYSADDR_BITS 38
12#define MAX_PHYSMEM_BITS 36
13
14#endif /* CONFIG_SPARSEMEM */
15
16#endif /* _ASM_PPC64_SPARSEMEM_H */
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
index 48b7900e90ec..0494df6fca74 100644
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-ppc64/thread_info.h
@@ -24,7 +24,7 @@ struct thread_info {
24 struct task_struct *task; /* main task structure */ 24 struct task_struct *task; /* main task structure */
25 struct exec_domain *exec_domain; /* execution domain */ 25 struct exec_domain *exec_domain; /* execution domain */
26 int cpu; /* cpu we're on */ 26 int cpu; /* cpu we're on */
27 int preempt_count; 27 int preempt_count; /* 0 => preemptable, <0 => BUG */
28 struct restart_block restart_block; 28 struct restart_block restart_block;
29 /* set by force_successful_syscall_return */ 29 /* set by force_successful_syscall_return */
30 unsigned char syscall_noerror; 30 unsigned char syscall_noerror;
diff --git a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
index 8d6e3760ee10..c6c762cad8b0 100644
--- a/include/asm-ppc64/time.h
+++ b/include/asm-ppc64/time.h
@@ -34,6 +34,15 @@ struct rtc_time;
34extern void to_tm(int tim, struct rtc_time * tm); 34extern void to_tm(int tim, struct rtc_time * tm);
35extern time_t last_rtc_update; 35extern time_t last_rtc_update;
36 36
37void generic_calibrate_decr(void);
38void setup_default_decr(void);
39
40/* Some sane defaults: 125 MHz timebase, 1GHz processor */
41extern unsigned long ppc_proc_freq;
42#define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8)
43extern unsigned long ppc_tb_freq;
44#define DEFAULT_TB_FREQ 125000000UL
45
37/* 46/*
38 * By putting all of this stuff into a single struct we 47 * By putting all of this stuff into a single struct we
39 * reduce the number of cache lines touched by do_gettimeofday. 48 * reduce the number of cache lines touched by do_gettimeofday.
diff --git a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h
index d58d9dd79998..fcdcfd26a26b 100644
--- a/include/asm-ppc64/topology.h
+++ b/include/asm-ppc64/topology.h
@@ -59,10 +59,8 @@ static inline int node_to_first_cpu(int node)
59 .nr_balance_failed = 0, \ 59 .nr_balance_failed = 0, \
60} 60}
61 61
62#else /* !CONFIG_NUMA */ 62#endif /* CONFIG_NUMA */
63 63
64#include <asm-generic/topology.h> 64#include <asm-generic/topology.h>
65 65
66#endif /* CONFIG_NUMA */
67
68#endif /* _ASM_PPC64_TOPOLOGY_H */ 66#endif /* _ASM_PPC64_TOPOLOGY_H */
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h
index aade85c53a63..fe101d41e849 100644
--- a/include/asm-s390/thread_info.h
+++ b/include/asm-s390/thread_info.h
@@ -50,7 +50,7 @@ struct thread_info {
50 struct exec_domain *exec_domain; /* execution domain */ 50 struct exec_domain *exec_domain; /* execution domain */
51 unsigned long flags; /* low level flags */ 51 unsigned long flags; /* low level flags */
52 unsigned int cpu; /* current CPU */ 52 unsigned int cpu; /* current CPU */
53 unsigned int preempt_count; /* 0 => preemptable */ 53 int preempt_count; /* 0 => preemptable, <0 => BUG */
54 struct restart_block restart_block; 54 struct restart_block restart_block;
55}; 55};
56 56
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
index 4bbbd9f3c37e..46080cefaff8 100644
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -20,7 +20,7 @@ struct thread_info {
20 struct exec_domain *exec_domain; /* execution domain */ 20 struct exec_domain *exec_domain; /* execution domain */
21 __u32 flags; /* low level flags */ 21 __u32 flags; /* low level flags */
22 __u32 cpu; 22 __u32 cpu;
23 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 23 int preempt_count; /* 0 => preemptable, <0 => BUG */
24 struct restart_block restart_block; 24 struct restart_block restart_block;
25 __u8 supervisor_stack[0]; 25 __u8 supervisor_stack[0];
26}; 26};
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h
index 8a32d6bd0b79..10f024c6a2e3 100644
--- a/include/asm-sh64/thread_info.h
+++ b/include/asm-sh64/thread_info.h
@@ -22,7 +22,7 @@ struct thread_info {
22 struct exec_domain *exec_domain; /* execution domain */ 22 struct exec_domain *exec_domain; /* execution domain */
23 unsigned long flags; /* low level flags */ 23 unsigned long flags; /* low level flags */
24 /* Put the 4 32-bit fields together to make asm offsetting easier. */ 24 /* Put the 4 32-bit fields together to make asm offsetting easier. */
25 __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ 25 int preempt_count; /* 0 => preemptable, <0 => BUG */
26 __u16 cpu; 26 __u16 cpu;
27 27
28 mm_segment_t addr_limit; 28 mm_segment_t addr_limit;
diff --git a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
index 104f03c55416..ff6ccb3d24c6 100644
--- a/include/asm-sparc/thread_info.h
+++ b/include/asm-sparc/thread_info.h
@@ -30,9 +30,9 @@ struct thread_info {
30 struct task_struct *task; /* main task structure */ 30 struct task_struct *task; /* main task structure */
31 struct exec_domain *exec_domain; /* execution domain */ 31 struct exec_domain *exec_domain; /* execution domain */
32 unsigned long flags; /* low level flags */ 32 unsigned long flags; /* low level flags */
33
34 int cpu; /* cpu we're on */ 33 int cpu; /* cpu we're on */
35 int preempt_count; 34 int preempt_count; /* 0 => preemptable,
35 <0 => BUG */
36 int softirq_count; 36 int softirq_count;
37 int hardirq_count; 37 int hardirq_count;
38 38
diff --git a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
index 22f58055b8ab..b59122dd176d 100644
--- a/include/asm-sparc64/compat.h
+++ b/include/asm-sparc64/compat.h
@@ -25,6 +25,7 @@ typedef s32 compat_daddr_t;
25typedef u32 compat_caddr_t; 25typedef u32 compat_caddr_t;
26typedef __kernel_fsid_t compat_fsid_t; 26typedef __kernel_fsid_t compat_fsid_t;
27typedef s32 compat_key_t; 27typedef s32 compat_key_t;
28typedef s32 compat_timer_t;
28 29
29typedef s32 compat_int_t; 30typedef s32 compat_int_t;
30typedef s32 compat_long_t; 31typedef s32 compat_long_t;
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index 517caaba1c87..0cd652956929 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -46,7 +46,7 @@ struct thread_info {
46 unsigned long fault_address; 46 unsigned long fault_address;
47 struct pt_regs *kregs; 47 struct pt_regs *kregs;
48 struct exec_domain *exec_domain; 48 struct exec_domain *exec_domain;
49 int preempt_count; 49 int preempt_count; /* 0 => preemptable, <0 => BUG */
50 int __pad; 50 int __pad;
51 51
52 unsigned long *utraps; 52 unsigned long *utraps;
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index 1feaaf148ef1..97267f059ef5 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -17,7 +17,7 @@ struct thread_info {
17 struct exec_domain *exec_domain; /* execution domain */ 17 struct exec_domain *exec_domain; /* execution domain */
18 unsigned long flags; /* low level flags */ 18 unsigned long flags; /* low level flags */
19 __u32 cpu; /* current CPU */ 19 __u32 cpu; /* current CPU */
20 __s32 preempt_count; /* 0 => preemptable, 20 int preempt_count; /* 0 => preemptable,
21 <0 => BUG */ 21 <0 => BUG */
22 mm_segment_t addr_limit; /* thread address space: 22 mm_segment_t addr_limit; /* thread address space:
23 0-0xBFFFFFFF for user 23 0-0xBFFFFFFF for user
diff --git a/include/asm-v850/thread_info.h b/include/asm-v850/thread_info.h
index e2ef44593752..e4cfad94a553 100644
--- a/include/asm-v850/thread_info.h
+++ b/include/asm-v850/thread_info.h
@@ -30,7 +30,8 @@ struct thread_info {
30 struct exec_domain *exec_domain; /* execution domain */ 30 struct exec_domain *exec_domain; /* execution domain */
31 unsigned long flags; /* low level flags */ 31 unsigned long flags; /* low level flags */
32 int cpu; /* cpu we're on */ 32 int cpu; /* cpu we're on */
33 int preempt_count; 33 int preempt_count; /* 0 => preemptable,
34 <0 => BUG */
34 struct restart_block restart_block; 35 struct restart_block restart_block;
35}; 36};
36 37
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
index 5dd7727c756b..a31bb99be53f 100644
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -411,8 +411,6 @@ static __inline__ int ffs(int x)
411/* find last set bit */ 411/* find last set bit */
412#define fls(x) generic_fls(x) 412#define fls(x) generic_fls(x)
413 413
414#define ARCH_HAS_ATOMIC_UNSIGNED 1
415
416#endif /* __KERNEL__ */ 414#endif /* __KERNEL__ */
417 415
418#endif /* _X86_64_BITOPS_H */ 416#endif /* _X86_64_BITOPS_H */
diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
index c0a7717923ed..6efa00fe4e7b 100644
--- a/include/asm-x86_64/ia32.h
+++ b/include/asm-x86_64/ia32.h
@@ -94,7 +94,7 @@ typedef struct compat_siginfo{
94 94
95 /* POSIX.1b timers */ 95 /* POSIX.1b timers */
96 struct { 96 struct {
97 int _tid; /* timer id */ 97 compat_timer_t _tid; /* timer id */
98 int _overrun; /* overrun count */ 98 int _overrun; /* overrun count */
99 compat_sigval_t _sigval; /* same as below */ 99 compat_sigval_t _sigval; /* same as below */
100 int _sys_private; /* not to be passed to user */ 100 int _sys_private; /* not to be passed to user */
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index 94202703fae2..37fc3f149a5a 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -124,12 +124,7 @@ extern inline void * phys_to_virt(unsigned long address)
124/* 124/*
125 * Change "struct page" to physical address. 125 * Change "struct page" to physical address.
126 */ 126 */
127#ifdef CONFIG_DISCONTIGMEM
128#include <asm/mmzone.h>
129#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) 127#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
130#else
131#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
132#endif
133 128
134#include <asm-generic/iomap.h> 129#include <asm-generic/iomap.h>
135 130
diff --git a/include/asm-x86_64/kprobes.h b/include/asm-x86_64/kprobes.h
index bfea52d516f8..6d6d883fdf6d 100644
--- a/include/asm-x86_64/kprobes.h
+++ b/include/asm-x86_64/kprobes.h
@@ -38,6 +38,9 @@ typedef u8 kprobe_opcode_t;
38 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) 38 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
39 39
40#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry 40#define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry
41#define ARCH_SUPPORTS_KRETPROBES
42
43void kretprobe_trampoline(void);
41 44
42/* Architecture specific copy of original instruction*/ 45/* Architecture specific copy of original instruction*/
43struct arch_specific_insn { 46struct arch_specific_insn {
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index d95b7c240831..768413751b34 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -6,7 +6,7 @@
6 6
7#include <linux/config.h> 7#include <linux/config.h>
8 8
9#ifdef CONFIG_DISCONTIGMEM 9#ifdef CONFIG_NUMA
10 10
11#define VIRTUAL_BUG_ON(x) 11#define VIRTUAL_BUG_ON(x)
12 12
@@ -30,27 +30,23 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
30 return nid; 30 return nid;
31} 31}
32 32
33#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
34
35#define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr))
36#define NODE_DATA(nid) (node_data[nid]) 33#define NODE_DATA(nid) (node_data[nid])
37 34
38#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
39
40#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
41#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) 35#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
42#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ 36#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \
43 NODE_DATA(nid)->node_spanned_pages) 37 NODE_DATA(nid)->node_spanned_pages)
44 38
45#define local_mapnr(kvaddr) \ 39#ifdef CONFIG_DISCONTIGMEM
46 ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) ) 40
41#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
42#define kvaddr_to_nid(kaddr) phys_to_nid(__pa(kaddr))
47 43
48/* AK: this currently doesn't deal with invalid addresses. We'll see 44/* AK: this currently doesn't deal with invalid addresses. We'll see
49 if the 2.5 kernel doesn't pass them 45 if the 2.5 kernel doesn't pass them
50 (2.4 used to). */ 46 (2.4 used to). */
51#define pfn_to_page(pfn) ({ \ 47#define pfn_to_page(pfn) ({ \
52 int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); \ 48 int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); \
53 ((pfn) - node_start_pfn(nid)) + node_mem_map(nid); \ 49 ((pfn) - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map; \
54}) 50})
55 51
56#define page_to_pfn(page) \ 52#define page_to_pfn(page) \
@@ -60,4 +56,8 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
60 ({ u8 nid__ = pfn_to_nid(pfn); \ 56 ({ u8 nid__ = pfn_to_nid(pfn); \
61 nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) <= node_end_pfn(nid__); })) 57 nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) <= node_end_pfn(nid__); }))
62#endif 58#endif
59
60#define local_mapnr(kvaddr) \
61 ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
62#endif
63#endif 63#endif
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
index 513e52c71821..bc700232728d 100644
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -57,11 +57,6 @@
57 (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ 57 (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
58} while(0) 58} while(0)
59 59
60#define rdpmc(counter,low,high) \
61 __asm__ __volatile__("rdpmc" \
62 : "=a" (low), "=d" (high) \
63 : "c" (counter))
64
65#define write_tsc(val1,val2) wrmsr(0x10, val1, val2) 60#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
66 61
67#define rdpmc(counter,low,high) \ 62#define rdpmc(counter,low,high) \
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index 9ce338c3a71e..60130f4ca986 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -119,7 +119,9 @@ extern __inline__ int get_order(unsigned long size)
119 __pa(v); }) 119 __pa(v); })
120 120
121#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) 121#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
122#ifndef CONFIG_DISCONTIGMEM 122#define __boot_va(x) __va(x)
123#define __boot_pa(x) __pa(x)
124#ifdef CONFIG_FLATMEM
123#define pfn_to_page(pfn) (mem_map + (pfn)) 125#define pfn_to_page(pfn) (mem_map + (pfn))
124#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) 126#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
125#define pfn_valid(pfn) ((pfn) < max_mapnr) 127#define pfn_valid(pfn) ((pfn) < max_mapnr)
diff --git a/include/asm-x86_64/param.h b/include/asm-x86_64/param.h
index b707f0568c9e..40b11937180d 100644
--- a/include/asm-x86_64/param.h
+++ b/include/asm-x86_64/param.h
@@ -1,9 +1,11 @@
1#include <linux/config.h>
2
1#ifndef _ASMx86_64_PARAM_H 3#ifndef _ASMx86_64_PARAM_H
2#define _ASMx86_64_PARAM_H 4#define _ASMx86_64_PARAM_H
3 5
4#ifdef __KERNEL__ 6#ifdef __KERNEL__
5# define HZ 1000 /* Internal kernel timer frequency */ 7# define HZ CONFIG_HZ /* Internal kernel timer frequency */
6# define USER_HZ 100 /* .. some user interfaces are in "ticks */ 8# define USER_HZ 100 /* .. some user interfaces are in "ticks */
7#define CLOCKS_PER_SEC (USER_HZ) /* like times() */ 9#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
8#endif 10#endif
9 11
diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h
index 415d73f3c8ef..9c71855736fb 100644
--- a/include/asm-x86_64/percpu.h
+++ b/include/asm-x86_64/percpu.h
@@ -39,7 +39,7 @@ extern void setup_per_cpu_areas(void);
39#define DEFINE_PER_CPU(type, name) \ 39#define DEFINE_PER_CPU(type, name) \
40 __typeof__(type) per_cpu__##name 40 __typeof__(type) per_cpu__##name
41 41
42#define per_cpu(var, cpu) (*((void)cpu, &per_cpu__##var)) 42#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
43#define __get_cpu_var(var) per_cpu__##var 43#define __get_cpu_var(var) per_cpu__##var
44 44
45#endif /* SMP */ 45#endif /* SMP */
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 8b55f139968f..106f666517bb 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -280,6 +280,14 @@ struct thread_struct {
280 set_fs(USER_DS); \ 280 set_fs(USER_DS); \
281} while(0) 281} while(0)
282 282
283#define get_debugreg(var, register) \
284 __asm__("movq %%db" #register ", %0" \
285 :"=r" (var))
286#define set_debugreg(value, register) \
287 __asm__("movq %0,%%db" #register \
288 : /* no output */ \
289 :"r" (value))
290
283struct task_struct; 291struct task_struct;
284struct mm_struct; 292struct mm_struct;
285 293
diff --git a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h
index 5bbc8d3141c8..ca6f15ff61d4 100644
--- a/include/asm-x86_64/ptrace.h
+++ b/include/asm-x86_64/ptrace.h
@@ -82,6 +82,7 @@ struct pt_regs {
82 82
83#if defined(__KERNEL__) && !defined(__ASSEMBLY__) 83#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
84#define user_mode(regs) (!!((regs)->cs & 3)) 84#define user_mode(regs) (!!((regs)->cs & 3))
85#define user_mode_vm(regs) user_mode(regs)
85#define instruction_pointer(regs) ((regs)->rip) 86#define instruction_pointer(regs) ((regs)->rip)
86extern unsigned long profile_pc(struct pt_regs *regs); 87extern unsigned long profile_pc(struct pt_regs *regs);
87void signal_fault(struct pt_regs *regs, void __user *frame, char *where); 88void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
diff --git a/include/asm-x86_64/sparsemem.h b/include/asm-x86_64/sparsemem.h
new file mode 100644
index 000000000000..dabb16714a71
--- /dev/null
+++ b/include/asm-x86_64/sparsemem.h
@@ -0,0 +1,26 @@
1#ifndef _ASM_X86_64_SPARSEMEM_H
2#define _ASM_X86_64_SPARSEMEM_H 1
3
4#ifdef CONFIG_SPARSEMEM
5
6/*
7 * generic non-linear memory support:
8 *
9 * 1) we will not split memory into more chunks than will fit into the flags
10 * field of the struct page
11 *
12 * SECTION_SIZE_BITS 2^n: size of each section
13 * MAX_PHYSADDR_BITS 2^n: max size of physical address space
14 * MAX_PHYSMEM_BITS 2^n: how much memory we can have in that space
15 *
16 */
17
18#define SECTION_SIZE_BITS 27 /* matt - 128 is convenient right now */
19#define MAX_PHYSADDR_BITS 40
20#define MAX_PHYSMEM_BITS 40
21
22extern int early_pfn_to_nid(unsigned long pfn);
23
24#endif /* CONFIG_SPARSEMEM */
25
26#endif /* _ASM_X86_64_SPARSEMEM_H */
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
index f4b3b249639c..08eb6e4f3737 100644
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -29,7 +29,7 @@ struct thread_info {
29 __u32 flags; /* low level flags */ 29 __u32 flags; /* low level flags */
30 __u32 status; /* thread synchronous flags */ 30 __u32 status; /* thread synchronous flags */
31 __u32 cpu; /* current CPU */ 31 __u32 cpu; /* current CPU */
32 int preempt_count; 32 int preempt_count; /* 0 => preemptable, <0 => BUG */
33 33
34 mm_segment_t addr_limit; 34 mm_segment_t addr_limit;
35 struct restart_block restart_block; 35 struct restart_block restart_block;
diff --git a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h
index 34f31a18f90b..24ecf6a637cb 100644
--- a/include/asm-x86_64/timex.h
+++ b/include/asm-x86_64/timex.h
@@ -26,6 +26,9 @@ static inline cycles_t get_cycles (void)
26 26
27extern unsigned int cpu_khz; 27extern unsigned int cpu_khz;
28 28
29extern int read_current_timer(unsigned long *timer_value);
30#define ARCH_HAS_READ_CURRENT_TIMER 1
31
29extern struct vxtime_data vxtime; 32extern struct vxtime_data vxtime;
30 33
31#endif 34#endif
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index 67f24e0ea819..8f77e9f6bc23 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -3,7 +3,7 @@
3 3
4#include <linux/config.h> 4#include <linux/config.h>
5 5
6#ifdef CONFIG_DISCONTIGMEM 6#ifdef CONFIG_NUMA
7 7
8#include <asm/mpspec.h> 8#include <asm/mpspec.h>
9#include <asm/bitops.h> 9#include <asm/bitops.h>
@@ -13,8 +13,8 @@
13extern cpumask_t cpu_online_map; 13extern cpumask_t cpu_online_map;
14 14
15extern unsigned char cpu_to_node[]; 15extern unsigned char cpu_to_node[];
16extern unsigned char pci_bus_to_node[];
16extern cpumask_t node_to_cpumask[]; 17extern cpumask_t node_to_cpumask[];
17extern cpumask_t pci_bus_to_cpumask[];
18 18
19#ifdef CONFIG_ACPI_NUMA 19#ifdef CONFIG_ACPI_NUMA
20extern int __node_distance(int, int); 20extern int __node_distance(int, int);
@@ -26,18 +26,9 @@ extern int __node_distance(int, int);
26#define parent_node(node) (node) 26#define parent_node(node) (node)
27#define node_to_first_cpu(node) (__ffs(node_to_cpumask[node])) 27#define node_to_first_cpu(node) (__ffs(node_to_cpumask[node]))
28#define node_to_cpumask(node) (node_to_cpumask[node]) 28#define node_to_cpumask(node) (node_to_cpumask[node])
29#define pcibus_to_node(bus) pci_bus_to_node[(bus)->number]
30#define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus));
29 31
30static inline cpumask_t __pcibus_to_cpumask(int bus)
31{
32 cpumask_t busmask = pci_bus_to_cpumask[bus];
33 cpumask_t online = cpu_online_map;
34 cpumask_t res;
35 cpus_and(res, busmask, online);
36 return res;
37}
38#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus->number)
39
40#ifdef CONFIG_NUMA
41/* sched_domains SD_NODE_INIT for x86_64 machines */ 32/* sched_domains SD_NODE_INIT for x86_64 machines */
42#define SD_NODE_INIT (struct sched_domain) { \ 33#define SD_NODE_INIT (struct sched_domain) { \
43 .span = CPU_MASK_NONE, \ 34 .span = CPU_MASK_NONE, \
@@ -59,7 +50,6 @@ static inline cpumask_t __pcibus_to_cpumask(int bus)
59 .balance_interval = 1, \ 50 .balance_interval = 1, \
60 .nr_balance_failed = 0, \ 51 .nr_balance_failed = 0, \
61} 52}
62#endif
63 53
64#endif 54#endif
65 55
diff --git a/include/asm-xtensa/a.out.h b/include/asm-xtensa/a.out.h
new file mode 100644
index 000000000000..3be701dfe098
--- /dev/null
+++ b/include/asm-xtensa/a.out.h
@@ -0,0 +1,33 @@
1/*
2 * include/asm-xtensa/addrspace.h
3 *
4 * Dummy a.out file. Xtensa does not support the a.out format, but the kernel
5 * seems to depend on it.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 *
11 * Copyright (C) 2001 - 2005 Tensilica Inc.
12 */
13
14#ifndef _XTENSA_A_OUT_H
15#define _XTENSA_A_OUT_H
16
17/* Note: the kernel needs the a.out definitions, even if only ELF is used. */
18
19#define STACK_TOP TASK_SIZE
20
21struct exec
22{
23 unsigned long a_info;
24 unsigned a_text;
25 unsigned a_data;
26 unsigned a_bss;
27 unsigned a_syms;
28 unsigned a_entry;
29 unsigned a_trsize;
30 unsigned a_drsize;
31};
32
33#endif /* _XTENSA_A_OUT_H */
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
new file mode 100644
index 000000000000..d72bcb32ba4f
--- /dev/null
+++ b/include/asm-xtensa/atomic.h
@@ -0,0 +1,272 @@
1/*
2 * include/asm-xtensa/atomic.h
3 *
4 * Atomic operations that C can't guarantee us. Useful for resource counting..
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_ATOMIC_H
14#define _XTENSA_ATOMIC_H
15
16#include <linux/config.h>
17#include <linux/stringify.h>
18
19typedef struct { volatile int counter; } atomic_t;
20
21#ifdef __KERNEL__
22#include <asm/processor.h>
23#include <asm/system.h>
24
25#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
26
27/*
28 * This Xtensa implementation assumes that the right mechanism
29 * for exclusion is for locking interrupts to level 1.
30 *
31 * Locking interrupts looks like this:
32 *
33 * rsil a15, 1
34 * <code>
35 * wsr a15, PS
36 * rsync
37 *
38 * Note that a15 is used here because the register allocation
39 * done by the compiler is not guaranteed and a window overflow
40 * may not occur between the rsil and wsr instructions. By using
41 * a15 in the rsil, the machine is guaranteed to be in a state
42 * where no register reference will cause an overflow.
43 */
44
45/**
46 * atomic_read - read atomic variable
47 * @v: pointer of type atomic_t
48 *
49 * Atomically reads the value of @v.
50 */
51#define atomic_read(v) ((v)->counter)
52
53/**
54 * atomic_set - set atomic variable
55 * @v: pointer of type atomic_t
56 * @i: required value
57 *
58 * Atomically sets the value of @v to @i.
59 */
60#define atomic_set(v,i) ((v)->counter = (i))
61
62/**
63 * atomic_add - add integer to atomic variable
64 * @i: integer value to add
65 * @v: pointer of type atomic_t
66 *
67 * Atomically adds @i to @v.
68 */
69extern __inline__ void atomic_add(int i, atomic_t * v)
70{
71 unsigned int vval;
72
73 __asm__ __volatile__(
74 "rsil a15, "__stringify(LOCKLEVEL)"\n\t"
75 "l32i %0, %2, 0 \n\t"
76 "add %0, %0, %1 \n\t"
77 "s32i %0, %2, 0 \n\t"
78 "wsr a15, "__stringify(PS)" \n\t"
79 "rsync \n"
80 : "=&a" (vval)
81 : "a" (i), "a" (v)
82 : "a15", "memory"
83 );
84}
85
86/**
87 * atomic_sub - subtract the atomic variable
88 * @i: integer value to subtract
89 * @v: pointer of type atomic_t
90 *
91 * Atomically subtracts @i from @v.
92 */
93extern __inline__ void atomic_sub(int i, atomic_t *v)
94{
95 unsigned int vval;
96
97 __asm__ __volatile__(
98 "rsil a15, "__stringify(LOCKLEVEL)"\n\t"
99 "l32i %0, %2, 0 \n\t"
100 "sub %0, %0, %1 \n\t"
101 "s32i %0, %2, 0 \n\t"
102 "wsr a15, "__stringify(PS)" \n\t"
103 "rsync \n"
104 : "=&a" (vval)
105 : "a" (i), "a" (v)
106 : "a15", "memory"
107 );
108}
109
110/*
111 * We use atomic_{add|sub}_return to define other functions.
112 */
113
114extern __inline__ int atomic_add_return(int i, atomic_t * v)
115{
116 unsigned int vval;
117
118 __asm__ __volatile__(
119 "rsil a15,"__stringify(LOCKLEVEL)"\n\t"
120 "l32i %0, %2, 0 \n\t"
121 "add %0, %0, %1 \n\t"
122 "s32i %0, %2, 0 \n\t"
123 "wsr a15, "__stringify(PS)" \n\t"
124 "rsync \n"
125 : "=&a" (vval)
126 : "a" (i), "a" (v)
127 : "a15", "memory"
128 );
129
130 return vval;
131}
132
133extern __inline__ int atomic_sub_return(int i, atomic_t * v)
134{
135 unsigned int vval;
136
137 __asm__ __volatile__(
138 "rsil a15,"__stringify(LOCKLEVEL)"\n\t"
139 "l32i %0, %2, 0 \n\t"
140 "sub %0, %0, %1 \n\t"
141 "s32i %0, %2, 0 \n\t"
142 "wsr a15, "__stringify(PS)" \n\t"
143 "rsync \n"
144 : "=&a" (vval)
145 : "a" (i), "a" (v)
146 : "a15", "memory"
147 );
148
149 return vval;
150}
151
152/**
153 * atomic_sub_and_test - subtract value from variable and test result
154 * @i: integer value to subtract
155 * @v: pointer of type atomic_t
156 *
157 * Atomically subtracts @i from @v and returns
158 * true if the result is zero, or false for all
159 * other cases.
160 */
161#define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0)
162
163/**
164 * atomic_inc - increment atomic variable
165 * @v: pointer of type atomic_t
166 *
167 * Atomically increments @v by 1.
168 */
169#define atomic_inc(v) atomic_add(1,(v))
170
171/**
172 * atomic_inc - increment atomic variable
173 * @v: pointer of type atomic_t
174 *
175 * Atomically increments @v by 1.
176 */
177#define atomic_inc_return(v) atomic_add_return(1,(v))
178
179/**
180 * atomic_dec - decrement atomic variable
181 * @v: pointer of type atomic_t
182 *
183 * Atomically decrements @v by 1.
184 */
185#define atomic_dec(v) atomic_sub(1,(v))
186
187/**
188 * atomic_dec_return - decrement atomic variable
189 * @v: pointer of type atomic_t
190 *
191 * Atomically decrements @v by 1.
192 */
193#define atomic_dec_return(v) atomic_sub_return(1,(v))
194
195/**
196 * atomic_dec_and_test - decrement and test
197 * @v: pointer of type atomic_t
198 *
199 * Atomically decrements @v by 1 and
200 * returns true if the result is 0, or false for all other
201 * cases.
202 */
203#define atomic_dec_and_test(v) (atomic_sub_return(1,(v)) == 0)
204
205/**
206 * atomic_inc_and_test - increment and test
207 * @v: pointer of type atomic_t
208 *
209 * Atomically increments @v by 1
210 * and returns true if the result is zero, or false for all
211 * other cases.
212 */
213#define atomic_inc_and_test(v) (atomic_add_return(1,(v)) == 0)
214
215/**
216 * atomic_add_negative - add and test if negative
217 * @v: pointer of type atomic_t
218 * @i: integer value to add
219 *
220 * Atomically adds @i to @v and returns true
221 * if the result is negative, or false when
222 * result is greater than or equal to zero.
223 */
224#define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0)
225
226
227extern __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
228{
229 unsigned int all_f = -1;
230 unsigned int vval;
231
232 __asm__ __volatile__(
233 "rsil a15,"__stringify(LOCKLEVEL)"\n\t"
234 "l32i %0, %2, 0 \n\t"
235 "xor %1, %4, %3 \n\t"
236 "and %0, %0, %4 \n\t"
237 "s32i %0, %2, 0 \n\t"
238 "wsr a15, "__stringify(PS)" \n\t"
239 "rsync \n"
240 : "=&a" (vval), "=a" (mask)
241 : "a" (v), "a" (all_f), "1" (mask)
242 : "a15", "memory"
243 );
244}
245
246extern __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)
247{
248 unsigned int vval;
249
250 __asm__ __volatile__(
251 "rsil a15,"__stringify(LOCKLEVEL)"\n\t"
252 "l32i %0, %2, 0 \n\t"
253 "or %0, %0, %1 \n\t"
254 "s32i %0, %2, 0 \n\t"
255 "wsr a15, "__stringify(PS)" \n\t"
256 "rsync \n"
257 : "=&a" (vval)
258 : "a" (mask), "a" (v)
259 : "a15", "memory"
260 );
261}
262
263/* Atomic operations are already serializing */
264#define smp_mb__before_atomic_dec() barrier()
265#define smp_mb__after_atomic_dec() barrier()
266#define smp_mb__before_atomic_inc() barrier()
267#define smp_mb__after_atomic_inc() barrier()
268
269#endif /* __KERNEL__ */
270
271#endif /* _XTENSA_ATOMIC_H */
272
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
new file mode 100644
index 000000000000..d395ef226c32
--- /dev/null
+++ b/include/asm-xtensa/bitops.h
@@ -0,0 +1,446 @@
1/*
2 * include/asm-xtensa/bitops.h
3 *
4 * Atomic operations that C can't guarantee us.Useful for resource counting etc.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_BITOPS_H
14#define _XTENSA_BITOPS_H
15
16#ifdef __KERNEL__
17
18#include <asm/processor.h>
19#include <asm/byteorder.h>
20#include <asm/system.h>
21
22#ifdef CONFIG_SMP
23# error SMP not supported on this architecture
24#endif
25
26static __inline__ void set_bit(int nr, volatile void * addr)
27{
28 unsigned long mask = 1 << (nr & 0x1f);
29 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
30 unsigned long flags;
31
32 local_irq_save(flags);
33 *a |= mask;
34 local_irq_restore(flags);
35}
36
37static __inline__ void __set_bit(int nr, volatile unsigned long * addr)
38{
39 unsigned long mask = 1 << (nr & 0x1f);
40 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
41
42 *a |= mask;
43}
44
45static __inline__ void clear_bit(int nr, volatile void * addr)
46{
47 unsigned long mask = 1 << (nr & 0x1f);
48 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
49 unsigned long flags;
50
51 local_irq_save(flags);
52 *a &= ~mask;
53 local_irq_restore(flags);
54}
55
56static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
57{
58 unsigned long mask = 1 << (nr & 0x1f);
59 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
60
61 *a &= ~mask;
62}
63
64/*
65 * clear_bit() doesn't provide any barrier for the compiler.
66 */
67
68#define smp_mb__before_clear_bit() barrier()
69#define smp_mb__after_clear_bit() barrier()
70
71static __inline__ void change_bit(int nr, volatile void * addr)
72{
73 unsigned long mask = 1 << (nr & 0x1f);
74 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
75 unsigned long flags;
76
77 local_irq_save(flags);
78 *a ^= mask;
79 local_irq_restore(flags);
80}
81
82static __inline__ void __change_bit(int nr, volatile void * addr)
83{
84 unsigned long mask = 1 << (nr & 0x1f);
85 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
86
87 *a ^= mask;
88}
89
90static __inline__ int test_and_set_bit(int nr, volatile void * addr)
91{
92 unsigned long retval;
93 unsigned long mask = 1 << (nr & 0x1f);
94 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
95 unsigned long flags;
96
97 local_irq_save(flags);
98 retval = (mask & *a) != 0;
99 *a |= mask;
100 local_irq_restore(flags);
101
102 return retval;
103}
104
105static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
106{
107 unsigned long retval;
108 unsigned long mask = 1 << (nr & 0x1f);
109 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
110
111 retval = (mask & *a) != 0;
112 *a |= mask;
113
114 return retval;
115}
116
117static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
118{
119 unsigned long retval;
120 unsigned long mask = 1 << (nr & 0x1f);
121 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
122 unsigned long flags;
123
124 local_irq_save(flags);
125 retval = (mask & *a) != 0;
126 *a &= ~mask;
127 local_irq_restore(flags);
128
129 return retval;
130}
131
132static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
133{
134 unsigned long mask = 1 << (nr & 0x1f);
135 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
136 unsigned long old = *a;
137
138 *a = old & ~mask;
139 return (old & mask) != 0;
140}
141
142static __inline__ int test_and_change_bit(int nr, volatile void * addr)
143{
144 unsigned long retval;
145 unsigned long mask = 1 << (nr & 0x1f);
146 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
147 unsigned long flags;
148
149 local_irq_save(flags);
150
151 retval = (mask & *a) != 0;
152 *a ^= mask;
153 local_irq_restore(flags);
154
155 return retval;
156}
157
158/*
159 * non-atomic version; can be reordered
160 */
161
162static __inline__ int __test_and_change_bit(int nr, volatile void *addr)
163{
164 unsigned long mask = 1 << (nr & 0x1f);
165 unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
166 unsigned long old = *a;
167
168 *a = old ^ mask;
169 return (old & mask) != 0;
170}
171
172static __inline__ int test_bit(int nr, const volatile void *addr)
173{
174 return 1UL & (((const volatile unsigned int *)addr)[nr>>5] >> (nr&31));
175}
176
177#if XCHAL_HAVE_NSAU
178
179static __inline__ int __cntlz (unsigned long x)
180{
181 int lz;
182 asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
183 return 31 - lz;
184}
185
186#else
187
188static __inline__ int __cntlz (unsigned long x)
189{
190 unsigned long sum, x1, x2, x4, x8, x16;
191 x1 = x & 0xAAAAAAAA;
192 x2 = x & 0xCCCCCCCC;
193 x4 = x & 0xF0F0F0F0;
194 x8 = x & 0xFF00FF00;
195 x16 = x & 0xFFFF0000;
196 sum = x2 ? 2 : 0;
197 sum += (x16 != 0) * 16;
198 sum += (x8 != 0) * 8;
199 sum += (x4 != 0) * 4;
200 sum += (x1 != 0);
201
202 return sum;
203}
204
205#endif
206
207/*
208 * ffz: Find first zero in word. Undefined if no zero exists.
209 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
210 */
211
212static __inline__ int ffz(unsigned long x)
213{
214 if ((x = ~x) == 0)
215 return 32;
216 return __cntlz(x & -x);
217}
218
219/*
220 * __ffs: Find first bit set in word. Return 0 for bit 0
221 */
222
223static __inline__ int __ffs(unsigned long x)
224{
225 return __cntlz(x & -x);
226}
227
228/*
229 * ffs: Find first bit set in word. This is defined the same way as
230 * the libc and compiler builtin ffs routines, therefore
231 * differs in spirit from the above ffz (man ffs).
232 */
233
234static __inline__ int ffs(unsigned long x)
235{
236 return __cntlz(x & -x) + 1;
237}
238
239/*
240 * fls: Find last (most-significant) bit set in word.
241 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
242 */
243
244static __inline__ int fls (unsigned int x)
245{
246 return __cntlz(x);
247}
248
249static __inline__ int
250find_next_bit(const unsigned long *addr, int size, int offset)
251{
252 const unsigned long *p = addr + (offset >> 5);
253 unsigned long result = offset & ~31UL;
254 unsigned long tmp;
255
256 if (offset >= size)
257 return size;
258 size -= result;
259 offset &= 31UL;
260 if (offset) {
261 tmp = *p++;
262 tmp &= ~0UL << offset;
263 if (size < 32)
264 goto found_first;
265 if (tmp)
266 goto found_middle;
267 size -= 32;
268 result += 32;
269 }
270 while (size >= 32) {
271 if ((tmp = *p++) != 0)
272 goto found_middle;
273 result += 32;
274 size -= 32;
275 }
276 if (!size)
277 return result;
278 tmp = *p;
279
280found_first:
281 tmp &= ~0UL >> (32 - size);
282 if (tmp == 0UL) /* Are any bits set? */
283 return result + size; /* Nope. */
284found_middle:
285 return result + __ffs(tmp);
286}
287
288/**
289 * find_first_bit - find the first set bit in a memory region
290 * @addr: The address to start the search at
291 * @size: The maximum size to search
292 *
293 * Returns the bit-number of the first set bit, not the number of the byte
294 * containing a bit.
295 */
296
297#define find_first_bit(addr, size) \
298 find_next_bit((addr), (size), 0)
299
300static __inline__ int
301find_next_zero_bit(const unsigned long *addr, int size, int offset)
302{
303 const unsigned long *p = addr + (offset >> 5);
304 unsigned long result = offset & ~31UL;
305 unsigned long tmp;
306
307 if (offset >= size)
308 return size;
309 size -= result;
310 offset &= 31UL;
311 if (offset) {
312 tmp = *p++;
313 tmp |= ~0UL >> (32-offset);
314 if (size < 32)
315 goto found_first;
316 if (~tmp)
317 goto found_middle;
318 size -= 32;
319 result += 32;
320 }
321 while (size & ~31UL) {
322 if (~(tmp = *p++))
323 goto found_middle;
324 result += 32;
325 size -= 32;
326 }
327 if (!size)
328 return result;
329 tmp = *p;
330
331found_first:
332 tmp |= ~0UL << size;
333found_middle:
334 return result + ffz(tmp);
335}
336
337#define find_first_zero_bit(addr, size) \
338 find_next_zero_bit((addr), (size), 0)
339
340#ifdef __XTENSA_EL__
341# define ext2_set_bit(nr,addr) __test_and_set_bit((nr), (addr))
342# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr),(addr))
343# define ext2_clear_bit(nr,addr) __test_and_clear_bit((nr), (addr))
344# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr),(addr))
345# define ext2_test_bit(nr,addr) test_bit((nr), (addr))
346# define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr),(size))
347# define ext2_find_next_zero_bit(addr, size, offset) \
348 find_next_zero_bit((addr), (size), (offset))
349#elif defined(__XTENSA_EB__)
350# define ext2_set_bit(nr,addr) __test_and_set_bit((nr) ^ 0x18, (addr))
351# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr) ^ 0x18, (addr))
352# define ext2_clear_bit(nr,addr) __test_and_clear_bit((nr) ^ 18, (addr))
353# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr)^0x18,(addr))
354# define ext2_test_bit(nr,addr) test_bit((nr) ^ 0x18, (addr))
355# define ext2_find_first_zero_bit(addr, size) \
356 ext2_find_next_zero_bit((addr), (size), 0)
357
358static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
359{
360 unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
361 unsigned long result = offset & ~31UL;
362 unsigned long tmp;
363
364 if (offset >= size)
365 return size;
366 size -= result;
367 offset &= 31UL;
368 if(offset) {
369 /* We hold the little endian value in tmp, but then the
370 * shift is illegal. So we could keep a big endian value
371 * in tmp, like this:
372 *
373 * tmp = __swab32(*(p++));
374 * tmp |= ~0UL >> (32-offset);
375 *
376 * but this would decrease preformance, so we change the
377 * shift:
378 */
379 tmp = *(p++);
380 tmp |= __swab32(~0UL >> (32-offset));
381 if(size < 32)
382 goto found_first;
383 if(~tmp)
384 goto found_middle;
385 size -= 32;
386 result += 32;
387 }
388 while(size & ~31UL) {
389 if(~(tmp = *(p++)))
390 goto found_middle;
391 result += 32;
392 size -= 32;
393 }
394 if(!size)
395 return result;
396 tmp = *p;
397
398found_first:
399 /* tmp is little endian, so we would have to swab the shift,
400 * see above. But then we have to swab tmp below for ffz, so
401 * we might as well do this here.
402 */
403 return result + ffz(__swab32(tmp) | (~0UL << size));
404found_middle:
405 return result + ffz(__swab32(tmp));
406}
407
408#else
409# error processor byte order undefined!
410#endif
411
412
413#define hweight32(x) generic_hweight32(x)
414#define hweight16(x) generic_hweight16(x)
415#define hweight8(x) generic_hweight8(x)
416
417/*
418 * Find the first bit set in a 140-bit bitmap.
419 * The first 100 bits are unlikely to be set.
420 */
421
422static inline int sched_find_first_bit(const unsigned long *b)
423{
424 if (unlikely(b[0]))
425 return __ffs(b[0]);
426 if (unlikely(b[1]))
427 return __ffs(b[1]) + 32;
428 if (unlikely(b[2]))
429 return __ffs(b[2]) + 64;
430 if (b[3])
431 return __ffs(b[3]) + 96;
432 return __ffs(b[4]) + 128;
433}
434
435
436/* Bitmap functions for the minix filesystem. */
437
438#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
439#define minix_set_bit(nr,addr) set_bit(nr,addr)
440#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
441#define minix_test_bit(nr,addr) test_bit(nr,addr)
442#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
443
444#endif /* __KERNEL__ */
445
446#endif /* _XTENSA_BITOPS_H */
diff --git a/include/asm-xtensa/bootparam.h b/include/asm-xtensa/bootparam.h
new file mode 100644
index 000000000000..9983f2c1b7ee
--- /dev/null
+++ b/include/asm-xtensa/bootparam.h
@@ -0,0 +1,61 @@
1/*
2 * include/asm-xtensa/bootparam.h
3 *
4 * Definition of the Linux/Xtensa boot parameter structure
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * (Concept borrowed from the 68K port)
13 */
14
15#ifndef _XTENSA_BOOTPARAM_H
16#define _XTENSA_BOOTPARAM_H
17
18#define BP_VERSION 0x0001
19
20#define BP_TAG_COMMAND_LINE 0x1001 /* command line (0-terminated string)*/
21#define BP_TAG_INITRD 0x1002 /* ramdisk addr and size (bp_meminfo) */
22#define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */
23#define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */
24#define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */
25
26#define BP_TAG_FIRST 0x7B0B /* first tag with a version number */
27#define BP_TAG_LAST 0x7E0B /* last tag */
28
29#ifndef __ASSEMBLY__
30
31/* All records are aligned to 4 bytes */
32
33typedef struct bp_tag {
34 unsigned short id; /* tag id */
35 unsigned short size; /* size of this record excluding the structure*/
36 unsigned long data[0]; /* data */
37} bp_tag_t;
38
39typedef struct meminfo {
40 unsigned long type;
41 unsigned long start;
42 unsigned long end;
43} meminfo_t;
44
45#define SYSMEM_BANKS_MAX 5
46
47#define MEMORY_TYPE_CONVENTIONAL 0x1000
48#define MEMORY_TYPE_NONE 0x2000
49
50typedef struct sysmem_info {
51 int nr_banks;
52 meminfo_t bank[SYSMEM_BANKS_MAX];
53} sysmem_info_t;
54
55extern sysmem_info_t sysmem;
56
57#endif
58#endif
59
60
61
diff --git a/include/asm-xtensa/bug.h b/include/asm-xtensa/bug.h
new file mode 100644
index 000000000000..56703659b204
--- /dev/null
+++ b/include/asm-xtensa/bug.h
@@ -0,0 +1,41 @@
1/*
2 * include/asm-xtensa/bug.h
3 *
4 * Macros to cause a 'bug' message.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_BUG_H
14#define _XTENSA_BUG_H
15
16#include <linux/stringify.h>
17
18#define ILL __asm__ __volatile__ (".byte 0,0,0\n")
19
20#ifdef CONFIG_KALLSYMS
21# define BUG() do { \
22 printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
23 ILL; \
24} while (0)
25#else
26# define BUG() do { \
27 printk("kernel BUG!\n"); \
28 ILL; \
29} while (0)
30#endif
31
32#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
33#define PAGE_BUG(page) do { BUG(); } while (0)
34#define WARN_ON(condition) do { \
35 if (unlikely((condition)!=0)) { \
36 printk ("Warning in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
37 dump_stack(); \
38 } \
39} while (0)
40
41#endif /* _XTENSA_BUG_H */
diff --git a/include/asm-xtensa/bugs.h b/include/asm-xtensa/bugs.h
new file mode 100644
index 000000000000..c42285320133
--- /dev/null
+++ b/include/asm-xtensa/bugs.h
@@ -0,0 +1,22 @@
1/*
2 * include/asm-xtensa/bugs.h
3 *
4 * This is included by init/main.c to check for architecture-dependent bugs.
5 *
6 * Xtensa processors don't have any bugs. :)
7 *
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file "COPYING" in the main directory of
10 * this archive for more details.
11 */
12
13#ifndef _XTENSA_BUGS_H
14#define _XTENSA_BUGS_H
15
16#include <asm/processor.h>
17
18static void __init check_bugs(void)
19{
20}
21
22#endif /* _XTENSA_BUGS_H */
diff --git a/include/asm-xtensa/byteorder.h b/include/asm-xtensa/byteorder.h
new file mode 100644
index 000000000000..0b1552569aae
--- /dev/null
+++ b/include/asm-xtensa/byteorder.h
@@ -0,0 +1,82 @@
1/*
2 * include/asm-xtensa/byteorder.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_BYTEORDER_H
12#define _XTENSA_BYTEORDER_H
13
14#include <asm/processor.h>
15#include <asm/types.h>
16
17static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
18{
19 __u32 res;
20 /* instruction sequence from Xtensa ISA release 2/2000 */
21 __asm__("ssai 8 \n\t"
22 "srli %0, %1, 16 \n\t"
23 "src %0, %0, %1 \n\t"
24 "src %0, %0, %0 \n\t"
25 "src %0, %1, %0 \n"
26 : "=&a" (res)
27 : "a" (x)
28 );
29 return res;
30}
31
32static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
33{
34 /* Given that 'short' values are signed (i.e., can be negative),
35 * we cannot assume that the upper 16-bits of the register are
36 * zero. We are careful to mask values after shifting.
37 */
38
39 /* There exists an anomaly between xt-gcc and xt-xcc. xt-gcc
40 * inserts an extui instruction after putting this function inline
41 * to ensure that it uses only the least-significant 16 bits of
42 * the result. xt-xcc doesn't use an extui, but assumes the
43 * __asm__ macro follows convention that the upper 16 bits of an
44 * 'unsigned short' result are still zero. This macro doesn't
45 * follow convention; indeed, it leaves garbage in the upport 16
46 * bits of the register.
47
48 * Declaring the temporary variables 'res' and 'tmp' to be 32-bit
49 * types while the return type of the function is a 16-bit type
50 * forces both compilers to insert exactly one extui instruction
51 * (or equivalent) to mask off the upper 16 bits. */
52
53 __u32 res;
54 __u32 tmp;
55
56 __asm__("extui %1, %2, 8, 8\n\t"
57 "slli %0, %2, 8 \n\t"
58 "or %0, %0, %1 \n"
59 : "=&a" (res), "=&a" (tmp)
60 : "a" (x)
61 );
62
63 return res;
64}
65
66#define __arch__swab32(x) ___arch__swab32(x)
67#define __arch__swab16(x) ___arch__swab16(x)
68
69#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
70# define __BYTEORDER_HAS_U64__
71# define __SWAB_64_THRU_32__
72#endif
73
74#ifdef __XTENSA_EL__
75# include <linux/byteorder/little_endian.h>
76#elif defined(__XTENSA_EB__)
77# include <linux/byteorder/big_endian.h>
78#else
79# error processor byte order undefined!
80#endif
81
82#endif /* __ASM_XTENSA_BYTEORDER_H */
diff --git a/include/asm-xtensa/cache.h b/include/asm-xtensa/cache.h
new file mode 100644
index 000000000000..5aae3f12407c
--- /dev/null
+++ b/include/asm-xtensa/cache.h
@@ -0,0 +1,32 @@
1/*
2 * include/asm-xtensa/cacheflush.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 * 2 of the License, or (at your option) any later version.
8 *
9 * (C) 2001 - 2005 Tensilica Inc.
10 */
11
12#ifndef _XTENSA_CACHE_H
13#define _XTENSA_CACHE_H
14
15#include <xtensa/config/core.h>
16
17#if XCHAL_ICACHE_SIZE > 0
18# if (XCHAL_ICACHE_SIZE % (XCHAL_ICACHE_LINESIZE*XCHAL_ICACHE_WAYS*4)) != 0
19# error cache configuration outside expected/supported range!
20# endif
21#endif
22
23#if XCHAL_DCACHE_SIZE > 0
24# if (XCHAL_DCACHE_SIZE % (XCHAL_DCACHE_LINESIZE*XCHAL_DCACHE_WAYS*4)) != 0
25# error cache configuration outside expected/supported range!
26# endif
27#endif
28
29#define L1_CACHE_SHIFT XCHAL_CACHE_LINEWIDTH_MAX
30#define L1_CACHE_BYTES XCHAL_CACHE_LINESIZE_MAX
31
32#endif /* _XTENSA_CACHE_H */
diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h
new file mode 100644
index 000000000000..44a36e087844
--- /dev/null
+++ b/include/asm-xtensa/cacheflush.h
@@ -0,0 +1,122 @@
1/*
2 * include/asm-xtensa/cacheflush.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_CACHEFLUSH_H
12#define _XTENSA_CACHEFLUSH_H
13
14#ifdef __KERNEL__
15
16#include <linux/mm.h>
17#include <asm/processor.h>
18#include <asm/page.h>
19
20/*
21 * flush and invalidate data cache, invalidate instruction cache:
22 *
23 * __flush_invalidate_cache_all()
24 * __flush_invalidate_cache_range(from,sze)
25 *
26 * invalidate data or instruction cache:
27 *
28 * __invalidate_icache_all()
29 * __invalidate_icache_page(adr)
30 * __invalidate_dcache_page(adr)
31 * __invalidate_icache_range(from,size)
32 * __invalidate_dcache_range(from,size)
33 *
34 * flush data cache:
35 *
36 * __flush_dcache_page(adr)
37 *
38 * flush and invalidate data cache:
39 *
40 * __flush_invalidate_dcache_all()
41 * __flush_invalidate_dcache_page(adr)
42 * __flush_invalidate_dcache_range(from,size)
43 */
44
45extern void __flush_invalidate_cache_all(void);
46extern void __flush_invalidate_cache_range(unsigned long, unsigned long);
47extern void __flush_invalidate_dcache_all(void);
48extern void __invalidate_icache_all(void);
49
50extern void __invalidate_dcache_page(unsigned long);
51extern void __invalidate_icache_page(unsigned long);
52extern void __invalidate_icache_range(unsigned long, unsigned long);
53extern void __invalidate_dcache_range(unsigned long, unsigned long);
54
55#if XCHAL_DCACHE_IS_WRITEBACK
56extern void __flush_dcache_page(unsigned long);
57extern void __flush_invalidate_dcache_page(unsigned long);
58extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
59#else
60# define __flush_dcache_page(p) do { } while(0)
61# define __flush_invalidate_dcache_page(p) do { } while(0)
62# define __flush_invalidate_dcache_range(p,s) do { } while(0)
63#endif
64
65/*
66 * We have physically tagged caches - nothing to do here -
67 * unless we have cache aliasing.
68 *
69 * Pages can get remapped. Because this might change the 'color' of that page,
70 * we have to flush the cache before the PTE is changed.
71 * (see also Documentation/cachetlb.txt)
72 */
73
74#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
75
76#define flush_cache_all() __flush_invalidate_cache_all();
77#define flush_cache_mm(mm) __flush_invalidate_cache_all();
78
79#define flush_cache_vmap(start,end) __flush_invalidate_cache_all();
80#define flush_cache_vunmap(start,end) __flush_invalidate_cache_all();
81
82extern void flush_dcache_page(struct page*);
83
84extern void flush_cache_range(struct vm_area_struct*, ulong, ulong);
85extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long);
86
87#else
88
89#define flush_cache_all() do { } while (0)
90#define flush_cache_mm(mm) do { } while (0)
91
92#define flush_cache_vmap(start,end) do { } while (0)
93#define flush_cache_vunmap(start,end) do { } while (0)
94
95#define flush_dcache_page(page) do { } while (0)
96
97#define flush_cache_page(vma,addr,pfn) do { } while (0)
98#define flush_cache_range(vma,start,end) do { } while (0)
99
100#endif
101
102#define flush_icache_range(start,end) \
103 __invalidate_icache_range(start,(end)-(start))
104
105/* This is not required, see Documentation/cachetlb.txt */
106
107#define flush_icache_page(vma,page) do { } while(0)
108
109#define flush_dcache_mmap_lock(mapping) do { } while (0)
110#define flush_dcache_mmap_unlock(mapping) do { } while (0)
111
112
113#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
114 memcpy(dst, src, len)
115
116#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
117 memcpy(dst, src, len)
118
119#endif /* __KERNEL__ */
120
121#endif /* _XTENSA_CACHEFLUSH_H */
122
diff --git a/include/asm-xtensa/checksum.h b/include/asm-xtensa/checksum.h
new file mode 100644
index 000000000000..1a00fad19929
--- /dev/null
+++ b/include/asm-xtensa/checksum.h
@@ -0,0 +1,264 @@
1/*
2 * include/asm-xtensa/checksum.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_CHECKSUM_H
12#define _XTENSA_CHECKSUM_H
13
14#include <linux/config.h>
15#include <linux/in6.h>
16#include <xtensa/config/core.h>
17
18/*
19 * computes the checksum of a memory block at buff, length len,
20 * and adds in "sum" (32-bit)
21 *
22 * returns a 32-bit number suitable for feeding into itself
23 * or csum_tcpudp_magic
24 *
25 * this function must be called with even lengths, except
26 * for the last fragment, which may be odd
27 *
28 * it's best to have buff aligned on a 32-bit boundary
29 */
30asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
31
32/*
33 * the same as csum_partial, but copies from src while it
34 * checksums, and handles user-space pointer exceptions correctly, when needed.
35 *
36 * here even more important to align src and dst on a 32-bit (or even
37 * better 64-bit) boundary
38 */
39
40asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
41 int *src_err_ptr, int *dst_err_ptr);
42
43/*
44 * Note: when you get a NULL pointer exception here this means someone
45 * passed in an incorrect kernel address to one of these functions.
46 *
47 * If you use these functions directly please don't forget the
48 * verify_area().
49 */
50extern __inline__
51unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
52 int len, int sum)
53{
54 return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
55}
56
57extern __inline__
58unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
59 int len, int sum, int *err_ptr)
60{
61 return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
62}
63
64/*
65 * These are the old (and unsafe) way of doing checksums, a warning message will be
66 * printed if they are used and an exeption occurs.
67 *
68 * these functions should go away after some time.
69 */
70
71#define csum_partial_copy_fromuser csum_partial_copy
72unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
73
74/*
75 * Fold a partial checksum
76 */
77
78static __inline__ unsigned int csum_fold(unsigned int sum)
79{
80 unsigned int __dummy;
81 __asm__("extui %1, %0, 16, 16\n\t"
82 "extui %0 ,%0, 0, 16\n\t"
83 "add %0, %0, %1\n\t"
84 "slli %1, %0, 16\n\t"
85 "add %0, %0, %1\n\t"
86 "extui %0, %0, 16, 16\n\t"
87 "neg %0, %0\n\t"
88 "addi %0, %0, -1\n\t"
89 "extui %0, %0, 0, 16\n\t"
90 : "=r" (sum), "=&r" (__dummy)
91 : "0" (sum));
92 return sum;
93}
94
95/*
96 * This is a version of ip_compute_csum() optimized for IP headers,
97 * which always checksum on 4 octet boundaries.
98 */
99static __inline__ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
100{
101 unsigned int sum, tmp, endaddr;
102
103 __asm__ __volatile__(
104 "sub %0, %0, %0\n\t"
105#if XCHAL_HAVE_LOOPS
106 "loopgtz %2, 2f\n\t"
107#else
108 "beqz %2, 2f\n\t"
109 "slli %4, %2, 2\n\t"
110 "add %4, %4, %1\n\t"
111 "0:\t"
112#endif
113 "l32i %3, %1, 0\n\t"
114 "add %0, %0, %3\n\t"
115 "bgeu %0, %3, 1f\n\t"
116 "addi %0, %0, 1\n\t"
117 "1:\t"
118 "addi %1, %1, 4\n\t"
119#if !XCHAL_HAVE_LOOPS
120 "blt %1, %4, 0b\n\t"
121#endif
122 "2:\t"
123 /* Since the input registers which are loaded with iph and ihl
124 are modified, we must also specify them as outputs, or gcc
125 will assume they contain their original values. */
126 : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
127 : "1" (iph), "2" (ihl));
128
129 return csum_fold(sum);
130}
131
132static __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
133 unsigned long daddr,
134 unsigned short len,
135 unsigned short proto,
136 unsigned int sum)
137{
138
139#ifdef __XTENSA_EL__
140 unsigned long len_proto = (ntohs(len)<<16)+proto*256;
141#elif defined(__XTENSA_EB__)
142 unsigned long len_proto = (proto<<16)+len;
143#else
144# error processor byte order undefined!
145#endif
146 __asm__("add %0, %0, %1\n\t"
147 "bgeu %0, %1, 1f\n\t"
148 "addi %0, %0, 1\n\t"
149 "1:\t"
150 "add %0, %0, %2\n\t"
151 "bgeu %0, %2, 1f\n\t"
152 "addi %0, %0, 1\n\t"
153 "1:\t"
154 "add %0, %0, %3\n\t"
155 "bgeu %0, %3, 1f\n\t"
156 "addi %0, %0, 1\n\t"
157 "1:\t"
158 : "=r" (sum), "=r" (len_proto)
159 : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum));
160 return sum;
161}
162
163/*
164 * computes the checksum of the TCP/UDP pseudo-header
165 * returns a 16-bit checksum, already complemented
166 */
167static __inline__ unsigned short int csum_tcpudp_magic(unsigned long saddr,
168 unsigned long daddr,
169 unsigned short len,
170 unsigned short proto,
171 unsigned int sum)
172{
173 return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
174}
175
176/*
177 * this routine is used for miscellaneous IP-like checksums, mainly
178 * in icmp.c
179 */
180
181static __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len)
182{
183 return csum_fold (csum_partial(buff, len, 0));
184}
185
186#define _HAVE_ARCH_IPV6_CSUM
187static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
188 struct in6_addr *daddr,
189 __u32 len,
190 unsigned short proto,
191 unsigned int sum)
192{
193 unsigned int __dummy;
194 __asm__("l32i %1, %2, 0\n\t"
195 "add %0, %0, %1\n\t"
196 "bgeu %0, %1, 1f\n\t"
197 "addi %0, %0, 1\n\t"
198 "1:\t"
199 "l32i %1, %2, 4\n\t"
200 "add %0, %0, %1\n\t"
201 "bgeu %0, %1, 1f\n\t"
202 "addi %0, %0, 1\n\t"
203 "1:\t"
204 "l32i %1, %2, 8\n\t"
205 "add %0, %0, %1\n\t"
206 "bgeu %0, %1, 1f\n\t"
207 "addi %0, %0, 1\n\t"
208 "1:\t"
209 "l32i %1, %2, 12\n\t"
210 "add %0, %0, %1\n\t"
211 "bgeu %0, %1, 1f\n\t"
212 "addi %0, %0, 1\n\t"
213 "1:\t"
214 "l32i %1, %3, 0\n\t"
215 "add %0, %0, %1\n\t"
216 "bgeu %0, %1, 1f\n\t"
217 "addi %0, %0, 1\n\t"
218 "1:\t"
219 "l32i %1, %3, 4\n\t"
220 "add %0, %0, %1\n\t"
221 "bgeu %0, %1, 1f\n\t"
222 "addi %0, %0, 1\n\t"
223 "1:\t"
224 "l32i %1, %3, 8\n\t"
225 "add %0, %0, %1\n\t"
226 "bgeu %0, %1, 1f\n\t"
227 "addi %0, %0, 1\n\t"
228 "1:\t"
229 "l32i %1, %3, 12\n\t"
230 "add %0, %0, %1\n\t"
231 "bgeu %0, %1, 1f\n\t"
232 "addi %0, %0, 1\n\t"
233 "1:\t"
234 "add %0, %0, %4\n\t"
235 "bgeu %0, %4, 1f\n\t"
236 "addi %0, %0, 1\n\t"
237 "1:\t"
238 "add %0, %0, %5\n\t"
239 "bgeu %0, %5, 1f\n\t"
240 "addi %0, %0, 1\n\t"
241 "1:\t"
242 : "=r" (sum), "=&r" (__dummy)
243 : "r" (saddr), "r" (daddr),
244 "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
245
246 return csum_fold(sum);
247}
248
249/*
250 * Copy and checksum to user
251 */
252#define HAVE_CSUM_COPY_USER
253static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
254 int len, int sum, int *err_ptr)
255{
256 if (access_ok(VERIFY_WRITE, dst, len))
257 return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
258
259 if (len)
260 *err_ptr = -EFAULT;
261
262 return -1; /* invalid checksum */
263}
264#endif
diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h
new file mode 100644
index 000000000000..a91b96dc0efe
--- /dev/null
+++ b/include/asm-xtensa/coprocessor.h
@@ -0,0 +1,70 @@
1/*
2 * include/asm-xtensa/cpextra.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2003 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_COPROCESSOR_H
12#define _XTENSA_COPROCESSOR_H
13
14#include <xtensa/config/core.h>
15
16#define XTOFS(last_start,last_size,align) \
17 ((last_start+last_size+align-1) & -align)
18
19#define XTENSA_CP_EXTRA_OFFSET 0
20#define XTENSA_CP_EXTRA_ALIGN XCHAL_EXTRA_SA_ALIGN
21
22#define XTENSA_CPE_CP0_OFFSET \
23 XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN)
24#define XTENSA_CPE_CP1_OFFSET \
25 XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN)
26#define XTENSA_CPE_CP2_OFFSET \
27 XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN)
28#define XTENSA_CPE_CP3_OFFSET \
29 XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN)
30#define XTENSA_CPE_CP4_OFFSET \
31 XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN)
32#define XTENSA_CPE_CP5_OFFSET \
33 XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN)
34#define XTENSA_CPE_CP6_OFFSET \
35 XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN)
36#define XTENSA_CPE_CP7_OFFSET \
37 XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN)
38#define XTENSA_CP_EXTRA_SIZE \
39 XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16)
40
41#if XCHAL_CP_NUM > 0
42# ifndef __ASSEMBLY__
43/*
44 * Tasks that own contents of (last user) each coprocessor.
45 * Entries are 0 for not-owned or non-existent coprocessors.
46 * Note: The size of this structure is fixed to 8 bytes in entry.S
47 */
48typedef struct {
49 struct task_struct *owner; /* owner */
50 int offset; /* offset in cpextra space. */
51} coprocessor_info_t;
52# else
53# define COPROCESSOR_INFO_OWNER 0
54# define COPROCESSOR_INFO_OFFSET 4
55# define COPROCESSOR_INFO_SIZE 8
56# endif
57#endif
58
59
60#ifndef __ASSEMBLY__
61# if XCHAL_CP_NUM > 0
62struct task_struct;
63extern void release_coprocessors (struct task_struct*);
64extern void save_coprocessor_registers(void*, int);
65# else
66# define release_coprocessors(task)
67# endif
68#endif
69
70#endif /* _XTENSA_COPROCESSOR_H */
diff --git a/include/asm-xtensa/cpumask.h b/include/asm-xtensa/cpumask.h
new file mode 100644
index 000000000000..ebeede397db3
--- /dev/null
+++ b/include/asm-xtensa/cpumask.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/cpumask.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_CPUMASK_H
12#define _XTENSA_CPUMASK_H
13
14#include <asm-generic/cpumask.h>
15
16#endif /* _XTENSA_CPUMASK_H */
diff --git a/include/asm-xtensa/cputime.h b/include/asm-xtensa/cputime.h
new file mode 100644
index 000000000000..a7fb864a50ae
--- /dev/null
+++ b/include/asm-xtensa/cputime.h
@@ -0,0 +1,6 @@
1#ifndef _XTENSA_CPUTIME_H
2#define _XTENSA_CPUTIME_H
3
4#include <asm-generic/cputime.h>
5
6#endif /* _XTENSA_CPUTIME_H */
diff --git a/include/asm-xtensa/current.h b/include/asm-xtensa/current.h
new file mode 100644
index 000000000000..8d1eb5d78649
--- /dev/null
+++ b/include/asm-xtensa/current.h
@@ -0,0 +1,38 @@
1/*
2 * include/asm-xtensa/current.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_CURRENT_H
12#define _XTENSA_CURRENT_H
13
14#ifndef __ASSEMBLY__
15
16#include <linux/thread_info.h>
17
18struct task_struct;
19
20static inline struct task_struct *get_current(void)
21{
22 return current_thread_info()->task;
23}
24
25#define current get_current()
26
27#else
28
29#define CURRENT_SHIFT 13
30
31#define GET_CURRENT(reg,sp) \
32 GET_THREAD_INFO(reg,sp); \
33 l32i reg, reg, TI_TASK \
34
35#endif
36
37
38#endif /* XTENSA_CURRENT_H */
diff --git a/include/asm-xtensa/delay.h b/include/asm-xtensa/delay.h
new file mode 100644
index 000000000000..6359c55e77a8
--- /dev/null
+++ b/include/asm-xtensa/delay.h
@@ -0,0 +1,50 @@
1/*
2 * include/asm-xtensa/delay.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 *
10 */
11
12#ifndef _XTENSA_DELAY_H
13#define _XTENSA_DELAY_H
14
15#include <linux/config.h>
16#include <asm/processor.h>
17#include <asm/param.h>
18
19extern unsigned long loops_per_jiffy;
20
21extern __inline__ void __delay(unsigned long loops)
22{
23 /* 2 cycles per loop. */
24 __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 1, 1b"
25 : "=r" (loops) : "0" (loops));
26}
27
28static __inline__ u32 xtensa_get_ccount(void)
29{
30 u32 ccount;
31 asm volatile ("rsr %0, 234; # CCOUNT\n" : "=r" (ccount));
32 return ccount;
33}
34
35/* For SMP/NUMA systems, change boot_cpu_data to something like
36 * local_cpu_data->... where local_cpu_data points to the current
37 * cpu. */
38
39static __inline__ void udelay (unsigned long usecs)
40{
41 unsigned long start = xtensa_get_ccount();
42 unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ));
43
44 /* Note: all variables are unsigned (can wrap around)! */
45 while (((unsigned long)xtensa_get_ccount()) - start < cycles)
46 ;
47}
48
49#endif
50
diff --git a/include/asm-xtensa/div64.h b/include/asm-xtensa/div64.h
new file mode 100644
index 000000000000..c4a105776383
--- /dev/null
+++ b/include/asm-xtensa/div64.h
@@ -0,0 +1,19 @@
1/*
2 * include/asm-xtensa/div64.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_DIV64_H
12#define _XTENSA_DIV64_H
13
14#define do_div(n,base) ({ \
15 int __res = n % ((unsigned int) base); \
16 n /= (unsigned int) base; \
17 __res; })
18
19#endif
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
new file mode 100644
index 000000000000..e86a206f1209
--- /dev/null
+++ b/include/asm-xtensa/dma-mapping.h
@@ -0,0 +1,182 @@
1/*
2 * include/asm-xtensa/dma_mapping.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2003 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_DMA_MAPPING_H
12#define _XTENSA_DMA_MAPPING_H
13
14#include <asm/scatterlist.h>
15#include <asm/cache.h>
16#include <asm/io.h>
17#include <linux/mm.h>
18
19/*
20 * DMA-consistent mapping functions.
21 */
22
23extern void *consistent_alloc(int, size_t, dma_addr_t, unsigned long);
24extern void consistent_free(void*, size_t, dma_addr_t);
25extern void consistent_sync(void*, size_t, int);
26
27#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
28#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
29
30void *dma_alloc_coherent(struct device *dev, size_t size,
31 dma_addr_t *dma_handle, int flag);
32
33void dma_free_coherent(struct device *dev, size_t size,
34 void *vaddr, dma_addr_t dma_handle);
35
36static inline dma_addr_t
37dma_map_single(struct device *dev, void *ptr, size_t size,
38 enum dma_data_direction direction)
39{
40 BUG_ON(direction == DMA_NONE);
41 consistent_sync(ptr, size, direction);
42 return virt_to_phys(ptr);
43}
44
45static inline void
46dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
47 enum dma_data_direction direction)
48{
49 BUG_ON(direction == DMA_NONE);
50}
51
52static inline int
53dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
54 enum dma_data_direction direction)
55{
56 int i;
57
58 BUG_ON(direction == DMA_NONE);
59
60 for (i = 0; i < nents; i++, sg++ ) {
61 BUG_ON(!sg->page);
62
63 sg->dma_address = page_to_phys(sg->page) + sg->offset;
64 consistent_sync(page_address(sg->page) + sg->offset,
65 sg->length, direction);
66 }
67
68 return nents;
69}
70
71static inline dma_addr_t
72dma_map_page(struct device *dev, struct page *page, unsigned long offset,
73 size_t size, enum dma_data_direction direction)
74{
75 BUG_ON(direction == DMA_NONE);
76 return (dma_addr_t)(page_to_pfn(page)) * PAGE_SIZE + offset;
77}
78
79static inline void
80dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
81 enum dma_data_direction direction)
82{
83 BUG_ON(direction == DMA_NONE);
84}
85
86
87static inline void
88dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
89 enum dma_data_direction direction)
90{
91 BUG_ON(direction == DMA_NONE);
92}
93
94static inline void
95dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
96 enum dma_data_direction direction)
97{
98 consistent_sync((void *)bus_to_virt(dma_handle), size, direction);
99}
100
101static inline void
102dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
103 enum dma_data_direction direction)
104{
105 consistent_sync((void *)bus_to_virt(dma_handle), size, direction);
106}
107
108static inline void
109dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
110 unsigned long offset, size_t size,
111 enum dma_data_direction direction)
112{
113
114 consistent_sync((void *)bus_to_virt(dma_handle)+offset,size,direction);
115}
116
117static inline void
118dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
119 unsigned long offset, size_t size,
120 enum dma_data_direction direction)
121{
122
123 consistent_sync((void *)bus_to_virt(dma_handle)+offset,size,direction);
124}
125static inline void
126dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
127 enum dma_data_direction dir)
128{
129 int i;
130 for (i = 0; i < nelems; i++, sg++)
131 consistent_sync(page_address(sg->page) + sg->offset,
132 sg->length, dir);
133}
134
135static inline void
136dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
137 enum dma_data_direction dir)
138{
139 int i;
140 for (i = 0; i < nelems; i++, sg++)
141 consistent_sync(page_address(sg->page) + sg->offset,
142 sg->length, dir);
143}
144static inline int
145dma_mapping_error(dma_addr_t dma_addr)
146{
147 return 0;
148}
149
150static inline int
151dma_supported(struct device *dev, u64 mask)
152{
153 return 1;
154}
155
156static inline int
157dma_set_mask(struct device *dev, u64 mask)
158{
159 if(!dev->dma_mask || !dma_supported(dev, mask))
160 return -EIO;
161
162 *dev->dma_mask = mask;
163
164 return 0;
165}
166
167static inline int
168dma_get_cache_alignment(void)
169{
170 return L1_CACHE_BYTES;
171}
172
173#define dma_is_consistent(d) (1)
174
175static inline void
176dma_cache_sync(void *vaddr, size_t size,
177 enum dma_data_direction direction)
178{
179 consistent_sync(vaddr, size, direction);
180}
181
182#endif /* _XTENSA_DMA_MAPPING_H */
diff --git a/include/asm-xtensa/dma.h b/include/asm-xtensa/dma.h
new file mode 100644
index 000000000000..1c22b0234586
--- /dev/null
+++ b/include/asm-xtensa/dma.h
@@ -0,0 +1,61 @@
1/*
2 * include/asm-xtensa/dma.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2003 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_DMA_H
12#define _XTENSA_DMA_H
13
14#include <linux/config.h>
15#include <asm/io.h> /* need byte IO */
16#include <xtensa/config/core.h>
17
18/*
19 * This is only to be defined if we have PC-like DMA.
20 * By default this is not true on an Xtensa processor,
21 * however on boards with a PCI bus, such functionality
22 * might be emulated externally.
23 *
24 * NOTE: there still exists driver code that assumes
25 * this is defined, eg. drivers/sound/soundcard.c (as of 2.4).
26 */
27#define MAX_DMA_CHANNELS 8
28
29/*
30 * The maximum virtual address to which DMA transfers
31 * can be performed on this platform.
32 *
33 * NOTE: This is board (platform) specific, not processor-specific!
34 *
35 * NOTE: This assumes DMA transfers can only be performed on
36 * the section of physical memory contiguously mapped in virtual
37 * space for the kernel. For the Xtensa architecture, this
38 * means the maximum possible size of this DMA area is
39 * the size of the statically mapped kernel segment
40 * (XCHAL_KSEG_{CACHED,BYPASS}_SIZE), ie. 128 MB.
41 *
42 * NOTE: When the entire KSEG area is DMA capable, we substract
43 * one from the max address so that the virt_to_phys() macro
44 * works correctly on the address (otherwise the address
45 * enters another area, and virt_to_phys() may not return
46 * the value desired).
47 */
48#define MAX_DMA_ADDRESS (PAGE_OFFSET + XCHAL_KSEG_CACHED_SIZE - 1)
49
50/* Reserve and release a DMA channel */
51extern int request_dma(unsigned int dmanr, const char * device_id);
52extern void free_dma(unsigned int dmanr);
53
54#ifdef CONFIG_PCI
55extern int isa_dma_bridge_buggy;
56#else
57#define isa_dma_bridge_buggy (0)
58#endif
59
60
61#endif
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
new file mode 100644
index 000000000000..64f1f53874fe
--- /dev/null
+++ b/include/asm-xtensa/elf.h
@@ -0,0 +1,222 @@
1/*
2 * include/asm-xtensa/elf.h
3 *
4 * ELF register definitions
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_ELF_H
14#define _XTENSA_ELF_H
15
16#include <asm/ptrace.h>
17#include <asm/coprocessor.h>
18#include <xtensa/config/core.h>
19
20/* Xtensa processor ELF architecture-magic number */
21
22#define EM_XTENSA 94
23#define EM_XTENSA_OLD 0xABC7
24
25/* ELF register definitions. This is needed for core dump support. */
26
27/*
28 * elf_gregset_t contains the application-level state in the following order:
29 * Processor info: config_version, cpuxy
30 * Processor state: pc, ps, exccause, excvaddr, wb, ws,
31 * lbeg, lend, lcount, sar
32 * GP regs: ar0 - arXX
33 */
34
35typedef unsigned long elf_greg_t;
36
37typedef struct {
38 elf_greg_t xchal_config_id0;
39 elf_greg_t xchal_config_id1;
40 elf_greg_t cpux;
41 elf_greg_t cpuy;
42 elf_greg_t pc;
43 elf_greg_t ps;
44 elf_greg_t exccause;
45 elf_greg_t excvaddr;
46 elf_greg_t windowbase;
47 elf_greg_t windowstart;
48 elf_greg_t lbeg;
49 elf_greg_t lend;
50 elf_greg_t lcount;
51 elf_greg_t sar;
52 elf_greg_t syscall;
53 elf_greg_t ar[XCHAL_NUM_AREGS];
54} xtensa_gregset_t;
55
56#define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
57
58typedef elf_greg_t elf_gregset_t[ELF_NGREG];
59
60/*
61 * Compute the size of the coprocessor and extra state layout (register info)
62 * table (in bytes).
63 * This is actually the maximum size of the table, as opposed to the size,
64 * which is available from the _xtensa_reginfo_table_size global variable.
65 *
66 * (See also arch/xtensa/kernel/coprocessor.S)
67 *
68 */
69
70#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
71# define XTENSA_CPE_LTABLE_SIZE 0
72#else
73# define XTENSA_CPE_SEGMENT(num) (num ? (1+num) : 0)
74# define XTENSA_CPE_LTABLE_ENTRIES \
75 ( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM) \
76 + XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM) \
77 + XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM) \
78 + XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM) \
79 + XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM) \
80 + XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM) \
81 + XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM) \
82 + XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM) \
83 + XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM) \
84 + 1 /* final entry */ \
85 )
86# define XTENSA_CPE_LTABLE_SIZE (XTENSA_CPE_LTABLE_ENTRIES * 8)
87#endif
88
89
90/*
91 * Instantiations of the elf_fpregset_t type contain, in most
92 * architectures, the floating point (FPU) register set.
93 * For Xtensa, this type is extended to contain all custom state,
94 * ie. coprocessor and "extra" (non-coprocessor) state (including,
95 * for example, TIE-defined states and register files; as well
96 * as other optional processor state).
97 * This includes FPU state if a floating-point coprocessor happens
98 * to have been configured within the Xtensa processor.
99 *
100 * TOTAL_FPREGS_SIZE is the required size (without rounding)
101 * of elf_fpregset_t. It provides space for the following:
102 *
103 * a) 32-bit mask of active coprocessors for this task (similar
104 * to CPENABLE in single-threaded Xtensa processor systems)
105 *
106 * b) table describing the layout of custom states (ie. of
107 * individual registers, etc) within the save areas
108 *
109 * c) save areas for each coprocessor and for non-coprocessor
110 * ("extra") state
111 *
112 * Note that save areas may require up to 16-byte alignment when
113 * accessed by save/restore sequences. We do not need to ensure
114 * such alignment in an elf_fpregset_t structure because custom
115 * state is not directly loaded/stored into it; rather, save area
116 * contents are copied to elf_fpregset_t from the active save areas
117 * (see 'struct task_struct' definition in processor.h for that)
118 * using memcpy(). But we do allow space for such alignment,
119 * to allow optimizations of layout and copying.
120 */
121
122#define TOTAL_FPREGS_SIZE \
123 (4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
124#define ELF_NFPREG \
125 ((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
126
127typedef unsigned int elf_fpreg_t;
128typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
129
130#define ELF_CORE_COPY_REGS(_eregs, _pregs) \
131 xtensa_elf_core_copy_regs (&_eregs, _pregs);
132
133extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
134
135/*
136 * This is used to ensure we don't load something for the wrong architecture.
137 */
138
139#define elf_check_arch(x) ( ( (x)->e_machine == EM_XTENSA ) || \
140 ( (x)->e_machine == EM_XTENSA_OLD ) )
141
142/*
143 * These are used to set parameters in the core dumps.
144 */
145
146#ifdef __XTENSA_EL__
147# define ELF_DATA ELFDATA2LSB
148#elif defined(__XTENSA_EB__)
149# define ELF_DATA ELFDATA2MSB
150#else
151# error processor byte order undefined!
152#endif
153
154#define ELF_CLASS ELFCLASS32
155#define ELF_ARCH EM_XTENSA
156
157#define USE_ELF_CORE_DUMP
158#define ELF_EXEC_PAGESIZE PAGE_SIZE
159
160/*
161 * This is the location that an ET_DYN program is loaded if exec'ed. Typical
162 * use of this is to invoke "./ld.so someprog" to test out a new version of
163 * the loader. We need to make sure that it is out of the way of the program
164 * that it will "exec", and that there is sufficient room for the brk.
165 */
166
167#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
168
169/*
170 * This yields a mask that user programs can use to figure out what
171 * instruction set this CPU supports. This could be done in user space,
172 * but it's not easy, and we've already done it here.
173 */
174
175#define ELF_HWCAP (0)
176
177/*
178 * This yields a string that ld.so will use to load implementation
179 * specific libraries for optimization. This is more specific in
180 * intent than poking at uname or /proc/cpuinfo.
181 * For the moment, we have only optimizations for the Intel generations,
182 * but that could change...
183 */
184
185#define ELF_PLATFORM (NULL)
186
187/*
188 * The Xtensa processor ABI says that when the program starts, a2
189 * contains a pointer to a function which might be registered using
190 * `atexit'. This provides a mean for the dynamic linker to call
191 * DT_FINI functions for shared libraries that have been loaded before
192 * the code runs.
193 *
194 * A value of 0 tells we have no such handler.
195 *
196 * We might as well make sure everything else is cleared too (except
197 * for the stack pointer in a1), just to make things more
198 * deterministic. Also, clearing a0 terminates debugger backtraces.
199 */
200
201#define ELF_PLAT_INIT(_r, load_addr) \
202 do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \
203 _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \
204 _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \
205 _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \
206 } while (0)
207
208#ifdef __KERNEL__
209
210#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
211
212extern void do_copy_regs (xtensa_gregset_t*, struct pt_regs*,
213 struct task_struct*);
214extern void do_restore_regs (xtensa_gregset_t*, struct pt_regs*,
215 struct task_struct*);
216extern void do_save_fpregs (elf_fpregset_t*, struct pt_regs*,
217 struct task_struct*);
218extern int do_restore_fpregs (elf_fpregset_t*, struct pt_regs*,
219 struct task_struct*);
220
221#endif /* __KERNEL__ */
222#endif /* _XTENSA_ELF_H */
diff --git a/include/asm-xtensa/errno.h b/include/asm-xtensa/errno.h
new file mode 100644
index 000000000000..ced5194d2750
--- /dev/null
+++ b/include/asm-xtensa/errno.h
@@ -0,0 +1,142 @@
1/*
2 * include/asm-xtensa/errno.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2002 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_ERRNO_H
12#define _XTENSA_ERRNO_H
13
14#define EPERM 1 /* Operation not permitted */
15#define ENOENT 2 /* No such file or directory */
16#define ESRCH 3 /* No such process */
17#define EINTR 4 /* Interrupted system call */
18#define EIO 5 /* I/O error */
19#define ENXIO 6 /* No such device or address */
20#define E2BIG 7 /* Arg list too long */
21#define ENOEXEC 8 /* Exec format error */
22#define EBADF 9 /* Bad file number */
23#define ECHILD 10 /* No child processes */
24#define EAGAIN 11 /* Try again */
25#define ENOMEM 12 /* Out of memory */
26#define EACCES 13 /* Permission denied */
27#define EFAULT 14 /* Bad address */
28#define ENOTBLK 15 /* Block device required */
29#define EBUSY 16 /* Device or resource busy */
30#define EEXIST 17 /* File exists */
31#define EXDEV 18 /* Cross-device link */
32#define ENODEV 19 /* No such device */
33#define ENOTDIR 20 /* Not a directory */
34#define EISDIR 21 /* Is a directory */
35#define EINVAL 22 /* Invalid argument */
36#define ENFILE 23 /* File table overflow */
37#define EMFILE 24 /* Too many open files */
38#define ENOTTY 25 /* Not a typewriter */
39#define ETXTBSY 26 /* Text file busy */
40#define EFBIG 27 /* File too large */
41#define ENOSPC 28 /* No space left on device */
42#define ESPIPE 29 /* Illegal seek */
43#define EROFS 30 /* Read-only file system */
44#define EMLINK 31 /* Too many links */
45#define EPIPE 32 /* Broken pipe */
46#define EDOM 33 /* Math argument out of domain of func */
47#define ERANGE 34 /* Math result not representable */
48#define EDEADLK 35 /* Resource deadlock would occur */
49#define ENAMETOOLONG 36 /* File name too long */
50#define ENOLCK 37 /* No record locks available */
51#define ENOSYS 38 /* Function not implemented */
52#define ENOTEMPTY 39 /* Directory not empty */
53#define ELOOP 40 /* Too many symbolic links encountered */
54#define EWOULDBLOCK EAGAIN /* Operation would block */
55#define ENOMSG 42 /* No message of desired type */
56#define EIDRM 43 /* Identifier removed */
57#define ECHRNG 44 /* Channel number out of range */
58#define EL2NSYNC 45 /* Level 2 not synchronized */
59#define EL3HLT 46 /* Level 3 halted */
60#define EL3RST 47 /* Level 3 reset */
61#define ELNRNG 48 /* Link number out of range */
62#define EUNATCH 49 /* Protocol driver not attached */
63#define ENOCSI 50 /* No CSI structure available */
64#define EL2HLT 51 /* Level 2 halted */
65#define EBADE 52 /* Invalid exchange */
66#define EBADR 53 /* Invalid request descriptor */
67#define EXFULL 54 /* Exchange full */
68#define ENOANO 55 /* No anode */
69#define EBADRQC 56 /* Invalid request code */
70#define EBADSLT 57 /* Invalid slot */
71
72#define EDEADLOCK EDEADLK
73
74#define EBFONT 59 /* Bad font file format */
75#define ENOSTR 60 /* Device not a stream */
76#define ENODATA 61 /* No data available */
77#define ETIME 62 /* Timer expired */
78#define ENOSR 63 /* Out of streams resources */
79#define ENONET 64 /* Machine is not on the network */
80#define ENOPKG 65 /* Package not installed */
81#define EREMOTE 66 /* Object is remote */
82#define ENOLINK 67 /* Link has been severed */
83#define EADV 68 /* Advertise error */
84#define ESRMNT 69 /* Srmount error */
85#define ECOMM 70 /* Communication error on send */
86#define EPROTO 71 /* Protocol error */
87#define EMULTIHOP 72 /* Multihop attempted */
88#define EDOTDOT 73 /* RFS specific error */
89#define EBADMSG 74 /* Not a data message */
90#define EOVERFLOW 75 /* Value too large for defined data type */
91#define ENOTUNIQ 76 /* Name not unique on network */
92#define EBADFD 77 /* File descriptor in bad state */
93#define EREMCHG 78 /* Remote address changed */
94#define ELIBACC 79 /* Can not access a needed shared library */
95#define ELIBBAD 80 /* Accessing a corrupted shared library */
96#define ELIBSCN 81 /* .lib section in a.out corrupted */
97#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
98#define ELIBEXEC 83 /* Cannot exec a shared library directly */
99#define EILSEQ 84 /* Illegal byte sequence */
100#define ERESTART 85 /* Interrupted system call should be restarted */
101#define ESTRPIPE 86 /* Streams pipe error */
102#define EUSERS 87 /* Too many users */
103#define ENOTSOCK 88 /* Socket operation on non-socket */
104#define EDESTADDRREQ 89 /* Destination address required */
105#define EMSGSIZE 90 /* Message too long */
106#define EPROTOTYPE 91 /* Protocol wrong type for socket */
107#define ENOPROTOOPT 92 /* Protocol not available */
108#define EPROTONOSUPPORT 93 /* Protocol not supported */
109#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
110#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
111#define EPFNOSUPPORT 96 /* Protocol family not supported */
112#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
113#define EADDRINUSE 98 /* Address already in use */
114#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
115#define ENETDOWN 100 /* Network is down */
116#define ENETUNREACH 101 /* Network is unreachable */
117#define ENETRESET 102 /* Network dropped connection because of reset */
118#define ECONNABORTED 103 /* Software caused connection abort */
119#define ECONNRESET 104 /* Connection reset by peer */
120#define ENOBUFS 105 /* No buffer space available */
121#define EISCONN 106 /* Transport endpoint is already connected */
122#define ENOTCONN 107 /* Transport endpoint is not connected */
123#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
124#define ETOOMANYREFS 109 /* Too many references: cannot splice */
125#define ETIMEDOUT 110 /* Connection timed out */
126#define ECONNREFUSED 111 /* Connection refused */
127#define EHOSTDOWN 112 /* Host is down */
128#define EHOSTUNREACH 113 /* No route to host */
129#define EALREADY 114 /* Operation already in progress */
130#define EINPROGRESS 115 /* Operation now in progress */
131#define ESTALE 116 /* Stale NFS file handle */
132#define EUCLEAN 117 /* Structure needs cleaning */
133#define ENOTNAM 118 /* Not a XENIX named type file */
134#define ENAVAIL 119 /* No XENIX semaphores available */
135#define EISNAM 120 /* Is a named type file */
136#define EREMOTEIO 121 /* Remote I/O error */
137#define EDQUOT 122 /* Quota exceeded */
138
139#define ENOMEDIUM 123 /* No medium found */
140#define EMEDIUMTYPE 124 /* Wrong medium type */
141
142#endif /* _XTENSA_ERRNO_H */
diff --git a/include/asm-xtensa/fcntl.h b/include/asm-xtensa/fcntl.h
new file mode 100644
index 000000000000..48876bb727d2
--- /dev/null
+++ b/include/asm-xtensa/fcntl.h
@@ -0,0 +1,101 @@
1/*
2 * include/asm-xtensa/fcntl.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
9 * Copyright (C) 2001 - 2005 Tensilica Inc.
10 */
11
12#ifndef _XTENSA_FCNTL_H
13#define _XTENSA_FCNTL_H
14
15/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
16 located on an ext2 file system */
17#define O_ACCMODE 0x0003
18#define O_RDONLY 0x0000
19#define O_WRONLY 0x0001
20#define O_RDWR 0x0002
21#define O_APPEND 0x0008
22#define O_SYNC 0x0010
23#define O_NONBLOCK 0x0080
24#define O_CREAT 0x0100 /* not fcntl */
25#define O_TRUNC 0x0200 /* not fcntl */
26#define O_EXCL 0x0400 /* not fcntl */
27#define O_NOCTTY 0x0800 /* not fcntl */
28#define FASYNC 0x1000 /* fcntl, for BSD compatibility */
29#define O_LARGEFILE 0x2000 /* allow large file opens - currently ignored */
30#define O_DIRECT 0x8000 /* direct disk access hint - currently ignored*/
31#define O_DIRECTORY 0x10000 /* must be a directory */
32#define O_NOFOLLOW 0x20000 /* don't follow links */
33#define O_NOATIME 0x100000
34
35#define O_NDELAY O_NONBLOCK
36
37#define F_DUPFD 0 /* dup */
38#define F_GETFD 1 /* get close_on_exec */
39#define F_SETFD 2 /* set/clear close_on_exec */
40#define F_GETFL 3 /* get file->f_flags */
41#define F_SETFL 4 /* set file->f_flags */
42#define F_GETLK 14
43#define F_GETLK64 15
44#define F_SETLK 6
45#define F_SETLKW 7
46#define F_SETLK64 16
47#define F_SETLKW64 17
48
49#define F_SETOWN 24 /* for sockets. */
50#define F_GETOWN 23 /* for sockets. */
51#define F_SETSIG 10 /* for sockets. */
52#define F_GETSIG 11 /* for sockets. */
53
54/* for F_[GET|SET]FL */
55#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
56
57/* for posix fcntl() and lockf() */
58#define F_RDLCK 0
59#define F_WRLCK 1
60#define F_UNLCK 2
61
62/* for old implementation of bsd flock () */
63#define F_EXLCK 4 /* or 3 */
64#define F_SHLCK 8 /* or 4 */
65
66/* for leases */
67#define F_INPROGRESS 16
68
69/* operations for bsd flock(), also used by the kernel implementation */
70#define LOCK_SH 1 /* shared lock */
71#define LOCK_EX 2 /* exclusive lock */
72#define LOCK_NB 4 /* or'd with one of the above to prevent
73 blocking */
74#define LOCK_UN 8 /* remove lock */
75
76#define LOCK_MAND 32 /* This is a mandatory flock ... */
77#define LOCK_READ 64 /* which allows concurrent read operations */
78#define LOCK_WRITE 128 /* which allows concurrent write operations */
79#define LOCK_RW 192 /* which allows concurrent read & write ops */
80
81typedef struct flock {
82 short l_type;
83 short l_whence;
84 __kernel_off_t l_start;
85 __kernel_off_t l_len;
86 long l_sysid;
87 __kernel_pid_t l_pid;
88 long pad[4];
89} flock_t;
90
91struct flock64 {
92 short l_type;
93 short l_whence;
94 __kernel_off_t l_start;
95 __kernel_off_t l_len;
96 pid_t l_pid;
97};
98
99#define F_LINUX_SPECIFIC_BASE 1024
100
101#endif /* _XTENSA_FCNTL_H */
diff --git a/include/asm-xtensa/fixmap.h b/include/asm-xtensa/fixmap.h
new file mode 100644
index 000000000000..4423b8ad4954
--- /dev/null
+++ b/include/asm-xtensa/fixmap.h
@@ -0,0 +1,252 @@
1/*
2 * include/asm-xtensa/fixmap.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_FIXMAP_H
12#define _XTENSA_FIXMAP_H
13
14#include <asm/processor.h>
15
16#ifdef CONFIG_MMU
17
18/*
19 * Here we define all the compile-time virtual addresses.
20 */
21
22#if XCHAL_SEG_MAPPABLE_VADDR != 0
23# error "Current port requires virtual user space starting at 0"
24#endif
25#if XCHAL_SEG_MAPPABLE_SIZE < 0x80000000
26# error "Current port requires at least 0x8000000 bytes for user space"
27#endif
28
29/* Verify instruction/data ram/rom and xlmi don't overlay vmalloc space. */
30
31#define __IN_VMALLOC(addr) \
32 (((addr) >= VMALLOC_START) && ((addr) < VMALLOC_END))
33#define __SPAN_VMALLOC(start,end) \
34 (((start) < VMALLOC_START) && ((end) >= VMALLOC_END))
35#define INSIDE_VMALLOC(start,end) \
36 (__IN_VMALLOC((start)) || __IN_VMALLOC(end) || __SPAN_VMALLOC((start),(end)))
37
38#if XCHAL_NUM_INSTROM
39# if XCHAL_NUM_INSTROM == 1
40# if INSIDE_VMALLOC(XCHAL_INSTROM0_VADDR,XCHAL_INSTROM0_VADDR+XCHAL_INSTROM0_SIZE)
41# error vmalloc range conflicts with instrom0
42# endif
43# endif
44# if XCHAL_NUM_INSTROM == 2
45# if INSIDE_VMALLOC(XCHAL_INSTROM1_VADDR,XCHAL_INSTROM1_VADDR+XCHAL_INSTROM1_SIZE)
46# error vmalloc range conflicts with instrom1
47# endif
48# endif
49#endif
50
51#if XCHAL_NUM_INSTRAM
52# if XCHAL_NUM_INSTRAM == 1
53# if INSIDE_VMALLOC(XCHAL_INSTRAM0_VADDR,XCHAL_INSTRAM0_VADDR+XCHAL_INSTRAM0_SIZE)
54# error vmalloc range conflicts with instram0
55# endif
56# endif
57# if XCHAL_NUM_INSTRAM == 2
58# if INSIDE_VMALLOC(XCHAL_INSTRAM1_VADDR,XCHAL_INSTRAM1_VADDR+XCHAL_INSTRAM1_SIZE)
59# error vmalloc range conflicts with instram1
60# endif
61# endif
62#endif
63
64#if XCHAL_NUM_DATAROM
65# if XCHAL_NUM_DATAROM == 1
66# if INSIDE_VMALLOC(XCHAL_DATAROM0_VADDR,XCHAL_DATAROM0_VADDR+XCHAL_DATAROM0_SIZE)
67# error vmalloc range conflicts with datarom0
68# endif
69# endif
70# if XCHAL_NUM_DATAROM == 2
71# if INSIDE_VMALLOC(XCHAL_DATAROM1_VADDR,XCHAL_DATAROM1_VADDR+XCHAL_DATAROM1_SIZE)
72# error vmalloc range conflicts with datarom1
73# endif
74# endif
75#endif
76
77#if XCHAL_NUM_DATARAM
78# if XCHAL_NUM_DATARAM == 1
79# if INSIDE_VMALLOC(XCHAL_DATARAM0_VADDR,XCHAL_DATARAM0_VADDR+XCHAL_DATARAM0_SIZE)
80# error vmalloc range conflicts with dataram0
81# endif
82# endif
83# if XCHAL_NUM_DATARAM == 2
84# if INSIDE_VMALLOC(XCHAL_DATARAM1_VADDR,XCHAL_DATARAM1_VADDR+XCHAL_DATARAM1_SIZE)
85# error vmalloc range conflicts with dataram1
86# endif
87# endif
88#endif
89
90#if XCHAL_NUM_XLMI
91# if XCHAL_NUM_XLMI == 1
92# if INSIDE_VMALLOC(XCHAL_XLMI0_VADDR,XCHAL_XLMI0_VADDR+XCHAL_XLMI0_SIZE)
93# error vmalloc range conflicts with xlmi0
94# endif
95# endif
96# if XCHAL_NUM_XLMI == 2
97# if INSIDE_VMALLOC(XCHAL_XLMI1_VADDR,XCHAL_XLMI1_VADDR+XCHAL_XLMI1_SIZE)
98# error vmalloc range conflicts with xlmi1
99# endif
100# endif
101#endif
102
103#if (XCHAL_NUM_INSTROM > 2) || \
104 (XCHAL_NUM_INSTRAM > 2) || \
105 (XCHAL_NUM_DATARAM > 2) || \
106 (XCHAL_NUM_DATAROM > 2) || \
107 (XCHAL_NUM_XLMI > 2)
108# error Insufficient checks on vmalloc above for more than 2 devices
109#endif
110
111/*
112 * USER_VM_SIZE does not necessarily equal TASK_SIZE. We bumped
113 * TASK_SIZE down to 0x4000000 to simplify the handling of windowed
114 * call instructions (currently limited to a range of 1 GByte). User
115 * tasks may very well reclaim the VM space from 0x40000000 to
116 * 0x7fffffff in the future, so we do not want the kernel becoming
117 * accustomed to having any of its stuff (e.g., page tables) in this
118 * region. This VM region is no-man's land for now.
119 */
120
121#define USER_VM_START XCHAL_SEG_MAPPABLE_VADDR
122#define USER_VM_SIZE 0x80000000
123
124/* Size of page table: */
125
126#define PGTABLE_SIZE_BITS (32 - XCHAL_MMU_MIN_PTE_PAGE_SIZE + 2)
127#define PGTABLE_SIZE (1L << PGTABLE_SIZE_BITS)
128
129/* All kernel-mappable space: */
130
131#define KERNEL_ALLMAP_START (USER_VM_START + USER_VM_SIZE)
132#define KERNEL_ALLMAP_SIZE (XCHAL_SEG_MAPPABLE_SIZE - KERNEL_ALLMAP_START)
133
134/* Carve out page table at start of kernel-mappable area: */
135
136#if KERNEL_ALLMAP_SIZE < PGTABLE_SIZE
137#error "Gimme some space for page table!"
138#endif
139#define PGTABLE_START KERNEL_ALLMAP_START
140
141/* Remaining kernel-mappable space: */
142
143#define KERNEL_MAPPED_START (KERNEL_ALLMAP_START + PGTABLE_SIZE)
144#define KERNEL_MAPPED_SIZE (KERNEL_ALLMAP_SIZE - PGTABLE_SIZE)
145
146#if KERNEL_MAPPED_SIZE < 0x01000000 /* 16 MB is arbitrary for now */
147# error "Shouldn't the kernel have at least *some* mappable space?"
148#endif
149
150#define MAX_LOW_MEMORY XCHAL_KSEG_CACHED_SIZE
151
152#endif
153
154/*
155 * Some constants used elsewhere, but perhaps only in Xtensa header
156 * files, so maybe we can get rid of some and access compile-time HAL
157 * directly...
158 *
159 * Note: We assume that system RAM is located at the very start of the
160 * kernel segments !!
161 */
162#define KERNEL_VM_LOW XCHAL_KSEG_CACHED_VADDR
163#define KERNEL_VM_HIGH XCHAL_KSEG_BYPASS_VADDR
164#define KERNEL_SPACE XCHAL_KSEG_CACHED_VADDR
165
166/*
167 * Returns the physical/virtual addresses of the kernel space
168 * (works with the cached kernel segment only, which is the
169 * one normally used for kernel operation).
170 */
171
172/* PHYSICAL BYPASS CACHED
173 *
174 * bypass vaddr bypass paddr * cached vaddr
175 * cached vaddr cached paddr bypass vaddr *
176 * bypass paddr * bypass vaddr cached vaddr
177 * cached paddr * bypass vaddr cached vaddr
178 * other * * *
179 */
180
181#define PHYSADDR(a) \
182(((unsigned)(a) >= XCHAL_KSEG_BYPASS_VADDR \
183 && (unsigned)(a) < XCHAL_KSEG_BYPASS_VADDR + XCHAL_KSEG_BYPASS_SIZE) ? \
184 (unsigned)(a) - XCHAL_KSEG_BYPASS_VADDR + XCHAL_KSEG_BYPASS_PADDR : \
185 ((unsigned)(a) >= XCHAL_KSEG_CACHED_VADDR \
186 && (unsigned)(a) < XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_CACHED_SIZE) ? \
187 (unsigned)(a) - XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_CACHED_PADDR : \
188 (unsigned)(a))
189
190#define BYPASS_ADDR(a) \
191(((unsigned)(a) >= XCHAL_KSEG_BYPASS_PADDR \
192 && (unsigned)(a) < XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_SIZE) ? \
193 (unsigned)(a) - XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_VADDR : \
194 ((unsigned)(a) >= XCHAL_KSEG_CACHED_PADDR \
195 && (unsigned)(a) < XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_SIZE) ? \
196 (unsigned)(a) - XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_BYPASS_VADDR : \
197 ((unsigned)(a) >= XCHAL_KSEG_CACHED_VADDR \
198 && (unsigned)(a) < XCHAL_KSEG_CACHED_VADDR+XCHAL_KSEG_CACHED_SIZE)? \
199 (unsigned)(a) - XCHAL_KSEG_CACHED_VADDR+XCHAL_KSEG_BYPASS_VADDR: \
200 (unsigned)(a))
201
202#define CACHED_ADDR(a) \
203(((unsigned)(a) >= XCHAL_KSEG_BYPASS_PADDR \
204 && (unsigned)(a) < XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_SIZE) ? \
205 (unsigned)(a) - XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_CACHED_VADDR : \
206 ((unsigned)(a) >= XCHAL_KSEG_CACHED_PADDR \
207 && (unsigned)(a) < XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_SIZE) ? \
208 (unsigned)(a) - XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_VADDR : \
209 ((unsigned)(a) >= XCHAL_KSEG_BYPASS_VADDR \
210 && (unsigned)(a) < XCHAL_KSEG_BYPASS_VADDR+XCHAL_KSEG_BYPASS_SIZE) ? \
211 (unsigned)(a) - XCHAL_KSEG_BYPASS_VADDR+XCHAL_KSEG_CACHED_VADDR : \
212 (unsigned)(a))
213
214#define PHYSADDR_IO(a) \
215(((unsigned)(a) >= XCHAL_KIO_BYPASS_VADDR \
216 && (unsigned)(a) < XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_SIZE) ? \
217 (unsigned)(a) - XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_PADDR : \
218 ((unsigned)(a) >= XCHAL_KIO_CACHED_VADDR \
219 && (unsigned)(a) < XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_SIZE) ? \
220 (unsigned)(a) - XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_PADDR : \
221 (unsigned)(a))
222
223#define BYPASS_ADDR_IO(a) \
224(((unsigned)(a) >= XCHAL_KIO_BYPASS_PADDR \
225 && (unsigned)(a) < XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_SIZE) ? \
226 (unsigned)(a) - XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_VADDR : \
227 ((unsigned)(a) >= XCHAL_KIO_CACHED_PADDR \
228 && (unsigned)(a) < XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_SIZE) ? \
229 (unsigned)(a) - XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_BYPASS_VADDR : \
230 ((unsigned)(a) >= XCHAL_KIO_CACHED_VADDR \
231 && (unsigned)(a) < XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_SIZE) ? \
232 (unsigned)(a) - XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_BYPASS_VADDR : \
233 (unsigned)(a))
234
235#define CACHED_ADDR_IO(a) \
236(((unsigned)(a) >= XCHAL_KIO_BYPASS_PADDR \
237 && (unsigned)(a) < XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_SIZE) ? \
238 (unsigned)(a) - XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_CACHED_VADDR : \
239 ((unsigned)(a) >= XCHAL_KIO_CACHED_PADDR \
240 && (unsigned)(a) < XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_SIZE) ? \
241 (unsigned)(a) - XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_VADDR : \
242 ((unsigned)(a) >= XCHAL_KIO_BYPASS_VADDR \
243 && (unsigned)(a) < XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_SIZE) ? \
244 (unsigned)(a) - XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_CACHED_VADDR : \
245 (unsigned)(a))
246
247#endif /* _XTENSA_ADDRSPACE_H */
248
249
250
251
252
diff --git a/include/asm-xtensa/hardirq.h b/include/asm-xtensa/hardirq.h
new file mode 100644
index 000000000000..e07c76c36b95
--- /dev/null
+++ b/include/asm-xtensa/hardirq.h
@@ -0,0 +1,28 @@
1/*
2 * include/asm-xtensa/hardirq.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2002 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_HARDIRQ_H
12#define _XTENSA_HARDIRQ_H
13
14#include <linux/config.h>
15#include <linux/cache.h>
16#include <asm/irq.h>
17
18/* headers.S is sensitive to the offsets of these fields */
19typedef struct {
20 unsigned int __softirq_pending;
21 unsigned int __syscall_count;
22 struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
23 unsigned int __nmi_count; /* arch dependent */
24} ____cacheline_aligned irq_cpustat_t;
25
26#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
27
28#endif /* _XTENSA_HARDIRQ_H */
diff --git a/include/asm-xtensa/hdreg.h b/include/asm-xtensa/hdreg.h
new file mode 100644
index 000000000000..64b80607b80d
--- /dev/null
+++ b/include/asm-xtensa/hdreg.h
@@ -0,0 +1,17 @@
1/*
2 * include/asm-xtensa/hdreg.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2002 - 2005 Tensilica Inc.
9 * Copyright (C) 1994-1996 Linus Torvalds & authors
10 */
11
12#ifndef _XTENSA_HDREG_H
13#define _XTENSA_HDREG_H
14
15typedef unsigned int ide_ioreg_t;
16
17#endif
diff --git a/include/asm-xtensa/highmem.h b/include/asm-xtensa/highmem.h
new file mode 100644
index 000000000000..0a046ca5a687
--- /dev/null
+++ b/include/asm-xtensa/highmem.h
@@ -0,0 +1,17 @@
1/*
2 * include/asm-xtensa/highmem.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2003 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_HIGHMEM_H
12#define _XTENSA_HIGHMEM_H
13
14extern void flush_cache_kmaps(void);
15
16#endif
17
diff --git a/include/asm-xtensa/hw_irq.h b/include/asm-xtensa/hw_irq.h
new file mode 100644
index 000000000000..ccf436249eaa
--- /dev/null
+++ b/include/asm-xtensa/hw_irq.h
@@ -0,0 +1,18 @@
1/*
2 * include/asm-xtensa/hw_irq.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2002 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_HW_IRQ_H
12#define _XTENSA_HW_IRQ_H
13
14static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
15{
16}
17
18#endif
diff --git a/include/asm-xtensa/ide.h b/include/asm-xtensa/ide.h
new file mode 100644
index 000000000000..b523cd4a486e
--- /dev/null
+++ b/include/asm-xtensa/ide.h
@@ -0,0 +1,36 @@
1/*
2 * include/asm-xtensa/ide.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1994 - 1996 Linus Torvalds & authors
9 * Copyright (C) 2001 - 2005 Tensilica Inc.
10 */
11
12#ifndef _XTENSA_IDE_H
13#define _XTENSA_IDE_H
14
15#ifdef __KERNEL__
16
17#include <linux/config.h>
18
19#ifndef MAX_HWIFS
20# define MAX_HWIFS 1
21#endif
22
23static __inline__ int ide_default_irq(unsigned long base)
24{
25 /* Unsupported! */
26 return 0;
27}
28
29static __inline__ unsigned long ide_default_io_base(int index)
30{
31 /* Unsupported! */
32 return 0;
33}
34
35#endif /* __KERNEL__ */
36#endif /* _XTENSA_IDE_H */
diff --git a/include/asm-xtensa/io.h b/include/asm-xtensa/io.h
new file mode 100644
index 000000000000..2c471c42ecfc
--- /dev/null
+++ b/include/asm-xtensa/io.h
@@ -0,0 +1,197 @@
1/*
2 * linux/include/asm-xtensa/io.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_IO_H
12#define _XTENSA_IO_H
13
14#ifdef __KERNEL__
15#include <linux/config.h>
16#include <asm/byteorder.h>
17
18#include <linux/types.h>
19#include <asm/fixmap.h>
20
21#define _IO_BASE 0
22
23
24/*
25 * swap functions to change byte order from little-endian to big-endian and
26 * vice versa.
27 */
28
29static inline unsigned short _swapw (unsigned short v)
30{
31 return (v << 8) | (v >> 8);
32}
33
34static inline unsigned int _swapl (unsigned int v)
35{
36 return (v << 24) | ((v & 0xff00) << 8) | ((v >> 8) & 0xff00) | (v >> 24);
37}
38
39/*
40 * Change virtual addresses to physical addresses and vv.
41 * These are trivial on the 1:1 Linux/Xtensa mapping
42 */
43
44extern inline unsigned long virt_to_phys(volatile void * address)
45{
46 return PHYSADDR((unsigned long)address);
47}
48
49extern inline void * phys_to_virt(unsigned long address)
50{
51 return (void*) CACHED_ADDR(address);
52}
53
54/*
55 * IO bus memory addresses are also 1:1 with the physical address
56 */
57
58extern inline unsigned long virt_to_bus(volatile void * address)
59{
60 return PHYSADDR((unsigned long)address);
61}
62
63extern inline void * bus_to_virt (unsigned long address)
64{
65 return (void *) CACHED_ADDR(address);
66}
67
68/*
69 * Change "struct page" to physical address.
70 */
71
72extern inline void *ioremap(unsigned long offset, unsigned long size)
73{
74 return (void *) CACHED_ADDR_IO(offset);
75}
76
77extern inline void *ioremap_nocache(unsigned long offset, unsigned long size)
78{
79 return (void *) BYPASS_ADDR_IO(offset);
80}
81
82extern inline void iounmap(void *addr)
83{
84}
85
86/*
87 * Generic I/O
88 */
89
90#define readb(addr) \
91 ({ unsigned char __v = (*(volatile unsigned char *)(addr)); __v; })
92#define readw(addr) \
93 ({ unsigned short __v = (*(volatile unsigned short *)(addr)); __v; })
94#define readl(addr) \
95 ({ unsigned int __v = (*(volatile unsigned int *)(addr)); __v; })
96#define writeb(b, addr) (void)((*(volatile unsigned char *)(addr)) = (b))
97#define writew(b, addr) (void)((*(volatile unsigned short *)(addr)) = (b))
98#define writel(b, addr) (void)((*(volatile unsigned int *)(addr)) = (b))
99
100static inline __u8 __raw_readb(const volatile void __iomem *addr)
101{
102 return *(__force volatile __u8 *)(addr);
103}
104static inline __u16 __raw_readw(const volatile void __iomem *addr)
105{
106 return *(__force volatile __u16 *)(addr);
107}
108static inline __u32 __raw_readl(const volatile void __iomem *addr)
109{
110 return *(__force volatile __u32 *)(addr);
111}
112static inline void __raw_writeb(__u8 b, volatile void __iomem *addr)
113{
114 *(__force volatile __u8 *)(addr) = b;
115}
116static inline void __raw_writew(__u16 b, volatile void __iomem *addr)
117{
118 *(__force volatile __u16 *)(addr) = b;
119}
120static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
121{
122 *(__force volatile __u32 *)(addr) = b;
123}
124
125
126
127
128/* These are the definitions for the x86 IO instructions
129 * inb/inw/inl/outb/outw/outl, the "string" versions
130 * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
131 * inb_p/inw_p/...
132 * The macros don't do byte-swapping.
133 */
134
135#define inb(port) readb((u8 *)((port)+_IO_BASE))
136#define outb(val, port) writeb((val),(u8 *)((unsigned long)(port)+_IO_BASE))
137#define inw(port) readw((u16 *)((port)+_IO_BASE))
138#define outw(val, port) writew((val),(u16 *)((unsigned long)(port)+_IO_BASE))
139#define inl(port) readl((u32 *)((port)+_IO_BASE))
140#define outl(val, port) writel((val),(u32 *)((unsigned long)(port)))
141
142#define inb_p(port) inb((port))
143#define outb_p(val, port) outb((val), (port))
144#define inw_p(port) inw((port))
145#define outw_p(val, port) outw((val), (port))
146#define inl_p(port) inl((port))
147#define outl_p(val, port) outl((val), (port))
148
149extern void insb (unsigned long port, void *dst, unsigned long count);
150extern void insw (unsigned long port, void *dst, unsigned long count);
151extern void insl (unsigned long port, void *dst, unsigned long count);
152extern void outsb (unsigned long port, const void *src, unsigned long count);
153extern void outsw (unsigned long port, const void *src, unsigned long count);
154extern void outsl (unsigned long port, const void *src, unsigned long count);
155
156#define IO_SPACE_LIMIT ~0
157
158#define memset_io(a,b,c) memset((void *)(a),(b),(c))
159#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
160#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
161
162/* At this point the Xtensa doesn't provide byte swap instructions */
163
164#ifdef __XTENSA_EB__
165# define in_8(addr) (*(u8*)(addr))
166# define in_le16(addr) _swapw(*(u16*)(addr))
167# define in_le32(addr) _swapl(*(u32*)(addr))
168# define out_8(b, addr) *(u8*)(addr) = (b)
169# define out_le16(b, addr) *(u16*)(addr) = _swapw(b)
170# define out_le32(b, addr) *(u32*)(addr) = _swapl(b)
171#elif defined(__XTENSA_EL__)
172# define in_8(addr) (*(u8*)(addr))
173# define in_le16(addr) (*(u16*)(addr))
174# define in_le32(addr) (*(u32*)(addr))
175# define out_8(b, addr) *(u8*)(addr) = (b)
176# define out_le16(b, addr) *(u16*)(addr) = (b)
177# define out_le32(b, addr) *(u32*)(addr) = (b)
178#else
179# error processor byte order undefined!
180#endif
181
182
183/*
184 * * Convert a physical pointer to a virtual kernel pointer for /dev/mem
185 * * access
186 * */
187#define xlate_dev_mem_ptr(p) __va(p)
188
189/*
190 * * Convert a virtual cached pointer to an uncached pointer
191 * */
192#define xlate_dev_kmem_ptr(p) p
193
194
195#endif /* __KERNEL__ */
196
197#endif /* _XTENSA_IO_H */
diff --git a/include/asm-xtensa/ioctl.h b/include/asm-xtensa/ioctl.h
new file mode 100644
index 000000000000..856c605d62b1
--- /dev/null
+++ b/include/asm-xtensa/ioctl.h
@@ -0,0 +1,83 @@
1/*
2 * include/asm-xtensa/ioctl.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2003 - 2005 Tensilica Inc.
9 *
10 * Derived from "include/asm-i386/ioctl.h"
11 */
12
13#ifndef _XTENSA_IOCTL_H
14#define _XTENSA_IOCTL_H
15
16
17/* ioctl command encoding: 32 bits total, command in lower 16 bits,
18 * size of the parameter structure in the lower 14 bits of the
19 * upper 16 bits.
20 * Encoding the size of the parameter structure in the ioctl request
21 * is useful for catching programs compiled with old versions
22 * and to avoid overwriting user space outside the user buffer area.
23 * The highest 2 bits are reserved for indicating the ``access mode''.
24 * NOTE: This limits the max parameter size to 16kB -1 !
25 */
26
27/*
28 * The following is for compatibility across the various Linux
29 * platforms. The i386 ioctl numbering scheme doesn't really enforce
30 * a type field. De facto, however, the top 8 bits of the lower 16
31 * bits are indeed used as a type field, so we might just as well make
32 * this explicit here. Please be sure to use the decoding macros
33 * below from now on.
34 */
35#define _IOC_NRBITS 8
36#define _IOC_TYPEBITS 8
37#define _IOC_SIZEBITS 14
38#define _IOC_DIRBITS 2
39
40#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
41#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
42#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
43#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
44
45#define _IOC_NRSHIFT 0
46#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
47#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
48#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
49
50/*
51 * Direction bits.
52 */
53#define _IOC_NONE 0U
54#define _IOC_WRITE 1U
55#define _IOC_READ 2U
56
57#define _IOC(dir,type,nr,size) \
58 (((dir) << _IOC_DIRSHIFT) | \
59 ((type) << _IOC_TYPESHIFT) | \
60 ((nr) << _IOC_NRSHIFT) | \
61 ((size) << _IOC_SIZESHIFT))
62
63/* used to create numbers */
64#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
65#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
66#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
67#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
68
69/* used to decode ioctl numbers.. */
70#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
71#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
72#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
73#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
74
75/* ...and for the drivers/sound files... */
76
77#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
78#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
79#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
80#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
81#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
82
83#endif
diff --git a/include/asm-xtensa/ioctls.h b/include/asm-xtensa/ioctls.h
new file mode 100644
index 000000000000..10c443435c11
--- /dev/null
+++ b/include/asm-xtensa/ioctls.h
@@ -0,0 +1,112 @@
1/*
2 * include/asm-xtensa/ioctl.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2003 - 2005 Tensilica Inc.
9 *
10 * Derived from "include/asm-i386/ioctls.h"
11 */
12
13#ifndef _XTENSA_IOCTLS_H
14#define _XTENSA_IOCTLS_H
15
16#include <asm/ioctl.h>
17
18#define FIOCLEX _IO('f', 1)
19#define FIONCLEX _IO('f', 2)
20#define FIOASYNC _IOW('f', 125, int)
21#define FIONBIO _IOW('f', 126, int)
22#define FIONREAD _IOR('f', 127, int)
23#define TIOCINQ FIONREAD
24#define FIOQSIZE _IOR('f', 128, loff_t)
25
26#define TCGETS 0x5401
27#define TCSETS 0x5402
28#define TCSETSW 0x5403
29#define TCSETSF 0x5404
30
31#define TCGETA _IOR('t', 23, struct termio)
32#define TCSETA _IOW('t', 24, struct termio)
33#define TCSETAW _IOW('t', 25, struct termio)
34#define TCSETAF _IOW('t', 28, struct termio)
35
36#define TCSBRK _IO('t', 29)
37#define TCXONC _IO('t', 30)
38#define TCFLSH _IO('t', 31)
39
40#define TIOCSWINSZ _IOW('t', 103, struct winsize)
41#define TIOCGWINSZ _IOR('t', 104, struct winsize)
42#define TIOCSTART _IO('t', 110) /* start output, like ^Q */
43#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */
44#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */
45
46#define TIOCSPGRP _IOW('t', 118, int)
47#define TIOCGPGRP _IOR('t', 119, int)
48
49#define TIOCEXCL _IO('T', 12)
50#define TIOCNXCL _IO('T', 13)
51#define TIOCSCTTY _IO('T', 14)
52
53#define TIOCSTI _IOW('T', 18, char)
54#define TIOCMGET _IOR('T', 21, unsigned int)
55#define TIOCMBIS _IOW('T', 22, unsigned int)
56#define TIOCMBIC _IOW('T', 23, unsigned int)
57#define TIOCMSET _IOW('T', 24, unsigned int)
58# define TIOCM_LE 0x001
59# define TIOCM_DTR 0x002
60# define TIOCM_RTS 0x004
61# define TIOCM_ST 0x008
62# define TIOCM_SR 0x010
63# define TIOCM_CTS 0x020
64# define TIOCM_CAR 0x040
65# define TIOCM_RNG 0x080
66# define TIOCM_DSR 0x100
67# define TIOCM_CD TIOCM_CAR
68# define TIOCM_RI TIOCM_RNG
69
70#define TIOCGSOFTCAR _IOR('T', 25, unsigned int)
71#define TIOCSSOFTCAR _IOW('T', 26, unsigned int)
72#define TIOCLINUX _IOW('T', 28, char)
73#define TIOCCONS _IO('T', 29)
74#define TIOCGSERIAL _IOR('T', 30, struct serial_struct)
75#define TIOCSSERIAL _IOW('T', 31, struct serial_struct)
76#define TIOCPKT _IOW('T', 32, int)
77# define TIOCPKT_DATA 0
78# define TIOCPKT_FLUSHREAD 1
79# define TIOCPKT_FLUSHWRITE 2
80# define TIOCPKT_STOP 4
81# define TIOCPKT_START 8
82# define TIOCPKT_NOSTOP 16
83# define TIOCPKT_DOSTOP 32
84
85
86#define TIOCNOTTY _IO('T', 34)
87#define TIOCSETD _IOW('T', 35, int)
88#define TIOCGETD _IOR('T', 36, int)
89#define TCSBRKP _IOW('T', 37, int) /* Needed for POSIX tcsendbreak()*/
90#define TIOCTTYGSTRUCT _IOR('T', 38, struct tty_struct) /* For debugging only*/
91#define TIOCSBRK _IO('T', 39) /* BSD compatibility */
92#define TIOCCBRK _IO('T', 40) /* BSD compatibility */
93#define TIOCGSID _IOR('T', 41, pid_t) /* Return the session ID of FD*/
94#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
95#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
96
97#define TIOCSERCONFIG _IO('T', 83)
98#define TIOCSERGWILD _IOR('T', 84, int)
99#define TIOCSERSWILD _IOW('T', 85, int)
100#define TIOCGLCKTRMIOS 0x5456
101#define TIOCSLCKTRMIOS 0x5457
102#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
103#define TIOCSERGETLSR _IOR('T', 89, unsigned int) /* Get line status reg. */
104 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
105# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
106#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* Get multiport config */
107#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */
108
109#define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */
110#define TIOCGICOUNT _IOR('T', 93, struct async_icount) /* read serial port inline interrupt counts */
111
112#endif /* _XTENSA_IOCTLS_H */
diff --git a/include/asm-xtensa/ipc.h b/include/asm-xtensa/ipc.h
new file mode 100644
index 000000000000..d37bdb4d4c9c
--- /dev/null
+++ b/include/asm-xtensa/ipc.h
@@ -0,0 +1,34 @@
1/*
2 * include/asm-xtensa/ipc.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_IPC_H
12#define _XTENSA_IPC_H
13
14struct ipc_kludge {
15 struct msgbuf __user *msgp;
16 long msgtyp;
17};
18
19#define SEMOP 1
20#define SEMGET 2
21#define SEMCTL 3
22#define SEMTIMEDOP 4
23#define MSGSND 11
24#define MSGRCV 12
25#define MSGGET 13
26#define MSGCTL 14
27#define SHMAT 21
28#define SHMDT 22
29#define SHMGET 23
30#define SHMCTL 24
31
32#define IPCCALL(version,op) ((version)<<16 | (op))
33
34#endif /* _XTENSA_IPC_H */
diff --git a/include/asm-xtensa/ipcbuf.h b/include/asm-xtensa/ipcbuf.h
new file mode 100644
index 000000000000..c33aa6a42145
--- /dev/null
+++ b/include/asm-xtensa/ipcbuf.h
@@ -0,0 +1,37 @@
1/*
2 * include/asm-xtensa/ipcbuf.h
3 *
4 * The ipc64_perm structure for the Xtensa architecture.
5 * Note extra padding because this structure is passed back and forth
6 * between kernel and user space.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_IPCBUF_H
12#define _XTENSA_IPCBUF_H
13
14/*
15 * Pad space is left for:
16 * - 32-bit mode_t and seq
17 * - 2 miscellaneous 32-bit values
18 *
19 * This file is subject to the terms and conditions of the GNU General
20 * Public License. See the file "COPYING" in the main directory of
21 * this archive for more details.
22 */
23
24struct ipc64_perm
25{
26 __kernel_key_t key;
27 __kernel_uid32_t uid;
28 __kernel_gid32_t gid;
29 __kernel_uid32_t cuid;
30 __kernel_gid32_t cgid;
31 __kernel_mode_t mode;
32 unsigned long seq;
33 unsigned long __unused1;
34 unsigned long __unused2;
35};
36
37#endif /* _XTENSA_IPCBUF_H */
diff --git a/include/asm-xtensa/irq.h b/include/asm-xtensa/irq.h
new file mode 100644
index 000000000000..d984e955938f
--- /dev/null
+++ b/include/asm-xtensa/irq.h
@@ -0,0 +1,37 @@
1/*
2 * include/asm-xtensa/irq.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_IRQ_H
12#define _XTENSA_IRQ_H
13
14#include <linux/config.h>
15#include <asm/platform/hardware.h>
16
17#include <xtensa/config/core.h>
18
19#ifndef PLATFORM_NR_IRQS
20# define PLATFORM_NR_IRQS 0
21#endif
22#define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS
23#define NR_IRQS (XTENSA_NR_IRQS + PLATFORM_NR_IRQS)
24
25static __inline__ int irq_canonicalize(int irq)
26{
27 return (irq);
28}
29
30struct irqaction;
31#if 0 // FIXME
32extern void disable_irq_nosync(unsigned int);
33extern void disable_irq(unsigned int);
34extern void enable_irq(unsigned int);
35#endif
36
37#endif /* _XTENSA_IRQ_H */
diff --git a/include/asm-xtensa/kmap_types.h b/include/asm-xtensa/kmap_types.h
new file mode 100644
index 000000000000..9e822d2e3bce
--- /dev/null
+++ b/include/asm-xtensa/kmap_types.h
@@ -0,0 +1,31 @@
1/*
2 * include/asm-xtensa/kmap_types.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_KMAP_TYPES_H
12#define _XTENSA_KMAP_TYPES_H
13
14enum km_type {
15 KM_BOUNCE_READ,
16 KM_SKB_SUNRPC_DATA,
17 KM_SKB_DATA_SOFTIRQ,
18 KM_USER0,
19 KM_USER1,
20 KM_BIO_SRC_IRQ,
21 KM_BIO_DST_IRQ,
22 KM_PTE0,
23 KM_PTE1,
24 KM_IRQ0,
25 KM_IRQ1,
26 KM_SOFTIRQ0,
27 KM_SOFTIRQ1,
28 KM_TYPE_NR
29};
30
31#endif /* _XTENSA_KMAP_TYPES_H */
diff --git a/include/asm-xtensa/linkage.h b/include/asm-xtensa/linkage.h
new file mode 100644
index 000000000000..bf2128a99d79
--- /dev/null
+++ b/include/asm-xtensa/linkage.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/linkage.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_LINKAGE_H
12#define _XTENSA_LINKAGE_H
13
14/* Nothing to do here ... */
15
16#endif /* _XTENSA_LINKAGE_H */
diff --git a/include/asm-xtensa/local.h b/include/asm-xtensa/local.h
new file mode 100644
index 000000000000..48723e550d14
--- /dev/null
+++ b/include/asm-xtensa/local.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/local.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_LOCAL_H
12#define _XTENSA_LOCAL_H
13
14#include <asm-generic/local.h>
15
16#endif /* _XTENSA_LOCAL_H */
diff --git a/include/asm-xtensa/mman.h b/include/asm-xtensa/mman.h
new file mode 100644
index 000000000000..9a95a45df996
--- /dev/null
+++ b/include/asm-xtensa/mman.h
@@ -0,0 +1,80 @@
1/*
2 * include/asm-xtensa/mman.h
3 *
4 * Xtensa Processor memory-manager definitions
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 1995 by Ralf Baechle
11 * Copyright (C) 2001 - 2005 Tensilica Inc.
12 */
13
14#ifndef _XTENSA_MMAN_H
15#define _XTENSA_MMAN_H
16
17/*
18 * Protections are chosen from these bits, OR'd together. The
19 * implementation does not necessarily support PROT_EXEC or PROT_WRITE
20 * without PROT_READ. The only guarantees are that no writing will be
21 * allowed without PROT_WRITE and no access will be allowed for PROT_NONE.
22 */
23
24#define PROT_NONE 0x0 /* page can not be accessed */
25#define PROT_READ 0x1 /* page can be read */
26#define PROT_WRITE 0x2 /* page can be written */
27#define PROT_EXEC 0x4 /* page can be executed */
28
29#define PROT_SEM 0x10 /* page may be used for atomic ops */
30#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
31#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end fo growsup vma */
32
33/*
34 * Flags for mmap
35 */
36#define MAP_SHARED 0x001 /* Share changes */
37#define MAP_PRIVATE 0x002 /* Changes are private */
38#define MAP_TYPE 0x00f /* Mask for type of mapping */
39#define MAP_FIXED 0x010 /* Interpret addr exactly */
40
41/* not used by linux, but here to make sure we don't clash with ABI defines */
42#define MAP_RENAME 0x020 /* Assign page to file */
43#define MAP_AUTOGROW 0x040 /* File may grow by writing */
44#define MAP_LOCAL 0x080 /* Copy on fork/sproc */
45#define MAP_AUTORSRV 0x100 /* Logical swap reserved on demand */
46
47/* These are linux-specific */
48#define MAP_NORESERVE 0x0400 /* don't check for reservations */
49#define MAP_ANONYMOUS 0x0800 /* don't use a file */
50#define MAP_GROWSDOWN 0x1000 /* stack-like segment */
51#define MAP_DENYWRITE 0x2000 /* ETXTBSY */
52#define MAP_EXECUTABLE 0x4000 /* mark it as an executable */
53#define MAP_LOCKED 0x8000 /* pages are locked */
54#define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */
55#define MAP_NONBLOCK 0x20000 /* do not block on IO */
56
57/*
58 * Flags for msync
59 */
60#define MS_ASYNC 0x0001 /* sync memory asynchronously */
61#define MS_INVALIDATE 0x0002 /* invalidate mappings & caches */
62#define MS_SYNC 0x0004 /* synchronous memory sync */
63
64/*
65 * Flags for mlockall
66 */
67#define MCL_CURRENT 1 /* lock all current mappings */
68#define MCL_FUTURE 2 /* lock all future mappings */
69
70#define MADV_NORMAL 0x0 /* default page-in behavior */
71#define MADV_RANDOM 0x1 /* page-in minimum required */
72#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */
73#define MADV_WILLNEED 0x3 /* pre-fault pages */
74#define MADV_DONTNEED 0x4 /* discard these pages */
75
76/* compatibility flags */
77#define MAP_ANON MAP_ANONYMOUS
78#define MAP_FILE 0
79
80#endif /* _XTENSA_MMAN_H */
diff --git a/include/asm-xtensa/mmu.h b/include/asm-xtensa/mmu.h
new file mode 100644
index 000000000000..44c5bb04c55c
--- /dev/null
+++ b/include/asm-xtensa/mmu.h
@@ -0,0 +1,17 @@
1/*
2 * include/asm-xtensa/mmu.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_MMU_H
12#define _XTENSA_MMU_H
13
14/* Default "unsigned long" context */
15typedef unsigned long mm_context_t;
16
17#endif /* _XTENSA_MMU_H */
diff --git a/include/asm-xtensa/mmu_context.h b/include/asm-xtensa/mmu_context.h
new file mode 100644
index 000000000000..1b0801548cd9
--- /dev/null
+++ b/include/asm-xtensa/mmu_context.h
@@ -0,0 +1,330 @@
1/*
2 * include/asm-xtensa/mmu_context.h
3 *
4 * Switch an MMU context.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_MMU_CONTEXT_H
14#define _XTENSA_MMU_CONTEXT_H
15
16#include <linux/config.h>
17#include <linux/stringify.h>
18
19#include <asm/pgtable.h>
20#include <asm/mmu_context.h>
21#include <asm/cacheflush.h>
22#include <asm/tlbflush.h>
23
24/*
25 * Linux was ported to Xtensa assuming all auto-refill ways in set 0
26 * had the same properties (a very likely assumption). Multiple sets
27 * of auto-refill ways will still work properly, but not as optimally
28 * as the Xtensa designer may have assumed.
29 *
30 * We make this case a hard #error, killing the kernel build, to alert
31 * the developer to this condition (which is more likely an error).
32 * You super-duper clever developers can change it to a warning or
33 * remove it altogether if you think you know what you're doing. :)
34 */
35
36#if (XCHAL_HAVE_TLBS != 1)
37# error "Linux must have an MMU!"
38#endif
39
40#if ((XCHAL_ITLB_ARF_WAYS == 0) || (XCHAL_DTLB_ARF_WAYS == 0))
41# error "MMU must have auto-refill ways"
42#endif
43
44#if ((XCHAL_ITLB_ARF_SETS != 1) || (XCHAL_DTLB_ARF_SETS != 1))
45# error Linux may not use all auto-refill ways as efficiently as you think
46#endif
47
48#if (XCHAL_MMU_MAX_PTE_PAGE_SIZE != XCHAL_MMU_MIN_PTE_PAGE_SIZE)
49# error Only one page size allowed!
50#endif
51
52extern unsigned long asid_cache;
53extern pgd_t *current_pgd;
54
55/*
56 * Define the number of entries per auto-refill way in set 0 of both I and D
57 * TLBs. We deal only with set 0 here (an assumption further explained in
58 * assertions.h). Also, define the total number of ARF entries in both TLBs.
59 */
60
61#define ITLB_ENTRIES_PER_ARF_WAY (XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,ENTRIES))
62#define DTLB_ENTRIES_PER_ARF_WAY (XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,ENTRIES))
63
64#define ITLB_ENTRIES \
65 (ITLB_ENTRIES_PER_ARF_WAY * (XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,WAYS)))
66#define DTLB_ENTRIES \
67 (DTLB_ENTRIES_PER_ARF_WAY * (XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,WAYS)))
68
69
70/*
71 * SMALLEST_NTLB_ENTRIES is the smaller of ITLB_ENTRIES and DTLB_ENTRIES.
72 * In practice, they are probably equal. This macro simplifies function
73 * flush_tlb_range().
74 */
75
76#if (DTLB_ENTRIES < ITLB_ENTRIES)
77# define SMALLEST_NTLB_ENTRIES DTLB_ENTRIES
78#else
79# define SMALLEST_NTLB_ENTRIES ITLB_ENTRIES
80#endif
81
82
83/*
84 * asid_cache tracks only the ASID[USER_RING] field of the RASID special
85 * register, which is the current user-task asid allocation value.
86 * mm->context has the same meaning. When it comes time to write the
87 * asid_cache or mm->context values to the RASID special register, we first
88 * shift the value left by 8, then insert the value.
89 * ASID[0] always contains the kernel's asid value, and we reserve three
90 * other asid values that we never assign to user tasks.
91 */
92
93#define ASID_INC 0x1
94#define ASID_MASK ((1 << XCHAL_MMU_ASID_BITS) - 1)
95
96/*
97 * XCHAL_MMU_ASID_INVALID is a configurable Xtensa processor constant
98 * indicating invalid address space. XCHAL_MMU_ASID_KERNEL is a configurable
99 * Xtensa processor constant indicating the kernel address space. They can
100 * be arbitrary values.
101 *
102 * We identify three more unique, reserved ASID values to use in the unused
103 * ring positions. No other user process will be assigned these reserved
104 * ASID values.
105 *
106 * For example, given that
107 *
108 * XCHAL_MMU_ASID_INVALID == 0
109 * XCHAL_MMU_ASID_KERNEL == 1
110 *
111 * the following maze of #if statements would generate
112 *
113 * ASID_RESERVED_1 == 2
114 * ASID_RESERVED_2 == 3
115 * ASID_RESERVED_3 == 4
116 * ASID_FIRST_NONRESERVED == 5
117 */
118
119#if (XCHAL_MMU_ASID_INVALID != XCHAL_MMU_ASID_KERNEL + 1)
120# define ASID_RESERVED_1 ((XCHAL_MMU_ASID_KERNEL + 1) & ASID_MASK)
121#else
122# define ASID_RESERVED_1 ((XCHAL_MMU_ASID_KERNEL + 2) & ASID_MASK)
123#endif
124
125#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_1 + 1)
126# define ASID_RESERVED_2 ((ASID_RESERVED_1 + 1) & ASID_MASK)
127#else
128# define ASID_RESERVED_2 ((ASID_RESERVED_1 + 2) & ASID_MASK)
129#endif
130
131#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_2 + 1)
132# define ASID_RESERVED_3 ((ASID_RESERVED_2 + 1) & ASID_MASK)
133#else
134# define ASID_RESERVED_3 ((ASID_RESERVED_2 + 2) & ASID_MASK)
135#endif
136
137#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_3 + 1)
138# define ASID_FIRST_NONRESERVED ((ASID_RESERVED_3 + 1) & ASID_MASK)
139#else
140# define ASID_FIRST_NONRESERVED ((ASID_RESERVED_3 + 2) & ASID_MASK)
141#endif
142
143#define ASID_ALL_RESERVED ( ((ASID_RESERVED_1) << 24) + \
144 ((ASID_RESERVED_2) << 16) + \
145 ((ASID_RESERVED_3) << 8) + \
146 ((XCHAL_MMU_ASID_KERNEL)) )
147
148
149/*
150 * NO_CONTEXT is the invalid ASID value that we don't ever assign to
151 * any user or kernel context. NO_CONTEXT is a better mnemonic than
152 * XCHAL_MMU_ASID_INVALID, so we use it in code instead.
153 */
154
155#define NO_CONTEXT XCHAL_MMU_ASID_INVALID
156
157#if (KERNEL_RING != 0)
158# error The KERNEL_RING really should be zero.
159#endif
160
161#if (USER_RING >= XCHAL_MMU_RINGS)
162# error USER_RING cannot be greater than the highest numbered ring.
163#endif
164
165#if (USER_RING == KERNEL_RING)
166# error The user and kernel rings really should not be equal.
167#endif
168
169#if (USER_RING == 1)
170#define ASID_INSERT(x) ( ((ASID_RESERVED_1) << 24) + \
171 ((ASID_RESERVED_2) << 16) + \
172 (((x) & (ASID_MASK)) << 8) + \
173 ((XCHAL_MMU_ASID_KERNEL)) )
174
175#elif (USER_RING == 2)
176#define ASID_INSERT(x) ( ((ASID_RESERVED_1) << 24) + \
177 (((x) & (ASID_MASK)) << 16) + \
178 ((ASID_RESERVED_2) << 8) + \
179 ((XCHAL_MMU_ASID_KERNEL)) )
180
181#elif (USER_RING == 3)
182#define ASID_INSERT(x) ( (((x) & (ASID_MASK)) << 24) + \
183 ((ASID_RESERVED_1) << 16) + \
184 ((ASID_RESERVED_2) << 8) + \
185 ((XCHAL_MMU_ASID_KERNEL)) )
186
187#else
188#error Goofy value for USER_RING
189
190#endif /* USER_RING == 1 */
191
192
193/*
194 * All unused by hardware upper bits will be considered
195 * as a software asid extension.
196 */
197
198#define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
199#define ASID_FIRST_VERSION \
200 ((unsigned long)(~ASID_VERSION_MASK) + 1 + ASID_FIRST_NONRESERVED)
201
202extern inline void set_rasid_register (unsigned long val)
203{
204 __asm__ __volatile__ (" wsr %0, "__stringify(RASID)"\n\t"
205 " isync\n" : : "a" (val));
206}
207
208extern inline unsigned long get_rasid_register (void)
209{
210 unsigned long tmp;
211 __asm__ __volatile__ (" rsr %0, "__stringify(RASID)"\n\t" : "=a" (tmp));
212 return tmp;
213}
214
215
216#if ((XCHAL_MMU_ASID_INVALID == 0) && (XCHAL_MMU_ASID_KERNEL == 1))
217
218extern inline void
219get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
220{
221 extern void flush_tlb_all(void);
222 if (! ((asid += ASID_INC) & ASID_MASK) ) {
223 flush_tlb_all(); /* start new asid cycle */
224 if (!asid) /* fix version if needed */
225 asid = ASID_FIRST_VERSION - ASID_FIRST_NONRESERVED;
226 asid += ASID_FIRST_NONRESERVED;
227 }
228 mm->context = asid_cache = asid;
229}
230
231#else
232#warning ASID_{INVALID,KERNEL} values impose non-optimal get_new_mmu_context implementation
233
234/* XCHAL_MMU_ASID_INVALID == 0 and XCHAL_MMU_ASID_KERNEL ==1 are
235 really the best, but if you insist... */
236
237extern inline int validate_asid (unsigned long asid)
238{
239 switch (asid) {
240 case XCHAL_MMU_ASID_INVALID:
241 case XCHAL_MMU_ASID_KERNEL:
242 case ASID_RESERVED_1:
243 case ASID_RESERVED_2:
244 case ASID_RESERVED_3:
245 return 0; /* can't use these values as ASIDs */
246 }
247 return 1; /* valid */
248}
249
250extern inline void
251get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
252{
253 extern void flush_tlb_all(void);
254 while (1) {
255 asid += ASID_INC;
256 if ( ! (asid & ASID_MASK) ) {
257 flush_tlb_all(); /* start new asid cycle */
258 if (!asid) /* fix version if needed */
259 asid = ASID_FIRST_VERSION - ASID_FIRST_NONRESERVED;
260 asid += ASID_FIRST_NONRESERVED;
261 break; /* no need to validate here */
262 }
263 if (validate_asid (asid & ASID_MASK))
264 break;
265 }
266 mm->context = asid_cache = asid;
267}
268
269#endif
270
271
272/*
273 * Initialize the context related info for a new mm_struct
274 * instance.
275 */
276
277extern inline int
278init_new_context(struct task_struct *tsk, struct mm_struct *mm)
279{
280 mm->context = NO_CONTEXT;
281 return 0;
282}
283
284extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
285 struct task_struct *tsk)
286{
287 unsigned long asid = asid_cache;
288
289 /* Check if our ASID is of an older version and thus invalid */
290
291 if ((next->context ^ asid) & ASID_VERSION_MASK)
292 get_new_mmu_context(next, asid);
293
294 set_rasid_register (ASID_INSERT(next->context));
295 invalidate_page_directory();
296}
297
298#define deactivate_mm(tsk, mm) do { } while(0)
299
300/*
301 * Destroy context related info for an mm_struct that is about
302 * to be put to rest.
303 */
304extern inline void destroy_context(struct mm_struct *mm)
305{
306 /* Nothing to do. */
307}
308
309/*
310 * After we have set current->mm to a new value, this activates
311 * the context for the new mm so we see the new mappings.
312 */
313extern inline void
314activate_mm(struct mm_struct *prev, struct mm_struct *next)
315{
316 /* Unconditionally get a new ASID. */
317
318 get_new_mmu_context(next, asid_cache);
319 set_rasid_register (ASID_INSERT(next->context));
320 invalidate_page_directory();
321}
322
323
324static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
325{
326 /* Nothing to do. */
327
328}
329
330#endif /* _XTENSA_MMU_CONTEXT_H */
diff --git a/include/asm-xtensa/module.h b/include/asm-xtensa/module.h
new file mode 100644
index 000000000000..ffb25bfdf6a1
--- /dev/null
+++ b/include/asm-xtensa/module.h
@@ -0,0 +1,25 @@
1/*
2 * include/asm-xtensa/module.h
3 *
4 * This file contains the module code specific to the Xtensa architecture.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_MODULE_H
14#define _XTENSA_MODULE_H
15
16struct mod_arch_specific
17{
18 /* Module support is not completely implemented. */
19};
20
21#define Elf_Shdr Elf32_Shdr
22#define Elf_Sym Elf32_Sym
23#define Elf_Ehdr Elf32_Ehdr
24
25#endif /* _XTENSA_MODULE_H */
diff --git a/include/asm-xtensa/msgbuf.h b/include/asm-xtensa/msgbuf.h
new file mode 100644
index 000000000000..693c96755280
--- /dev/null
+++ b/include/asm-xtensa/msgbuf.h
@@ -0,0 +1,48 @@
1/*
2 * include/asm-xtensa/msgbuf.h
3 *
4 * The msqid64_ds structure for the Xtensa architecture.
5 * Note extra padding because this structure is passed back and forth
6 * between kernel and user space.
7 *
8 * Pad space is left for:
9 * - 64-bit time_t to solve y2038 problem
10 * - 2 miscellaneous 32-bit values
11 *
12 * This file is subject to the terms and conditions of the GNU General
13 * Public License. See the file "COPYING" in the main directory of
14 * this archive for more details.
15 */
16
17#ifndef _XTENSA_MSGBUF_H
18#define _XTENSA_MSGBUF_H
19
20struct msqid64_ds {
21 struct ipc64_perm msg_perm;
22#ifdef __XTENSA_EB__
23 unsigned int __unused1;
24 __kernel_time_t msg_stime; /* last msgsnd time */
25 unsigned int __unused2;
26 __kernel_time_t msg_rtime; /* last msgrcv time */
27 unsigned int __unused3;
28 __kernel_time_t msg_ctime; /* last change time */
29#elif defined(__XTENSA_EL__)
30 __kernel_time_t msg_stime; /* last msgsnd time */
31 unsigned int __unused1;
32 __kernel_time_t msg_rtime; /* last msgrcv time */
33 unsigned int __unused2;
34 __kernel_time_t msg_ctime; /* last change time */
35 unsigned int __unused3;
36#else
37# error processor byte order undefined!
38#endif
39 unsigned long msg_cbytes; /* current number of bytes on queue */
40 unsigned long msg_qnum; /* number of messages in queue */
41 unsigned long msg_qbytes; /* max number of bytes on queue */
42 __kernel_pid_t msg_lspid; /* pid of last msgsnd */
43 __kernel_pid_t msg_lrpid; /* last receive pid */
44 unsigned long __unused4;
45 unsigned long __unused5;
46};
47
48#endif /* _XTENSA_MSGBUF_H */
diff --git a/include/asm-xtensa/namei.h b/include/asm-xtensa/namei.h
new file mode 100644
index 000000000000..3fdff039d27d
--- /dev/null
+++ b/include/asm-xtensa/namei.h
@@ -0,0 +1,26 @@
1/*
2 * include/asm-xtensa/namei.h
3 *
4 * Included from linux/fs/namei.c
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_NAMEI_H
14#define _XTENSA_NAMEI_H
15
16#ifdef __KERNEL__
17
18/* This dummy routine maybe changed to something useful
19 * for /usr/gnemul/ emulation stuff.
20 * Look at asm-sparc/namei.h for details.
21 */
22
23#define __emul_prefix() NULL
24
25#endif /* __KERNEL__ */
26#endif /* _XTENSA_NAMEI_H */
diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h
new file mode 100644
index 000000000000..b495e5b5a942
--- /dev/null
+++ b/include/asm-xtensa/page.h
@@ -0,0 +1,133 @@
1/*
2 * linux/include/asm-xtensa/page.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version2 as
6 * published by the Free Software Foundation.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PAGE_H
12#define _XTENSA_PAGE_H
13
14#ifdef __KERNEL__
15
16#include <asm/processor.h>
17#include <linux/config.h>
18
19/*
20 * PAGE_SHIFT determines the page size
21 * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary
22 */
23
24#define PAGE_SHIFT XCHAL_MMU_MIN_PTE_PAGE_SIZE
25#define PAGE_SIZE (1 << PAGE_SHIFT)
26#define PAGE_MASK (~(PAGE_SIZE-1))
27#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE - 1) & PAGE_MASK)
28
29#define DCACHE_WAY_SIZE (XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS)
30#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR
31
32#ifdef __ASSEMBLY__
33
34#define __pgprot(x) (x)
35
36#else
37
38/*
39 * These are used to make use of C type-checking..
40 */
41
42typedef struct { unsigned long pte; } pte_t; /* page table entry */
43typedef struct { unsigned long pgd; } pgd_t; /* PGD table entry */
44typedef struct { unsigned long pgprot; } pgprot_t;
45
46#define pte_val(x) ((x).pte)
47#define pgd_val(x) ((x).pgd)
48#define pgprot_val(x) ((x).pgprot)
49
50#define __pte(x) ((pte_t) { (x) } )
51#define __pgd(x) ((pgd_t) { (x) } )
52#define __pgprot(x) ((pgprot_t) { (x) } )
53
54/*
55 * Pure 2^n version of get_order
56 */
57
58extern __inline__ int get_order(unsigned long size)
59{
60 int order;
61#ifndef XCHAL_HAVE_NSU
62 unsigned long x1, x2, x4, x8, x16;
63
64 size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
65 x1 = size & 0xAAAAAAAA;
66 x2 = size & 0xCCCCCCCC;
67 x4 = size & 0xF0F0F0F0;
68 x8 = size & 0xFF00FF00;
69 x16 = size & 0xFFFF0000;
70 order = x2 ? 2 : 0;
71 order += (x16 != 0) * 16;
72 order += (x8 != 0) * 8;
73 order += (x4 != 0) * 4;
74 order += (x1 != 0);
75
76 return order;
77#else
78 size = (size - 1) >> PAGE_SHIFT;
79 asm ("nsau %0, %1" : "=r" (order) : "r" (size));
80 return 32 - order;
81#endif
82}
83
84
85struct page;
86extern void clear_page(void *page);
87extern void copy_page(void *to, void *from);
88
89/*
90 * If we have cache aliasing and writeback caches, we might have to do
91 * some extra work
92 */
93
94#if (DCACHE_WAY_SIZE > PAGE_SIZE)
95void clear_user_page(void *addr, unsigned long vaddr, struct page* page);
96void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page);
97#else
98# define clear_user_page(page,vaddr,pg) clear_page(page)
99# define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
100#endif
101
102/*
103 * This handles the memory map. We handle pages at
104 * XCHAL_KSEG_CACHED_VADDR for kernels with 32 bit address space.
105 * These macros are for conversion of kernel address, not user
106 * addresses.
107 */
108
109#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
110#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
111#define pfn_valid(pfn) ((unsigned long)pfn < max_mapnr)
112#ifndef CONFIG_DISCONTIGMEM
113# define pfn_to_page(pfn) (mem_map + (pfn))
114# define page_to_pfn(page) ((unsigned long)((page) - mem_map))
115#else
116# error CONFIG_DISCONTIGMEM not supported
117#endif
118
119#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
120#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT)
121#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
122#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
123
124#define WANT_PAGE_VIRTUAL
125
126
127#endif /* __ASSEMBLY__ */
128
129#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
130 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
131
132#endif /* __KERNEL__ */
133#endif /* _XTENSA_PAGE_H */
diff --git a/include/asm-xtensa/page.h.n b/include/asm-xtensa/page.h.n
new file mode 100644
index 000000000000..546cc6624f24
--- /dev/null
+++ b/include/asm-xtensa/page.h.n
@@ -0,0 +1,135 @@
1/*
2 * linux/include/asm-xtensa/page.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version2 as
6 * published by the Free Software Foundation.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PAGE_H
12#define _XTENSA_PAGE_H
13
14#ifdef __KERNEL__
15
16#include <asm/processor.h>
17#include <linux/config.h>
18
19/*
20 * PAGE_SHIFT determines the page size
21 * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary
22 */
23#define PAGE_SHIFT XCHAL_MMU_MIN_PTE_PAGE_SIZE
24#define PAGE_SIZE (1 << PAGE_SHIFT)
25#define PAGE_MASK (~(PAGE_SIZE-1))
26#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE - 1) & PAGE_MASK)
27
28#define DCACHE_WAY_SIZE (XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS)
29#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR
30
31#ifdef __ASSEMBLY__
32
33#define __pgprot(x) (x)
34
35#else
36
37
38/*
39 * These are used to make use of C type-checking..
40 */
41typedef struct { unsigned long pte; } pte_t; /* page table entry */
42typedef struct { unsigned long pmd; } pmd_t; /* PMD table entry */
43typedef struct { unsigned long pgd; } pgd_t; /* PGD table entry */
44typedef struct { unsigned long pgprot; } pgprot_t;
45
46#define pte_val(x) ((x).pte)
47#define pmd_val(x) ((x).pmd)
48#define pgd_val(x) ((x).pgd)
49#define pgprot_val(x) ((x).pgprot)
50
51#define __pte(x) ((pte_t) { (x) } )
52#define __pmd(x) ((pmd_t) { (x) } )
53#define __pgd(x) ((pgd_t) { (x) } )
54#define __pgprot(x) ((pgprot_t) { (x) } )
55
56/*
57 * Pure 2^n version of get_order
58 */
59extern __inline__ int get_order(unsigned long size)
60{
61 int order;
62#ifndef XCHAL_HAVE_NSU
63 unsigned long x1, x2, x4, x8, x16;
64
65 size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
66 x1 = size & 0xAAAAAAAA;
67 x2 = size & 0xCCCCCCCC;
68 x4 = size & 0xF0F0F0F0;
69 x8 = size & 0xFF00FF00;
70 x16 = size & 0xFFFF0000;
71 order = x2 ? 2 : 0;
72 order += (x16 != 0) * 16;
73 order += (x8 != 0) * 8;
74 order += (x4 != 0) * 4;
75 order += (x1 != 0);
76
77 return order;
78#else
79 size = (size - 1) >> PAGE_SHIFT;
80 asm ("nsau %0, %1" : "=r" (order) : "r" (size));
81 return 32 - order;
82#endif
83}
84
85
86struct page;
87extern void clear_page(void *page);
88extern void copy_page(void *to, void *from);
89
90/*
91 * If we have cache aliasing and writeback caches, we might have to do
92 * some extra work
93 */
94
95#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
96void clear_user_page(void *addr, unsigned long vaddr, struct page* page);
97void copy_user_page(void *to, void* from, unsigned long vaddr, struct page* page);
98#else
99# define clear_user_page(page,vaddr,pg) clear_page(page)
100# define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
101#endif
102
103
104/*
105 * This handles the memory map. We handle pages at
106 * XCHAL_KSEG_CACHED_VADDR for kernels with 32 bit address space.
107 * These macros are for conversion of kernel address, not user
108 * addresses.
109 */
110
111#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
112#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
113#define pfn_valid(pfn) ((unsigned long)pfn < max_mapnr)
114#ifndef CONFIG_DISCONTIGMEM
115# define pfn_to_page(pfn) (mem_map + (pfn))
116# define page_to_pfn(page) ((unsigned long)((page) - mem_map))
117#else
118# error CONFIG_DISCONTIGMEM not supported
119#endif
120
121#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
122#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT)
123#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
124#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
125
126#define WANT_PAGE_VIRTUAL
127
128
129#endif /* __ASSEMBLY__ */
130
131#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
132 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
133
134#endif /* __KERNEL__ */
135#endif /* _XTENSA_PAGE_H */
diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h
new file mode 100644
index 000000000000..c0eec8260b0e
--- /dev/null
+++ b/include/asm-xtensa/param.h
@@ -0,0 +1,34 @@
1/*
2 * include/asm-xtensa/param.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PARAM_H
12#define _XTENSA_PARAM_H
13
14#include <xtensa/config/core.h>
15
16#ifdef __KERNEL__
17# define HZ 100 /* internal timer frequency */
18# define USER_HZ 100 /* for user interfaces in "ticks" */
19# define CLOCKS_PER_SEC (USER_HZ) /* frequnzy at which times() counts */
20#endif
21
22#define EXEC_PAGESIZE (1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
23
24#ifndef NGROUPS
25#define NGROUPS 32
26#endif
27
28#ifndef NOGROUP
29#define NOGROUP (-1)
30#endif
31
32#define MAXHOSTNAMELEN 64 /* max length of hostname */
33
34#endif /* _XTENSA_PARAM_H */
diff --git a/include/asm-xtensa/pci-bridge.h b/include/asm-xtensa/pci-bridge.h
new file mode 100644
index 000000000000..00fcbd7c534a
--- /dev/null
+++ b/include/asm-xtensa/pci-bridge.h
@@ -0,0 +1,88 @@
1/*
2 * include/asm-xtensa/pci-bridge.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PCI_BRIDGE_H
12#define _XTENSA_PCI_BRIDGE_H
13
14#ifdef __KERNEL__
15
16struct device_node;
17struct pci_controller;
18
19/*
20 * pciauto_bus_scan() enumerates the pci space.
21 */
22
23extern int pciauto_bus_scan(struct pci_controller *, int);
24
25struct pci_space {
26 unsigned long start;
27 unsigned long end;
28 unsigned long base;
29};
30
31/*
32 * Structure of a PCI controller (host bridge)
33 */
34
35struct pci_controller {
36 int index; /* used for pci_controller_num */
37 struct pci_controller *next;
38 struct pci_bus *bus;
39 void *arch_data;
40
41 int first_busno;
42 int last_busno;
43
44 struct pci_ops *ops;
45 volatile unsigned int *cfg_addr;
46 volatile unsigned char *cfg_data;
47
48 /* Currently, we limit ourselves to 1 IO range and 3 mem
49 * ranges since the common pci_bus structure can't handle more
50 */
51 struct resource io_resource;
52 struct resource mem_resources[3];
53 int mem_resource_count;
54
55 /* Host bridge I/O and Memory space
56 * Used for BAR placement algorithms
57 */
58 struct pci_space io_space;
59 struct pci_space mem_space;
60
61 /* Return the interrupt number fo a device. */
62 int (*map_irq)(struct pci_dev*, u8, u8);
63
64};
65
66static inline void pcibios_init_resource(struct resource *res,
67 unsigned long start, unsigned long end, int flags, char *name)
68{
69 res->start = start;
70 res->end = end;
71 res->flags = flags;
72 res->name = name;
73 res->parent = NULL;
74 res->sibling = NULL;
75 res->child = NULL;
76}
77
78
79/* These are used for config access before all the PCI probing has been done. */
80int early_read_config_byte(struct pci_controller*, int, int, int, u8*);
81int early_read_config_word(struct pci_controller*, int, int, int, u16*);
82int early_read_config_dword(struct pci_controller*, int, int, int, u32*);
83int early_write_config_byte(struct pci_controller*, int, int, int, u8);
84int early_write_config_word(struct pci_controller*, int, int, int, u16);
85int early_write_config_dword(struct pci_controller*, int, int, int, u32);
86
87#endif /* __KERNEL__ */
88#endif /* _XTENSA_PCI_BRIDGE_H */
diff --git a/include/asm-xtensa/pci.h b/include/asm-xtensa/pci.h
new file mode 100644
index 000000000000..6817742301c2
--- /dev/null
+++ b/include/asm-xtensa/pci.h
@@ -0,0 +1,89 @@
1/*
2 * linux/include/asm-xtensa/pci.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PCI_H
12#define _XTENSA_PCI_H
13
14#ifdef __KERNEL__
15
16/* Can be used to override the logic in pci_scan_bus for skipping
17 * already-configured bus numbers - to be used for buggy BIOSes
18 * or architectures with incomplete PCI setup by the loader
19 */
20
21#define pcibios_assign_all_busses() 0
22
23extern struct pci_controller* pcibios_alloc_controller(void);
24
25extern inline void pcibios_set_master(struct pci_dev *dev)
26{
27 /* No special bus mastering setup handling */
28}
29
30extern inline void pcibios_penalize_isa_irq(int irq)
31{
32 /* We don't do dynamic PCI IRQ allocation */
33}
34
35/* Assume some values. (We should revise them, if necessary) */
36
37#define PCIBIOS_MIN_IO 0x2000
38#define PCIBIOS_MIN_MEM 0x10000000
39
40/* Dynamic DMA mapping stuff.
41 * Xtensa has everything mapped statically like x86.
42 */
43
44#include <linux/types.h>
45#include <linux/slab.h>
46#include <asm/scatterlist.h>
47#include <linux/string.h>
48#include <asm/io.h>
49
50struct pci_dev;
51
52/* The PCI address space does equal the physical memory address space.
53 * The networking and block device layers use this boolean for bounce buffer
54 * decisions.
55 */
56
57#define PCI_DMA_BUS_IS_PHYS (1)
58
59/* pci_unmap_{page,single} is a no-op, so */
60#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
61#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
62#define pci_unmap_addr(PTR, ADDR_NAME) (0)
63#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
64#define pci_ubnmap_len(PTR, LEN_NAME) (0)
65#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
66
67/* We cannot access memory above 4GB */
68#define pci_dac_dma_supported(pci_dev, mask) (0)
69
70/* Map a range of PCI memory or I/O space for a device into user space */
71int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
72 enum pci_mmap_state mmap_state, int write_combine);
73
74/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
75#define HAVE_PCI_MMAP 1
76
77static inline void pcibios_add_platform_entries(struct pci_dev *dev)
78{
79}
80
81#endif /* __KERNEL__ */
82
83/* Implement the pci_ DMA API in terms of the generic device dma_ one */
84#include <asm-generic/pci-dma-compat.h>
85
86/* Generic PCI */
87#include <asm-generic/pci.h>
88
89#endif /* _XTENSA_PCI_H */
diff --git a/include/asm-xtensa/percpu.h b/include/asm-xtensa/percpu.h
new file mode 100644
index 000000000000..6d2bc2ada9d1
--- /dev/null
+++ b/include/asm-xtensa/percpu.h
@@ -0,0 +1,16 @@
1/*
2 * linux/include/asm-xtensa/percpu.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PERCPU__
12#define _XTENSA_PERCPU__
13
14#include <asm-generic/percpu.h>
15
16#endif /* _XTENSA_PERCPU__ */
diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h
new file mode 100644
index 000000000000..734a8d060395
--- /dev/null
+++ b/include/asm-xtensa/pgalloc.h
@@ -0,0 +1,116 @@
1/*
2 * linux/include/asm-xtensa/pgalloc.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Copyright (C) 2001-2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PGALLOC_H
12#define _XTENSA_PGALLOC_H
13
14#ifdef __KERNEL__
15
16#include <linux/config.h>
17#include <linux/threads.h>
18#include <linux/highmem.h>
19#include <asm/processor.h>
20#include <asm/cacheflush.h>
21
22
23/* Cache aliasing:
24 *
25 * If the cache size for one way is greater than the page size, we have to
26 * deal with cache aliasing. The cache index is wider than the page size:
27 *
28 * |cache |
29 * |pgnum |page| virtual address
30 * |xxxxxX|zzzz|
31 * | | |
32 * \ / | |
33 * trans.| |
34 * / \ | |
35 * |yyyyyY|zzzz| physical address
36 *
37 * When the page number is translated to the physical page address, the lowest
38 * bit(s) (X) that are also part of the cache index are also translated (Y).
39 * If this translation changes this bit (X), the cache index is also afected,
40 * thus resulting in a different cache line than before.
41 * The kernel does not provide a mechanism to ensure that the page color
42 * (represented by this bit) remains the same when allocated or when pages
43 * are remapped. When user pages are mapped into kernel space, the color of
44 * the page might also change.
45 *
46 * We use the address space VMALLOC_END ... VMALLOC_END + DCACHE_WAY_SIZE * 2
47 * to temporarily map a patch so we can match the color.
48 */
49
50#if (DCACHE_WAY_SIZE > PAGE_SIZE)
51# define PAGE_COLOR_MASK (PAGE_MASK & (DCACHE_WAY_SIZE-1))
52# define PAGE_COLOR(a) \
53 (((unsigned long)(a)&PAGE_COLOR_MASK) >> PAGE_SHIFT)
54# define PAGE_COLOR_EQ(a,b) \
55 ((((unsigned long)(a) ^ (unsigned long)(b)) & PAGE_COLOR_MASK) == 0)
56# define PAGE_COLOR_MAP0(v) \
57 (VMALLOC_END + ((unsigned long)(v) & PAGE_COLOR_MASK))
58# define PAGE_COLOR_MAP1(v) \
59 (VMALLOC_END + ((unsigned long)(v) & PAGE_COLOR_MASK) + DCACHE_WAY_SIZE)
60#endif
61
62/*
63 * Allocating and freeing a pmd is trivial: the 1-entry pmd is
64 * inside the pgd, so has no extra memory associated with it.
65 */
66
67#define pgd_free(pgd) free_page((unsigned long)(pgd))
68
69#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
70
71static inline void
72pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *pte)
73{
74 pmd_val(*(pmdp)) = (unsigned long)(pte);
75 __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
76}
77
78static inline void
79pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *page)
80{
81 pmd_val(*(pmdp)) = (unsigned long)page_to_virt(page);
82 __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
83}
84
85
86
87#else
88
89# define pmd_populate_kernel(mm, pmdp, pte) \
90 (pmd_val(*(pmdp)) = (unsigned long)(pte))
91# define pmd_populate(mm, pmdp, page) \
92 (pmd_val(*(pmdp)) = (unsigned long)page_to_virt(page))
93
94#endif
95
96static inline pgd_t*
97pgd_alloc(struct mm_struct *mm)
98{
99 pgd_t *pgd;
100
101 pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGD_ORDER);
102
103 if (likely(pgd != NULL))
104 __flush_dcache_page((unsigned long)pgd);
105
106 return pgd;
107}
108
109extern pte_t* pte_alloc_one_kernel(struct mm_struct* mm, unsigned long addr);
110extern struct page* pte_alloc_one(struct mm_struct* mm, unsigned long addr);
111
112#define pte_free_kernel(pte) free_page((unsigned long)pte)
113#define pte_free(pte) __free_page(pte)
114
115#endif /* __KERNEL__ */
116#endif /* _XTENSA_PGALLOC_H */
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
new file mode 100644
index 000000000000..0bb6416ae266
--- /dev/null
+++ b/include/asm-xtensa/pgtable.h
@@ -0,0 +1,468 @@
1/*
2 * linux/include/asm-xtensa/page.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version2 as
6 * published by the Free Software Foundation.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PGTABLE_H
12#define _XTENSA_PGTABLE_H
13
14#include <asm-generic/pgtable-nopmd.h>
15#include <asm/page.h>
16
17/* Assertions. */
18
19#ifdef CONFIG_MMU
20
21
22#if (XCHAL_MMU_RINGS < 2)
23# error Linux build assumes at least 2 ring levels.
24#endif
25
26#if (XCHAL_MMU_CA_BITS != 4)
27# error We assume exactly four bits for CA.
28#endif
29
30#if (XCHAL_MMU_SR_BITS != 0)
31# error We have no room for SR bits.
32#endif
33
34/*
35 * Use the first min-wired way for mapping page-table pages.
36 * Page coloring requires a second min-wired way.
37 */
38
39#if (XCHAL_DTLB_MINWIRED_SETS == 0)
40# error Need a min-wired way for mapping page-table pages
41#endif
42
43#define DTLB_WAY_PGTABLE XCHAL_DTLB_SET(XCHAL_DTLB_MINWIRED_SET0, WAY)
44
45#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
46# if XCHAL_DTLB_SET(XCHAL_DTLB_MINWIRED_SET0, WAYS) >= 2
47# define DTLB_WAY_DCACHE_ALIAS0 (DTLB_WAY_PGTABLE + 1)
48# define DTLB_WAY_DCACHE_ALIAS1 (DTLB_WAY_PGTABLE + 2)
49# else
50# error Page coloring requires its own wired dtlb way!
51# endif
52#endif
53
54#endif /* CONFIG_MMU */
55
56/*
57 * We only use two ring levels, user and kernel space.
58 */
59
60#define USER_RING 1 /* user ring level */
61#define KERNEL_RING 0 /* kernel ring level */
62
63/*
64 * The Xtensa architecture port of Linux has a two-level page table system,
65 * i.e. the logical three-level Linux page table layout are folded.
66 * Each task has the following memory page tables:
67 *
68 * PGD table (page directory), ie. 3rd-level page table:
69 * One page (4 kB) of 1024 (PTRS_PER_PGD) pointers to PTE tables
70 * (Architectures that don't have the PMD folded point to the PMD tables)
71 *
72 * The pointer to the PGD table for a given task can be retrieved from
73 * the task structure (struct task_struct*) t, e.g. current():
74 * (t->mm ? t->mm : t->active_mm)->pgd
75 *
76 * PMD tables (page middle-directory), ie. 2nd-level page tables:
77 * Absent for the Xtensa architecture (folded, PTRS_PER_PMD == 1).
78 *
79 * PTE tables (page table entry), ie. 1st-level page tables:
80 * One page (4 kB) of 1024 (PTRS_PER_PTE) PTEs with a special PTE
81 * invalid_pte_table for absent mappings.
82 *
83 * The individual pages are 4 kB big with special pages for the empty_zero_page.
84 */
85#define PGDIR_SHIFT 22
86#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
87#define PGDIR_MASK (~(PGDIR_SIZE-1))
88
89/*
90 * Entries per page directory level: we use two-level, so
91 * we don't really have any PMD directory physically.
92 */
93#define PTRS_PER_PTE 1024
94#define PTRS_PER_PTE_SHIFT 10
95#define PTRS_PER_PMD 1
96#define PTRS_PER_PGD 1024
97#define PGD_ORDER 0
98#define PMD_ORDER 0
99#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
100#define FIRST_USER_ADDRESS XCHAL_SEG_MAPPABLE_VADDR
101#define FIRST_USER_PGD_NR (FIRST_USER_ADDRESS >> PGDIR_SHIFT)
102
103/* virtual memory area. We keep a distance to other memory regions to be
104 * on the safe side. We also use this area for cache aliasing.
105 */
106
107// FIXME: virtual memory area must be configuration-dependent
108
109#define VMALLOC_START 0xC0000000
110#define VMALLOC_END 0xC7FF0000
111
112/* Xtensa Linux config PTE layout (when present):
113 * 31-12: PPN
114 * 11-6: Software
115 * 5-4: RING
116 * 3-0: CA
117 *
118 * Similar to the Alpha and MIPS ports, we need to keep track of the ref
119 * and mod bits in software. We have a software "you can read
120 * from this page" bit, and a hardware one which actually lets the
121 * process read from the page. On the same token we have a software
122 * writable bit and the real hardware one which actually lets the
123 * process write to the page.
124 *
125 * See further below for PTE layout for swapped-out pages.
126 */
127
128#define _PAGE_VALID (1<<0) /* hardware: page is accessible */
129#define _PAGE_WRENABLE (1<<1) /* hardware: page is writable */
130
131/* None of these cache modes include MP coherency: */
132#define _PAGE_NO_CACHE (0<<2) /* bypass, non-speculative */
133#if XCHAL_DCACHE_IS_WRITEBACK
134# define _PAGE_WRITEBACK (1<<2) /* write back */
135# define _PAGE_WRITETHRU (2<<2) /* write through */
136#else
137# define _PAGE_WRITEBACK (1<<2) /* assume write through */
138# define _PAGE_WRITETHRU (1<<2)
139#endif
140#define _PAGE_NOALLOC (3<<2) /* don't allocate cache,if not cached */
141#define _CACHE_MASK (3<<2)
142
143#define _PAGE_USER (1<<4) /* user access (ring=1) */
144#define _PAGE_KERNEL (0<<4) /* kernel access (ring=0) */
145
146/* Software */
147#define _PAGE_RW (1<<6) /* software: page writable */
148#define _PAGE_DIRTY (1<<7) /* software: page dirty */
149#define _PAGE_ACCESSED (1<<8) /* software: page accessed (read) */
150#define _PAGE_FILE (1<<9) /* nonlinear file mapping*/
151
152#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _CACHE_MASK | _PAGE_DIRTY)
153#define _PAGE_PRESENT ( _PAGE_VALID | _PAGE_WRITEBACK | _PAGE_ACCESSED)
154
155#ifdef CONFIG_MMU
156
157# define PAGE_NONE __pgprot(_PAGE_PRESENT)
158# define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_RW)
159# define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER)
160# define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER)
161# define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_KERNEL | _PAGE_WRENABLE)
162# define PAGE_INVALID __pgprot(_PAGE_USER)
163
164# if (DCACHE_WAY_SIZE > PAGE_SIZE)
165# define PAGE_DIRECTORY __pgprot(_PAGE_VALID | _PAGE_ACCESSED | _PAGE_KERNEL)
166# else
167# define PAGE_DIRECTORY __pgprot(_PAGE_PRESENT | _PAGE_KERNEL)
168# endif
169
170#else /* no mmu */
171
172# define PAGE_NONE __pgprot(0)
173# define PAGE_SHARED __pgprot(0)
174# define PAGE_COPY __pgprot(0)
175# define PAGE_READONLY __pgprot(0)
176# define PAGE_KERNEL __pgprot(0)
177
178#endif
179
180/*
181 * On certain configurations of Xtensa MMUs (eg. the initial Linux config),
182 * the MMU can't do page protection for execute, and considers that the same as
183 * read. Also, write permissions may imply read permissions.
184 * What follows is the closest we can get by reasonable means..
185 * See linux/mm/mmap.c for protection_map[] array that uses these definitions.
186 */
187#define __P000 PAGE_NONE /* private --- */
188#define __P001 PAGE_READONLY /* private --r */
189#define __P010 PAGE_COPY /* private -w- */
190#define __P011 PAGE_COPY /* private -wr */
191#define __P100 PAGE_READONLY /* private x-- */
192#define __P101 PAGE_READONLY /* private x-r */
193#define __P110 PAGE_COPY /* private xw- */
194#define __P111 PAGE_COPY /* private xwr */
195
196#define __S000 PAGE_NONE /* shared --- */
197#define __S001 PAGE_READONLY /* shared --r */
198#define __S010 PAGE_SHARED /* shared -w- */
199#define __S011 PAGE_SHARED /* shared -wr */
200#define __S100 PAGE_READONLY /* shared x-- */
201#define __S101 PAGE_READONLY /* shared x-r */
202#define __S110 PAGE_SHARED /* shared xw- */
203#define __S111 PAGE_SHARED /* shared xwr */
204
205#ifndef __ASSEMBLY__
206
207#define pte_ERROR(e) \
208 printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
209#define pgd_ERROR(e) \
210 printk("%s:%d: bad pgd entry %08lx.\n", __FILE__, __LINE__, pgd_val(e))
211
212extern unsigned long empty_zero_page[1024];
213
214#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
215
216extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
217
218/*
219 * The pmd contains the kernel virtual address of the pte page.
220 */
221#define pmd_page_kernel(pmd) ((unsigned long)(pmd_val(pmd) & PAGE_MASK))
222#define pmd_page(pmd) virt_to_page(pmd_val(pmd))
223
224/*
225 * The following only work if pte_present() is true.
226 */
227#define pte_none(pte) (!(pte_val(pte) ^ _PAGE_USER))
228#define pte_present(pte) (pte_val(pte) & _PAGE_VALID)
229#define pte_clear(mm,addr,ptep) \
230 do { update_pte(ptep, __pte(_PAGE_USER)); } while(0)
231
232#define pmd_none(pmd) (!pmd_val(pmd))
233#define pmd_present(pmd) (pmd_val(pmd) & PAGE_MASK)
234#define pmd_clear(pmdp) do { set_pmd(pmdp, __pmd(0)); } while (0)
235#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK)
236
237/* Note: We use the _PAGE_USER bit to indicate write-protect kernel memory */
238
239static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
240static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
241static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
242static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
243static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
244static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_RW | _PAGE_WRENABLE); return pte; }
245static inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
246static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
247static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
248static inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
249static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
250static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
251static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; }
252
253/*
254 * Conversion functions: convert a page and protection to a page entry,
255 * and a page entry and page directory to the page they refer to.
256 */
257#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
258#define pte_same(a,b) (pte_val(a) == pte_val(b))
259#define pte_page(x) pfn_to_page(pte_pfn(x))
260#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
261#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
262
263extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
264{
265 return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
266}
267
268/*
269 * Certain architectures need to do special things when pte's
270 * within a page table are directly modified. Thus, the following
271 * hook is made available.
272 */
273static inline void update_pte(pte_t *ptep, pte_t pteval)
274{
275 *ptep = pteval;
276#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
277 __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (ptep));
278#endif
279}
280
281extern inline void
282set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
283{
284 update_pte(ptep, pteval);
285}
286
287
288extern inline void
289set_pmd(pmd_t *pmdp, pmd_t pmdval)
290{
291 *pmdp = pmdval;
292#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
293 __asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
294#endif
295}
296
297
298static inline int
299ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
300 pte_t *ptep)
301{
302 pte_t pte = *ptep;
303 if (!pte_young(pte))
304 return 0;
305 update_pte(ptep, pte_mkold(pte));
306 return 1;
307}
308
309static inline int
310ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr,
311 pte_t *ptep)
312{
313 pte_t pte = *ptep;
314 if (!pte_dirty(pte))
315 return 0;
316 update_pte(ptep, pte_mkclean(pte));
317 return 1;
318}
319
320static inline pte_t
321ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
322{
323 pte_t pte = *ptep;
324 pte_clear(mm, addr, ptep);
325 return pte;
326}
327
328static inline void
329ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
330{
331 pte_t pte = *ptep;
332 update_pte(ptep, pte_wrprotect(pte));
333}
334
335/* to find an entry in a kernel page-table-directory */
336#define pgd_offset_k(address) pgd_offset(&init_mm, address)
337
338/* to find an entry in a page-table-directory */
339#define pgd_offset(mm,address) ((mm)->pgd + pgd_index(address))
340
341#define pgd_index(address) ((address) >> PGDIR_SHIFT)
342
343/* Find an entry in the second-level page table.. */
344#define pmd_offset(dir,address) ((pmd_t*)(dir))
345
346/* Find an entry in the third-level page table.. */
347#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
348#define pte_offset_kernel(dir,addr) \
349 ((pte_t*) pmd_page_kernel(*(dir)) + pte_index(addr))
350#define pte_offset_map(dir,addr) pte_offset_kernel((dir),(addr))
351#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir),(addr))
352
353#define pte_unmap(pte) do { } while (0)
354#define pte_unmap_nested(pte) do { } while (0)
355
356
357/*
358 * Encode and decode a swap entry.
359 * Each PTE in a process VM's page table is either:
360 * "present" -- valid and not swapped out, protection bits are meaningful;
361 * "not present" -- which further subdivides in these two cases:
362 * "none" -- no mapping at all; identified by pte_none(), set by pte_clear(
363 * "swapped out" -- the page is swapped out, and the SWP macros below
364 * are used to store swap file info in the PTE itself.
365 *
366 * In the Xtensa processor MMU, any PTE entries in user space (or anywhere
367 * in virtual memory that can map differently across address spaces)
368 * must have a correct ring value that represents the RASID field that
369 * is changed when switching address spaces. Eg. such PTE entries cannot
370 * be set to ring zero, because that can cause a (global) kernel ASID
371 * entry to be created in the TLBs (even with invalid cache attribute),
372 * potentially causing a multihit exception when going back to another
373 * address space that mapped the same virtual address at another ring.
374 *
375 * SO: we avoid using ring bits (_PAGE_RING_MASK) in "not present" PTEs.
376 * We also avoid using the _PAGE_VALID bit which must be zero for non-present
377 * pages.
378 *
379 * We end up with the following available bits: 1..3 and 7..31.
380 * We don't bother with 1..3 for now (we can use them later if needed),
381 * and chose to allocate 6 bits for SWP_TYPE and the remaining 19 bits
382 * for SWP_OFFSET. At least 5 bits are needed for SWP_TYPE, because it
383 * is currently implemented as an index into swap_info[MAX_SWAPFILES]
384 * and MAX_SWAPFILES is currently defined as 32 in <linux/swap.h>.
385 * However, for some reason all other architectures in the 2.4 kernel
386 * reserve either 6, 7, or 8 bits so I'll not detract from that for now. :)
387 * SWP_OFFSET is an offset into the swap file in page-size units, so
388 * with 4 kB pages, 19 bits supports a maximum swap file size of 2 GB.
389 *
390 * FIXME: 2 GB isn't very big. Other bits can be used to allow
391 * larger swap sizes. In the meantime, it appears relatively easy to get
392 * around the 2 GB limitation by simply using multiple swap files.
393 */
394
395#define __swp_type(entry) (((entry).val >> 7) & 0x3f)
396#define __swp_offset(entry) ((entry).val >> 13)
397#define __swp_entry(type,offs) ((swp_entry_t) {((type) << 7) | ((offs) << 13)})
398#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
399#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
400
401#define PTE_FILE_MAX_BITS 29
402#define pte_to_pgoff(pte) (pte_val(pte) >> 3)
403#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE })
404
405
406#endif /* !defined (__ASSEMBLY__) */
407
408
409#ifdef __ASSEMBLY__
410
411/* Assembly macro _PGD_INDEX is the same as C pgd_index(unsigned long),
412 * _PGD_OFFSET as C pgd_offset(struct mm_struct*, unsigned long),
413 * _PMD_OFFSET as C pmd_offset(pgd_t*, unsigned long)
414 * _PTE_OFFSET as C pte_offset(pmd_t*, unsigned long)
415 *
416 * Note: We require an additional temporary register which can be the same as
417 * the register that holds the address.
418 *
419 * ((pte_t*) ((unsigned long)(pmd_val(*pmd) & PAGE_MASK)) + pte_index(addr))
420 *
421 */
422#define _PGD_INDEX(rt,rs) extui rt, rs, PGDIR_SHIFT, 32-PGDIR_SHIFT
423#define _PTE_INDEX(rt,rs) extui rt, rs, PAGE_SHIFT, PTRS_PER_PTE_SHIFT
424
425#define _PGD_OFFSET(mm,adr,tmp) l32i mm, mm, MM_PGD; \
426 _PGD_INDEX(tmp, adr); \
427 addx4 mm, tmp, mm
428
429#define _PTE_OFFSET(pmd,adr,tmp) _PTE_INDEX(tmp, adr); \
430 srli pmd, pmd, PAGE_SHIFT; \
431 slli pmd, pmd, PAGE_SHIFT; \
432 addx4 pmd, tmp, pmd
433
434#else
435
436extern void paging_init(void);
437
438#define kern_addr_valid(addr) (1)
439
440extern void update_mmu_cache(struct vm_area_struct * vma,
441 unsigned long address, pte_t pte);
442
443/*
444 * remap a physical address `phys' of size `size' with page protection `prot'
445 * into virtual address `from'
446 */
447#define io_remap_page_range(vma,from,phys,size,prot) \
448 remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
449
450
451/* No page table caches to init */
452
453#define pgtable_cache_init() do { } while (0)
454
455typedef pte_t *pte_addr_t;
456
457#endif /* !defined (__ASSEMBLY__) */
458
459#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
460#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
461#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
462#define __HAVE_ARCH_PTEP_SET_WRPROTECT
463#define __HAVE_ARCH_PTEP_MKDIRTY
464#define __HAVE_ARCH_PTE_SAME
465
466#include <asm-generic/pgtable.h>
467
468#endif /* _XTENSA_PGTABLE_H */
diff --git a/include/asm-xtensa/platform-iss/hardware.h b/include/asm-xtensa/platform-iss/hardware.h
new file mode 100644
index 000000000000..22240f001803
--- /dev/null
+++ b/include/asm-xtensa/platform-iss/hardware.h
@@ -0,0 +1,29 @@
1/*
2 * include/asm-xtensa/platform-iss/hardware.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 Tensilica Inc.
9 */
10
11/*
12 * This file contains the default configuration of ISS.
13 */
14
15#ifndef __ASM_XTENSA_ISS_HARDWARE
16#define __ASM_XTENSA_ISS_HARDWARE
17
18/*
19 * Memory configuration.
20 */
21
22#define PLATFORM_DEFAULT_MEM_START XSHAL_RAM_PADDR
23#define PLATFORM_DEFAULT_MEM_SIZE XSHAL_RAM_VSIZE
24
25/*
26 * Interrupt configuration.
27 */
28
29#endif /* __ASM_XTENSA_ISS_HARDWARE */
diff --git a/include/asm-xtensa/platform.h b/include/asm-xtensa/platform.h
new file mode 100644
index 000000000000..36163894bc20
--- /dev/null
+++ b/include/asm-xtensa/platform.h
@@ -0,0 +1,92 @@
1/*
2 * include/asm-xtensa/platform.h
3 *
4 * Platform specific functions
5 *
6 * This file is subject to the terms and conditions of the GNU General
7 * Public License. See the file "COPYING" in the main directory of
8 * this archive for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_PLATFORM_H
14#define _XTENSA_PLATFORM_H
15
16#include <linux/config.h>
17#include <linux/types.h>
18#include <linux/pci.h>
19
20#include <asm/bootparam.h>
21
22/*
23 * platform_init is called before the mmu is initialized to give the
24 * platform a early hook-up. bp_tag_t is a list of configuration tags
25 * passed from the boot-loader.
26 */
27extern void platform_init(bp_tag_t*);
28
29/*
30 * platform_setup is called from setup_arch with a pointer to the command-line
31 * string.
32 */
33extern void platform_setup (char **);
34
35/*
36 * platform_init_irq is called from init_IRQ.
37 */
38extern void platform_init_irq (void);
39
40/*
41 * platform_restart is called to restart the system.
42 */
43extern void platform_restart (void);
44
45/*
46 * platform_halt is called to stop the system and halt.
47 */
48extern void platform_halt (void);
49
50/*
51 * platform_power_off is called to stop the system and power it off.
52 */
53extern void platform_power_off (void);
54
55/*
56 * platform_idle is called from the idle function.
57 */
58extern void platform_idle (void);
59
60/*
61 * platform_heartbeat is called every HZ
62 */
63extern void platform_heartbeat (void);
64
65/*
66 * platform_pcibios_init is called to allow the platform to setup the pci bus.
67 */
68extern void platform_pcibios_init (void);
69
70/*
71 * platform_pcibios_fixup allows to modify the PCI configuration.
72 */
73extern int platform_pcibios_fixup (void);
74
75/*
76 * platform_calibrate_ccount calibrates cpu clock freq (CONFIG_XTENSA_CALIBRATE)
77 */
78extern void platform_calibrate_ccount (void);
79
80/*
81 * platform_get_rtc_time returns RTC seconds (returns 0 for no error)
82 */
83extern int platform_get_rtc_time(time_t*);
84
85/*
86 * platform_set_rtc_time set RTC seconds (returns 0 for no error)
87 */
88extern int platform_set_rtc_time(time_t);
89
90
91#endif /* _XTENSA_PLATFORM_H */
92
diff --git a/include/asm-xtensa/poll.h b/include/asm-xtensa/poll.h
new file mode 100644
index 000000000000..dffe447534e0
--- /dev/null
+++ b/include/asm-xtensa/poll.h
@@ -0,0 +1,37 @@
1/*
2 * include/asm-xtensa/poll.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_POLL_H
12#define _XTENSA_POLL_H
13
14
15#define POLLIN 0x0001
16#define POLLPRI 0x0002
17#define POLLOUT 0x0004
18
19#define POLLERR 0x0008
20#define POLLHUP 0x0010
21#define POLLNVAL 0x0020
22
23#define POLLRDNORM 0x0040
24#define POLLRDBAND 0x0080
25#define POLLWRNORM POLLOUT
26#define POLLWRBAND 0x0100
27
28#define POLLMSG 0x0400
29#define POLLREMOVE 0x0800
30
31struct pollfd {
32 int fd;
33 short events;
34 short revents;
35};
36
37#endif /* _XTENSA_POLL_H */
diff --git a/include/asm-xtensa/posix_types.h b/include/asm-xtensa/posix_types.h
new file mode 100644
index 000000000000..2c816b0e7762
--- /dev/null
+++ b/include/asm-xtensa/posix_types.h
@@ -0,0 +1,123 @@
1/*
2 * include/asm-xtensa/posix_types.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Largely copied from include/asm-ppc/posix_types.h
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_POSIX_TYPES_H
14#define _XTENSA_POSIX_TYPES_H
15
16/*
17 * This file is generally used by user-level software, so you need to
18 * be a little careful about namespace pollution etc. Also, we cannot
19 * assume GCC is being used.
20 */
21
22typedef unsigned long __kernel_ino_t;
23typedef unsigned int __kernel_mode_t;
24typedef unsigned short __kernel_nlink_t;
25typedef long __kernel_off_t;
26typedef int __kernel_pid_t;
27typedef unsigned short __kernel_ipc_pid_t;
28typedef unsigned int __kernel_uid_t;
29typedef unsigned int __kernel_gid_t;
30typedef unsigned int __kernel_size_t;
31typedef int __kernel_ssize_t;
32typedef long __kernel_ptrdiff_t;
33typedef long __kernel_time_t;
34typedef long __kernel_suseconds_t;
35typedef long __kernel_clock_t;
36typedef int __kernel_timer_t;
37typedef int __kernel_clockid_t;
38typedef int __kernel_daddr_t;
39typedef char * __kernel_caddr_t;
40typedef unsigned short __kernel_uid16_t;
41typedef unsigned short __kernel_gid16_t;
42typedef unsigned int __kernel_uid32_t;
43typedef unsigned int __kernel_gid32_t;
44
45typedef unsigned short __kernel_old_uid_t;
46typedef unsigned short __kernel_old_gid_t;
47typedef unsigned short __kernel_old_dev_t;
48
49#ifdef __GNUC__
50typedef long long __kernel_loff_t;
51#endif
52
53typedef struct {
54 int val[2];
55} __kernel_fsid_t;
56
57#ifndef __GNUC__
58
59#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
60#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
61#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
62#define __FD_ZERO(set) \
63 ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
64
65#else /* __GNUC__ */
66
67#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
68 || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
69/* With GNU C, use inline functions instead so args are evaluated only once: */
70
71#undef __FD_SET
72static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
73{
74 unsigned long _tmp = fd / __NFDBITS;
75 unsigned long _rem = fd % __NFDBITS;
76 fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
77}
78
79#undef __FD_CLR
80static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
81{
82 unsigned long _tmp = fd / __NFDBITS;
83 unsigned long _rem = fd % __NFDBITS;
84 fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
85}
86
87#undef __FD_ISSET
88static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
89{
90 unsigned long _tmp = fd / __NFDBITS;
91 unsigned long _rem = fd % __NFDBITS;
92 return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
93}
94
95/*
96 * This will unroll the loop for the normal constant case (8 ints,
97 * for a 256-bit fd_set)
98 */
99#undef __FD_ZERO
100static __inline__ void __FD_ZERO(__kernel_fd_set *p)
101{
102 unsigned int *tmp = (unsigned int *)p->fds_bits;
103 int i;
104
105 if (__builtin_constant_p(__FDSET_LONGS)) {
106 switch (__FDSET_LONGS) {
107 case 8:
108 tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
109 tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
110 return;
111 }
112 }
113 i = __FDSET_LONGS;
114 while (i) {
115 i--;
116 *tmp = 0;
117 tmp++;
118 }
119}
120
121#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
122#endif /* __GNUC__ */
123#endif /* _XTENSA_POSIX_TYPES_H */
diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h
new file mode 100644
index 000000000000..9cab5e4298b9
--- /dev/null
+++ b/include/asm-xtensa/processor.h
@@ -0,0 +1,205 @@
1/*
2 * include/asm-xtensa/processor.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PROCESSOR_H
12#define _XTENSA_PROCESSOR_H
13
14#ifdef __ASSEMBLY__
15#define _ASMLANGUAGE
16#endif
17
18#include <xtensa/config/core.h>
19#include <xtensa/config/specreg.h>
20#include <xtensa/config/tie.h>
21#include <xtensa/config/system.h>
22
23#include <asm/ptrace.h>
24#include <asm/types.h>
25#include <asm/coprocessor.h>
26
27/* Assertions. */
28
29#if (XCHAL_HAVE_WINDOWED != 1)
30#error Linux requires the Xtensa Windowed Registers Option.
31#endif
32
33/*
34 * User space process size: 1 GB.
35 * Windowed call ABI requires caller and callee to be located within the same
36 * 1 GB region. The C compiler places trampoline code on the stack for sources
37 * that take the address of a nested C function (a feature used by glibc), so
38 * the 1 GB requirement applies to the stack as well.
39 */
40
41#define TASK_SIZE 0x40000000
42
43/*
44 * General exception cause assigned to debug exceptions. Debug exceptions go
45 * to their own vector, rather than the general exception vectors (user,
46 * kernel, double); and their specific causes are reported via DEBUGCAUSE
47 * rather than EXCCAUSE. However it is sometimes convenient to redirect debug
48 * exceptions to the general exception mechanism. To do this, an otherwise
49 * unused EXCCAUSE value was assigned to debug exceptions for this purpose.
50 */
51
52#define EXCCAUSE_MAPPED_DEBUG 63
53
54/*
55 * We use DEPC also as a flag to distinguish between double and regular
56 * exceptions. For performance reasons, DEPC might contain the value of
57 * EXCCAUSE for regular exceptions, so we use this definition to mark a
58 * valid double exception address.
59 * (Note: We use it in bgeui, so it should be 64, 128, or 256)
60 */
61
62#define VALID_DOUBLE_EXCEPTION_ADDRESS 64
63
64/* LOCKLEVEL defines the interrupt level that masks all
65 * general-purpose interrupts.
66 */
67#define LOCKLEVEL 1
68
69/* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE
70 * registers
71 */
72#define WSBITS (XCHAL_NUM_AREGS / 4) /* width of WINDOWSTART in bits */
73#define WBBITS (XCHAL_NUM_AREGS_LOG2 - 2) /* width of WINDOWBASE in bits */
74
75#ifndef __ASSEMBLY__
76
77/* Build a valid return address for the specified call winsize.
78 * winsize must be 1 (call4), 2 (call8), or 3 (call12)
79 */
80#define MAKE_RA_FOR_CALL(ra,ws) (((ra) & 0x3fffffff) | (ws) << 30)
81
82/* Convert return address to a valid pc
83 * Note: We assume that the stack pointer is in the same 1GB ranges as the ra
84 */
85#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
86
87typedef struct {
88 unsigned long seg;
89} mm_segment_t;
90
91struct thread_struct {
92
93 /* kernel's return address and stack pointer for context switching */
94 unsigned long ra; /* kernel's a0: return address and window call size */
95 unsigned long sp; /* kernel's a1: stack pointer */
96
97 mm_segment_t current_ds; /* see uaccess.h for example uses */
98
99 /* struct xtensa_cpuinfo info; */
100
101 unsigned long bad_vaddr; /* last user fault */
102 unsigned long bad_uaddr; /* last kernel fault accessing user space */
103 unsigned long error_code;
104
105 unsigned long ibreak[XCHAL_NUM_IBREAK];
106 unsigned long dbreaka[XCHAL_NUM_DBREAK];
107 unsigned long dbreakc[XCHAL_NUM_DBREAK];
108
109 /* Allocate storage for extra state and coprocessor state. */
110 unsigned char cp_save[XTENSA_CP_EXTRA_SIZE]
111 __attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN)));
112
113 /* Make structure 16 bytes aligned. */
114 int align[0] __attribute__ ((aligned(16)));
115};
116
117
118/*
119 * Default implementation of macro that returns current
120 * instruction pointer ("program counter").
121 */
122#define current_text_addr() ({ __label__ _l; _l: &&_l;})
123
124
125/* This decides where the kernel will search for a free chunk of vm
126 * space during mmap's.
127 */
128#define TASK_UNMAPPED_BASE (TASK_SIZE / 2)
129
130#define INIT_THREAD \
131{ \
132 ra: 0, \
133 sp: sizeof(init_stack) + (long) &init_stack, \
134 current_ds: {0}, \
135 /*info: {0}, */ \
136 bad_vaddr: 0, \
137 bad_uaddr: 0, \
138 error_code: 0, \
139}
140
141
142/*
143 * Do necessary setup to start up a newly executed thread.
144 * Note: We set-up ps as if we did a call4 to the new pc.
145 * set_thread_state in signal.c depends on it.
146 */
147#define USER_PS_VALUE ( (1 << XCHAL_PS_WOE_SHIFT) + \
148 (1 << XCHAL_PS_CALLINC_SHIFT) + \
149 (USER_RING << XCHAL_PS_RING_SHIFT) + \
150 (1 << XCHAL_PS_PROGSTACK_SHIFT) + \
151 (1 << XCHAL_PS_EXCM_SHIFT) )
152
153/* Clearing a0 terminates the backtrace. */
154#define start_thread(regs, new_pc, new_sp) \
155 regs->pc = new_pc; \
156 regs->ps = USER_PS_VALUE; \
157 regs->areg[1] = new_sp; \
158 regs->areg[0] = 0; \
159 regs->wmask = 1; \
160 regs->depc = 0; \
161 regs->windowbase = 0; \
162 regs->windowstart = 1;
163
164/* Forward declaration */
165struct task_struct;
166struct mm_struct;
167
168// FIXME: do we need release_thread for CP??
169/* Free all resources held by a thread. */
170#define release_thread(thread) do { } while(0)
171
172// FIXME: do we need prepare_to_copy (lazy status) for CP??
173/* Prepare to copy thread state - unlazy all lazy status */
174#define prepare_to_copy(tsk) do { } while (0)
175
176/*
177 * create a kernel thread without removing it from tasklists
178 */
179extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
180
181/* Copy and release all segment info associated with a VM */
182
183#define copy_segments(p, mm) do { } while(0)
184#define release_segments(mm) do { } while(0)
185#define forget_segments() do { } while (0)
186
187#define thread_saved_pc(tsk) (xtensa_pt_regs(tsk)->pc)
188
189extern unsigned long get_wchan(struct task_struct *p);
190
191#define KSTK_EIP(tsk) (xtensa_pt_regs(tsk)->pc)
192#define KSTK_ESP(tsk) (xtensa_pt_regs(tsk)->areg[1])
193
194#define cpu_relax() do { } while (0)
195
196/* Special register access. */
197
198#define WSR(v,sr) __asm__ __volatile__ ("wsr %0,"__stringify(sr) :: "a"(v));
199#define RSR(v,sr) __asm__ __volatile__ ("rsr %0,"__stringify(sr) : "=a"(v));
200
201#define set_sr(x,sr) ({unsigned int v=(unsigned int)x; WSR(v,sr);})
202#define get_sr(sr) ({unsigned int v; RSR(v,sr); v; })
203
204#endif /* __ASSEMBLY__ */
205#endif /* _XTENSA_PROCESSOR_H */
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
new file mode 100644
index 000000000000..2848a5ff8349
--- /dev/null
+++ b/include/asm-xtensa/ptrace.h
@@ -0,0 +1,135 @@
1/*
2 * include/asm-xtensa/ptrace.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_PTRACE_H
12#define _XTENSA_PTRACE_H
13
14#include <xtensa/config/core.h>
15
16/*
17 * Kernel stack
18 *
19 * +-----------------------+ -------- STACK_SIZE
20 * | register file | |
21 * +-----------------------+ |
22 * | struct pt_regs | |
23 * +-----------------------+ | ------ PT_REGS_OFFSET
24 * double : 16 bytes spill area : | ^
25 * excetion :- - - - - - - - - - - -: | |
26 * frame : struct pt_regs : | |
27 * :- - - - - - - - - - - -: | |
28 * | | | |
29 * | memory stack | | |
30 * | | | |
31 * ~ ~ ~ ~
32 * ~ ~ ~ ~
33 * | | | |
34 * | | | |
35 * +-----------------------+ | | --- STACK_BIAS
36 * | struct task_struct | | | ^
37 * current --> +-----------------------+ | | |
38 * | struct thread_info | | | |
39 * +-----------------------+ --------
40 */
41
42#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)
43
44/* Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */
45
46#define EXC_TABLE_KSTK 0x004 /* Kernel Stack */
47#define EXC_TABLE_DOUBLE_SAVE 0x008 /* Double exception save area for a0 */
48#define EXC_TABLE_FIXUP 0x00c /* Fixup handler */
49#define EXC_TABLE_PARAM 0x010 /* For passing a parameter to fixup */
50#define EXC_TABLE_SYSCALL_SAVE 0x014 /* For fast syscall handler */
51#define EXC_TABLE_FAST_USER 0x100 /* Fast user exception handler */
52#define EXC_TABLE_FAST_KERNEL 0x200 /* Fast kernel exception handler */
53#define EXC_TABLE_DEFAULT 0x300 /* Default C-Handler */
54#define EXC_TABLE_SIZE 0x400
55
56/* Registers used by strace */
57
58#define REG_A_BASE 0xfc000000
59#define REG_AR_BASE 0x04000000
60#define REG_PC 0x14000000
61#define REG_PS 0x080000e6
62#define REG_WB 0x08000048
63#define REG_WS 0x08000049
64#define REG_LBEG 0x08000000
65#define REG_LEND 0x08000001
66#define REG_LCOUNT 0x08000002
67#define REG_SAR 0x08000003
68#define REG_DEPC 0x080000c0
69#define REG_EXCCAUSE 0x080000e8
70#define REG_EXCVADDR 0x080000ee
71#define SYSCALL_NR 0x1
72
73#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1)
74
75/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */
76
77#define PTRACE_GETREGS 12
78#define PTRACE_SETREGS 13
79#define PTRACE_GETFPREGS 14
80#define PTRACE_SETFPREGS 15
81#define PTRACE_GETFPREGSIZE 18
82
83#ifndef __ASSEMBLY__
84
85/*
86 * This struct defines the way the registers are stored on the
87 * kernel stack during a system call or other kernel entry.
88 */
89struct pt_regs {
90 unsigned long pc; /* 4 */
91 unsigned long ps; /* 8 */
92 unsigned long depc; /* 12 */
93 unsigned long exccause; /* 16 */
94 unsigned long excvaddr; /* 20 */
95 unsigned long debugcause; /* 24 */
96 unsigned long wmask; /* 28 */
97 unsigned long lbeg; /* 32 */
98 unsigned long lend; /* 36 */
99 unsigned long lcount; /* 40 */
100 unsigned long sar; /* 44 */
101 unsigned long windowbase; /* 48 */
102 unsigned long windowstart; /* 52 */
103 unsigned long syscall; /* 56 */
104 int reserved[2]; /* 64 */
105
106 /* Make sure the areg field is 16 bytes aligned. */
107 int align[0] __attribute__ ((aligned(16)));
108
109 /* current register frame.
110 * Note: The ESF for kernel exceptions ends after 16 registers!
111 */
112 unsigned long areg[16]; /* 128 (64) */
113};
114
115#ifdef __KERNEL__
116# define xtensa_pt_regs(tsk) ((struct pt_regs*) \
117 (((long)(tsk)->thread_info + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4)) - 1)
118# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
119# define instruction_pointer(regs) ((regs)->pc)
120extern void show_regs(struct pt_regs *);
121
122# ifndef CONFIG_SMP
123# define profile_pc(regs) instruction_pointer(regs)
124# endif
125#endif /* __KERNEL__ */
126
127#else /* __ASSEMBLY__ */
128
129#ifdef __KERNEL__
130# include <asm/offsets.h>
131#define PT_REGS_OFFSET (KERNEL_STACK_SIZE - PT_USER_SIZE)
132#endif
133
134#endif /* !__ASSEMBLY__ */
135#endif /* _XTENSA_PTRACE_H */
diff --git a/include/asm-xtensa/resource.h b/include/asm-xtensa/resource.h
new file mode 100644
index 000000000000..17b5ab311771
--- /dev/null
+++ b/include/asm-xtensa/resource.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/resource.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_RESOURCE_H
12#define _XTENSA_RESOURCE_H
13
14#include <asm-generic/resource.h>
15
16#endif /* _XTENSA_RESOURCE_H */
diff --git a/include/asm-xtensa/rmap.h b/include/asm-xtensa/rmap.h
new file mode 100644
index 000000000000..649588b7e9ad
--- /dev/null
+++ b/include/asm-xtensa/rmap.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/rmap.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_RMAP_H
12#define _XTENSA_RMAP_H
13
14#include <asm-generic/rmap.h>
15
16#endif
diff --git a/include/asm-xtensa/rwsem.h b/include/asm-xtensa/rwsem.h
new file mode 100644
index 000000000000..3c02b0e033f0
--- /dev/null
+++ b/include/asm-xtensa/rwsem.h
@@ -0,0 +1,175 @@
1/*
2 * include/asm-xtensa/rwsem.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Largely copied from include/asm-ppc/rwsem.h
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_RWSEM_H
14#define _XTENSA_RWSEM_H
15
16#include <linux/list.h>
17#include <linux/spinlock.h>
18#include <asm/atomic.h>
19#include <asm/system.h>
20
21/*
22 * the semaphore definition
23 */
24struct rw_semaphore {
25 signed long count;
26#define RWSEM_UNLOCKED_VALUE 0x00000000
27#define RWSEM_ACTIVE_BIAS 0x00000001
28#define RWSEM_ACTIVE_MASK 0x0000ffff
29#define RWSEM_WAITING_BIAS (-0x00010000)
30#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
31#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
32 spinlock_t wait_lock;
33 struct list_head wait_list;
34#if RWSEM_DEBUG
35 int debug;
36#endif
37};
38
39/*
40 * initialisation
41 */
42#if RWSEM_DEBUG
43#define __RWSEM_DEBUG_INIT , 0
44#else
45#define __RWSEM_DEBUG_INIT /* */
46#endif
47
48#define __RWSEM_INITIALIZER(name) \
49 { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
50 LIST_HEAD_INIT((name).wait_list) \
51 __RWSEM_DEBUG_INIT }
52
53#define DECLARE_RWSEM(name) \
54 struct rw_semaphore name = __RWSEM_INITIALIZER(name)
55
56extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
57extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
58extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
59extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
60
61static inline void init_rwsem(struct rw_semaphore *sem)
62{
63 sem->count = RWSEM_UNLOCKED_VALUE;
64 spin_lock_init(&sem->wait_lock);
65 INIT_LIST_HEAD(&sem->wait_list);
66#if RWSEM_DEBUG
67 sem->debug = 0;
68#endif
69}
70
71/*
72 * lock for reading
73 */
74static inline void __down_read(struct rw_semaphore *sem)
75{
76 if (atomic_add_return(1,(atomic_t *)(&sem->count)) > 0)
77 smp_wmb();
78 else
79 rwsem_down_read_failed(sem);
80}
81
82static inline int __down_read_trylock(struct rw_semaphore *sem)
83{
84 int tmp;
85
86 while ((tmp = sem->count) >= 0) {
87 if (tmp == cmpxchg(&sem->count, tmp,
88 tmp + RWSEM_ACTIVE_READ_BIAS)) {
89 smp_wmb();
90 return 1;
91 }
92 }
93 return 0;
94}
95
96/*
97 * lock for writing
98 */
99static inline void __down_write(struct rw_semaphore *sem)
100{
101 int tmp;
102
103 tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
104 (atomic_t *)(&sem->count));
105 if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
106 smp_wmb();
107 else
108 rwsem_down_write_failed(sem);
109}
110
111static inline int __down_write_trylock(struct rw_semaphore *sem)
112{
113 int tmp;
114
115 tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
116 RWSEM_ACTIVE_WRITE_BIAS);
117 smp_wmb();
118 return tmp == RWSEM_UNLOCKED_VALUE;
119}
120
121/*
122 * unlock after reading
123 */
124static inline void __up_read(struct rw_semaphore *sem)
125{
126 int tmp;
127
128 smp_wmb();
129 tmp = atomic_sub_return(1,(atomic_t *)(&sem->count));
130 if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
131 rwsem_wake(sem);
132}
133
134/*
135 * unlock after writing
136 */
137static inline void __up_write(struct rw_semaphore *sem)
138{
139 smp_wmb();
140 if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
141 (atomic_t *)(&sem->count)) < 0)
142 rwsem_wake(sem);
143}
144
145/*
146 * implement atomic add functionality
147 */
148static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
149{
150 atomic_add(delta, (atomic_t *)(&sem->count));
151}
152
153/*
154 * downgrade write lock to read lock
155 */
156static inline void __downgrade_write(struct rw_semaphore *sem)
157{
158 int tmp;
159
160 smp_wmb();
161 tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
162 if (tmp < 0)
163 rwsem_downgrade_wake(sem);
164}
165
166/*
167 * implement exchange and add functionality
168 */
169static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
170{
171 smp_mb();
172 return atomic_add_return(delta, (atomic_t *)(&sem->count));
173}
174
175#endif /* _XTENSA_RWSEM_XADD_H */
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
new file mode 100644
index 000000000000..38a2b9acd658
--- /dev/null
+++ b/include/asm-xtensa/scatterlist.h
@@ -0,0 +1,34 @@
1/*
2 * include/asm-xtensa/scatterlist.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SCATTERLIST_H
12#define _XTENSA_SCATTERLIST_H
13
14struct scatterlist {
15 struct page *page;
16 unsigned int offset;
17 dma_addr_t dma_address;
18 unsigned int length;
19};
20
21/*
22 * These macros should be used after a pci_map_sg call has been done
23 * to get bus addresses of each of the SG entries and their lengths.
24 * You should only work with the number of sg entries pci_map_sg
25 * returns, or alternatively stop on the first sg_dma_len(sg) which
26 * is 0.
27 */
28#define sg_dma_address(sg) ((sg)->dma_address)
29#define sg_dma_len(sg) ((sg)->length)
30
31
32#define ISA_DMA_THRESHOLD (~0UL)
33
34#endif /* _XTENSA_SCATTERLIST_H */
diff --git a/include/asm-xtensa/sections.h b/include/asm-xtensa/sections.h
new file mode 100644
index 000000000000..40b5191b55a2
--- /dev/null
+++ b/include/asm-xtensa/sections.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/sections.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SECTIONS_H
12#define _XTENSA_SECTIONS_H
13
14#include <asm-generic/sections.h>
15
16#endif /* _XTENSA_SECTIONS_H */
diff --git a/include/asm-xtensa/segment.h b/include/asm-xtensa/segment.h
new file mode 100644
index 000000000000..a2eb547a1a75
--- /dev/null
+++ b/include/asm-xtensa/segment.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/segment.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SEGMENT_H
12#define _XTENSA_SEGMENT_H
13
14#include <asm/uaccess.h>
15
16#endif /* _XTENSA_SEGEMENT_H */
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
new file mode 100644
index 000000000000..c8a7574a9a57
--- /dev/null
+++ b/include/asm-xtensa/semaphore.h
@@ -0,0 +1,129 @@
1/*
2 * linux/include/asm-xtensa/semaphore.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SEMAPHORE_H
12#define _XTENSA_SEMAPHORE_H
13
14#include <asm/atomic.h>
15#include <asm/system.h>
16#include <linux/wait.h>
17#include <linux/rwsem.h>
18
19struct semaphore {
20 atomic_t count;
21 int sleepers;
22 wait_queue_head_t wait;
23#if WAITQUEUE_DEBUG
24 long __magic;
25#endif
26};
27
28#if WAITQUEUE_DEBUG
29# define __SEM_DEBUG_INIT(name) \
30 , (int)&(name).__magic
31#else
32# define __SEM_DEBUG_INIT(name)
33#endif
34
35#define __SEMAPHORE_INITIALIZER(name,count) \
36 { ATOMIC_INIT(count), \
37 0, \
38 __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
39 __SEM_DEBUG_INIT(name) }
40
41#define __MUTEX_INITIALIZER(name) \
42 __SEMAPHORE_INITIALIZER(name, 1)
43
44#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
45 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
46
47#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
48#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
49
50extern inline void sema_init (struct semaphore *sem, int val)
51{
52/*
53 * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
54 *
55 * i'd rather use the more flexible initialization above, but sadly
56 * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
57 */
58 atomic_set(&sem->count, val);
59 init_waitqueue_head(&sem->wait);
60#if WAITQUEUE_DEBUG
61 sem->__magic = (int)&sem->__magic;
62#endif
63}
64
65static inline void init_MUTEX (struct semaphore *sem)
66{
67 sema_init(sem, 1);
68}
69
70static inline void init_MUTEX_LOCKED (struct semaphore *sem)
71{
72 sema_init(sem, 0);
73}
74
75asmlinkage void __down(struct semaphore * sem);
76asmlinkage int __down_interruptible(struct semaphore * sem);
77asmlinkage int __down_trylock(struct semaphore * sem);
78asmlinkage void __up(struct semaphore * sem);
79
80extern spinlock_t semaphore_wake_lock;
81
82extern __inline__ void down(struct semaphore * sem)
83{
84#if WAITQUEUE_DEBUG
85 CHECK_MAGIC(sem->__magic);
86#endif
87
88 if (atomic_sub_return(1, &sem->count) < 0)
89 __down(sem);
90}
91
92extern __inline__ int down_interruptible(struct semaphore * sem)
93{
94 int ret = 0;
95#if WAITQUEUE_DEBUG
96 CHECK_MAGIC(sem->__magic);
97#endif
98
99 if (atomic_sub_return(1, &sem->count) < 0)
100 ret = __down_interruptible(sem);
101 return ret;
102}
103
104extern __inline__ int down_trylock(struct semaphore * sem)
105{
106 int ret = 0;
107#if WAITQUEUE_DEBUG
108 CHECK_MAGIC(sem->__magic);
109#endif
110
111 if (atomic_sub_return(1, &sem->count) < 0)
112 ret = __down_trylock(sem);
113 return ret;
114}
115
116/*
117 * Note! This is subtle. We jump to wake people up only if
118 * the semaphore was negative (== somebody was waiting on it).
119 */
120extern __inline__ void up(struct semaphore * sem)
121{
122#if WAITQUEUE_DEBUG
123 CHECK_MAGIC(sem->__magic);
124#endif
125 if (atomic_add_return(1, &sem->count) <= 0)
126 __up(sem);
127}
128
129#endif /* _XTENSA_SEMAPHORE_H */
diff --git a/include/asm-xtensa/sembuf.h b/include/asm-xtensa/sembuf.h
new file mode 100644
index 000000000000..2d26c47666fe
--- /dev/null
+++ b/include/asm-xtensa/sembuf.h
@@ -0,0 +1,44 @@
1/*
2 * include/asm-xtensa/sembuf.h
3 *
4 * The semid64_ds structure for Xtensa architecture.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 *
12 * Note extra padding because this structure is passed back and forth
13 * between kernel and user space.
14 *
15 * Pad space is left for:
16 * - 64-bit time_t to solve y2038 problem
17 * - 2 miscellaneous 32-bit values
18 *
19 */
20
21#ifndef _XTENSA_SEMBUF_H
22#define _XTENSA_SEMBUF_H
23
24#include <asm/byteorder.h>
25
26struct semid64_ds {
27 struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
28#if XCHAL_HAVE_LE
29 __kernel_time_t sem_otime; /* last semop time */
30 unsigned long __unused1;
31 __kernel_time_t sem_ctime; /* last change time */
32 unsigned long __unused2;
33#else
34 unsigned long __unused1;
35 __kernel_time_t sem_otime; /* last semop time */
36 unsigned long __unused2;
37 __kernel_time_t sem_ctime; /* last change time */
38#endif
39 unsigned long sem_nsems; /* no. of semaphores in array */
40 unsigned long __unused3;
41 unsigned long __unused4;
42};
43
44#endif /* __ASM_XTENSA_SEMBUF_H */
diff --git a/include/asm-xtensa/serial.h b/include/asm-xtensa/serial.h
new file mode 100644
index 000000000000..ec04114fcf0b
--- /dev/null
+++ b/include/asm-xtensa/serial.h
@@ -0,0 +1,18 @@
1/*
2 * include/asm-xtensa/serial.h
3 *
4 * Configuration details for 8250, 16450, 16550, etc. serial ports
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_SERIAL_H
14#define _XTENSA_SERIAL_H
15
16#include <asm/platform/serial.h>
17
18#endif /* _XTENSA_SERIAL_H */
diff --git a/include/asm-xtensa/setup.h b/include/asm-xtensa/setup.h
new file mode 100644
index 000000000000..e3636520d8cc
--- /dev/null
+++ b/include/asm-xtensa/setup.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/setup.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SETUP_H
12#define _XTENSA_SETUP_H
13
14#define COMMAND_LINE_SIZE 256
15
16#endif
diff --git a/include/asm-xtensa/shmbuf.h b/include/asm-xtensa/shmbuf.h
new file mode 100644
index 000000000000..a30b81a4b933
--- /dev/null
+++ b/include/asm-xtensa/shmbuf.h
@@ -0,0 +1,50 @@
1/*
2 * include/asm-xtensa/shmbuf.h
3 *
4 * The shmid64_ds structure for Xtensa architecture.
5 * Note extra padding because this structure is passed back and forth
6 * between kernel and user space.
7 *
8 * Pad space is left for:
9 * - 64-bit time_t to solve y2038 problem
10 * - 2 miscellaneous 32-bit values
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 *
16 * Copyright (C) 2001 - 2005 Tensilica Inc.
17 */
18
19#ifndef _XTENSA_SHMBUF_H
20#define _XTENSA_SHMBUF_H
21
22struct shmid64_ds {
23 struct ipc64_perm shm_perm; /* operation perms */
24 size_t shm_segsz; /* size of segment (bytes) */
25 __kernel_time_t shm_atime; /* last attach time */
26 unsigned long __unused1;
27 __kernel_time_t shm_dtime; /* last detach time */
28 unsigned long __unused2;
29 __kernel_time_t shm_ctime; /* last change time */
30 unsigned long __unused3;
31 __kernel_pid_t shm_cpid; /* pid of creator */
32 __kernel_pid_t shm_lpid; /* pid of last operator */
33 unsigned long shm_nattch; /* no. of current attaches */
34 unsigned long __unused4;
35 unsigned long __unused5;
36};
37
38struct shminfo64 {
39 unsigned long shmmax;
40 unsigned long shmmin;
41 unsigned long shmmni;
42 unsigned long shmseg;
43 unsigned long shmall;
44 unsigned long __unused1;
45 unsigned long __unused2;
46 unsigned long __unused3;
47 unsigned long __unused4;
48};
49
50#endif /* _XTENSA_SHMBUF_H */
diff --git a/include/asm-xtensa/shmparam.h b/include/asm-xtensa/shmparam.h
new file mode 100644
index 000000000000..d3b65bfa71c3
--- /dev/null
+++ b/include/asm-xtensa/shmparam.h
@@ -0,0 +1,23 @@
1/*
2 * include/asm-xtensa/shmparam.h
3 *
4 * This file is subject to the terms and conditions of the GNU General
5 * Public License. See the file "COPYING" in the main directory of
6 * this archive for more details.
7 */
8
9#ifndef _XTENSA_SHMPARAM_H
10#define _XTENSA_SHMPARAM_H
11
12#include <asm/processor.h>
13
14/*
15 * Xtensa can have variable size caches, and if
16 * the size of single way is larger than the page size,
17 * then we have to start worrying about cache aliasing
18 * problems.
19 */
20
21#define SHMLBA ((PAGE_SIZE > DCACHE_WAY_SIZE)? PAGE_SIZE : DCACHE_WAY_SIZE)
22
23#endif /* _XTENSA_SHMPARAM_H */
diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h
new file mode 100644
index 000000000000..a75177291418
--- /dev/null
+++ b/include/asm-xtensa/sigcontext.h
@@ -0,0 +1,44 @@
1/*
2 * include/asm-xtensa/sigcontext.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2003 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SIGCONTEXT_H
12#define _XTENSA_SIGCONTEXT_H
13
14#define _ASMLANGUAGE
15#include <asm/processor.h>
16#include <asm/coprocessor.h>
17
18
19struct _cpstate {
20 unsigned char _cpstate[XTENSA_CP_EXTRA_SIZE];
21} __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
22
23
24struct sigcontext {
25 unsigned long oldmask;
26
27 /* CPU registers */
28 unsigned long sc_pc;
29 unsigned long sc_ps;
30 unsigned long sc_wmask;
31 unsigned long sc_windowbase;
32 unsigned long sc_windowstart;
33 unsigned long sc_lbeg;
34 unsigned long sc_lend;
35 unsigned long sc_lcount;
36 unsigned long sc_sar;
37 unsigned long sc_depc;
38 unsigned long sc_dareg0;
39 unsigned long sc_treg[4];
40 unsigned long sc_areg[XCHAL_NUM_AREGS];
41 struct _cpstate *sc_cpstate;
42};
43
44#endif /* __ASM_XTENSA_SIGCONTEXT_H */
diff --git a/include/asm-xtensa/siginfo.h b/include/asm-xtensa/siginfo.h
new file mode 100644
index 000000000000..44f0ae77b539
--- /dev/null
+++ b/include/asm-xtensa/siginfo.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/processor.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SIGINFO_H
12#define _XTENSA_SIGINFO_H
13
14#include <asm-generic/siginfo.h>
15
16#endif /* _XTENSA_SIGINFO_H */
diff --git a/include/asm-xtensa/signal.h b/include/asm-xtensa/signal.h
new file mode 100644
index 000000000000..5d6fc9cdf58d
--- /dev/null
+++ b/include/asm-xtensa/signal.h
@@ -0,0 +1,187 @@
1/*
2 * include/asm-xtensa/signal.h
3 *
4 * Swiped from SH.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_SIGNAL_H
14#define _XTENSA_SIGNAL_H
15
16
17#define _NSIG 64
18#define _NSIG_BPW 32
19#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
20
21#ifndef __ASSEMBLY__
22
23#include <linux/types.h>
24
25/* Avoid too many header ordering problems. */
26struct siginfo;
27typedef unsigned long old_sigset_t; /* at least 32 bits */
28typedef struct {
29 unsigned long sig[_NSIG_WORDS];
30} sigset_t;
31
32#endif
33
34#define SIGHUP 1
35#define SIGINT 2
36#define SIGQUIT 3
37#define SIGILL 4
38#define SIGTRAP 5
39#define SIGABRT 6
40#define SIGIOT 6
41#define SIGBUS 7
42#define SIGFPE 8
43#define SIGKILL 9
44#define SIGUSR1 10
45#define SIGSEGV 11
46#define SIGUSR2 12
47#define SIGPIPE 13
48#define SIGALRM 14
49#define SIGTERM 15
50#define SIGSTKFLT 16
51#define SIGCHLD 17
52#define SIGCONT 18
53#define SIGSTOP 19
54#define SIGTSTP 20
55#define SIGTTIN 21
56#define SIGTTOU 22
57#define SIGURG 23
58#define SIGXCPU 24
59#define SIGXFSZ 25
60#define SIGVTALRM 26
61#define SIGPROF 27
62#define SIGWINCH 28
63#define SIGIO 29
64#define SIGPOLL SIGIO
65/* #define SIGLOST 29 */
66#define SIGPWR 30
67#define SIGSYS 31
68#define SIGUNUSED 31
69
70/* These should not be considered constants from userland. */
71#define SIGRTMIN 32
72#define SIGRTMAX (_NSIG-1)
73
74/*
75 * SA_FLAGS values:
76 *
77 * SA_ONSTACK indicates that a registered stack_t will be used.
78 * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
79 * SA_RESTART flag to get restarting signals (which were the default long ago)
80 * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
81 * SA_RESETHAND clears the handler when the signal is delivered.
82 * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
83 * SA_NODEFER prevents the current signal from being masked in the handler.
84 *
85 * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
86 * Unix names RESETHAND and NODEFER respectively.
87 */
88#define SA_NOCLDSTOP 0x00000001
89#define SA_NOCLDWAIT 0x00000002 /* not supported yet */
90#define SA_SIGINFO 0x00000004
91#define SA_ONSTACK 0x08000000
92#define SA_RESTART 0x10000000
93#define SA_NODEFER 0x40000000
94#define SA_RESETHAND 0x80000000
95
96#define SA_NOMASK SA_NODEFER
97#define SA_ONESHOT SA_RESETHAND
98#define SA_INTERRUPT 0x20000000 /* dummy -- ignored */
99
100#define SA_RESTORER 0x04000000
101
102/*
103 * sigaltstack controls
104 */
105#define SS_ONSTACK 1
106#define SS_DISABLE 2
107
108#define MINSIGSTKSZ 2048
109#define SIGSTKSZ 8192
110
111#ifndef __ASSEMBLY__
112#ifdef __KERNEL__
113
114/*
115 * These values of sa_flags are used only by the kernel as part of the
116 * irq handling routines.
117 *
118 * SA_INTERRUPT is also used by the irq handling routines.
119 * SA_SHIRQ is for shared interrupt support on PCI and EISA.
120 */
121#define SA_PROBE SA_ONESHOT
122#define SA_SAMPLE_RANDOM SA_RESTART
123#define SA_SHIRQ 0x04000000
124#endif
125
126#define SIG_BLOCK 0 /* for blocking signals */
127#define SIG_UNBLOCK 1 /* for unblocking signals */
128#define SIG_SETMASK 2 /* for setting the signal mask */
129
130/* Type of a signal handler. */
131typedef void (*__sighandler_t)(int);
132
133#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
134#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
135#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
136
137#ifdef __KERNEL__
138struct old_sigaction {
139 __sighandler_t sa_handler;
140 old_sigset_t sa_mask;
141 unsigned long sa_flags;
142 void (*sa_restorer)(void);
143};
144
145struct sigaction {
146 __sighandler_t sa_handler;
147 unsigned long sa_flags;
148 void (*sa_restorer)(void);
149 sigset_t sa_mask; /* mask last for extensibility */
150};
151
152struct k_sigaction {
153 struct sigaction sa;
154};
155
156#else
157
158/* Here we must cater to libcs that poke about in kernel headers. */
159
160struct sigaction {
161 union {
162 __sighandler_t _sa_handler;
163 void (*_sa_sigaction)(int, struct siginfo *, void *);
164 } _u;
165 sigset_t sa_mask;
166 unsigned long sa_flags;
167 void (*sa_restorer)(void);
168};
169
170#define sa_handler _u._sa_handler
171#define sa_sigaction _u._sa_sigaction
172
173#endif /* __KERNEL__ */
174
175typedef struct sigaltstack {
176 void *ss_sp;
177 int ss_flags;
178 size_t ss_size;
179} stack_t;
180
181#ifdef __KERNEL__
182#include <asm/sigcontext.h>
183#define ptrace_signal_deliver(regs, cookie) do { } while (0)
184
185#endif /* __KERNEL__ */
186#endif /* __ASSEMBLY__ */
187#endif /* _XTENSA_SIGNAL_H */
diff --git a/include/asm-xtensa/smp.h b/include/asm-xtensa/smp.h
new file mode 100644
index 000000000000..83c569e3bdbd
--- /dev/null
+++ b/include/asm-xtensa/smp.h
@@ -0,0 +1,27 @@
1/*
2 * include/asm-xtensa/smp.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SMP_H
12#define _XTENSA_SMP_H
13
14extern struct xtensa_cpuinfo boot_cpu_data;
15
16#define cpu_data (&boot_cpu_data)
17#define current_cpu_data boot_cpu_data
18
19struct xtensa_cpuinfo {
20 unsigned long *pgd_cache;
21 unsigned long *pte_cache;
22 unsigned long pgtable_cache_sz;
23};
24
25#define cpu_logical_map(cpu) (cpu)
26
27#endif /* _XTENSA_SMP_H */
diff --git a/include/asm-xtensa/socket.h b/include/asm-xtensa/socket.h
new file mode 100644
index 000000000000..daccd05a14cd
--- /dev/null
+++ b/include/asm-xtensa/socket.h
@@ -0,0 +1,61 @@
1/*
2 * include/asm-xtensa/socket.h
3 *
4 * Copied from i386.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#ifndef _XTENSA_SOCKET_H
12#define _XTENSA_SOCKET_H
13
14#include <asm/sockios.h>
15
16/* For setsockoptions(2) */
17#define SOL_SOCKET 1
18
19#define SO_DEBUG 1
20#define SO_REUSEADDR 2
21#define SO_TYPE 3
22#define SO_ERROR 4
23#define SO_DONTROUTE 5
24#define SO_BROADCAST 6
25#define SO_SNDBUF 7
26#define SO_RCVBUF 8
27#define SO_KEEPALIVE 9
28#define SO_OOBINLINE 10
29#define SO_NO_CHECK 11
30#define SO_PRIORITY 12
31#define SO_LINGER 13
32#define SO_BSDCOMPAT 14
33/* To add :#define SO_REUSEPORT 15 */
34#define SO_PASSCRED 16
35#define SO_PEERCRED 17
36#define SO_RCVLOWAT 18
37#define SO_SNDLOWAT 19
38#define SO_RCVTIMEO 20
39#define SO_SNDTIMEO 21
40
41/* Security levels - as per NRL IPv6 - don't actually do anything */
42
43#define SO_SECURITY_AUTHENTICATION 22
44#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
45#define SO_SECURITY_ENCRYPTION_NETWORK 24
46
47#define SO_BINDTODEVICE 25
48
49/* Socket filtering */
50
51#define SO_ATTACH_FILTER 26
52#define SO_DETACH_FILTER 27
53
54#define SO_PEERNAME 28
55#define SO_TIMESTAMP 29
56#define SCM_TIMESTAMP SO_TIMESTAMP
57
58#define SO_ACCEPTCONN 30
59#define SO_PEERSEC 31
60
61#endif /* _XTENSA_SOCKET_H */
diff --git a/include/asm-xtensa/sockios.h b/include/asm-xtensa/sockios.h
new file mode 100644
index 000000000000..20d2ba10ecd1
--- /dev/null
+++ b/include/asm-xtensa/sockios.h
@@ -0,0 +1,30 @@
1/*
2 * include/asm-xtensa/sockios.h
3 *
4 * Socket-level I/O control calls. Copied from MIPS.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 1995 by Ralf Baechle
11 * Copyright (C) 2001 Tensilica Inc.
12 */
13
14#ifndef _XTENSA_SOCKIOS_H
15#define _XTENSA_SOCKIOS_H
16
17#include <asm/ioctl.h>
18
19/* Socket-level I/O control calls. */
20
21#define FIOGETOWN _IOR('f', 123, int)
22#define FIOSETOWN _IOW('f', 124, int)
23
24#define SIOCATMARK _IOR('s', 7, int)
25#define SIOCSPGRP _IOW('s', 8, pid_t)
26#define SIOCGPGRP _IOR('s', 9, pid_t)
27
28#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */
29
30#endif /* _XTENSA_SOCKIOS_H */
diff --git a/include/asm-xtensa/spinlock.h b/include/asm-xtensa/spinlock.h
new file mode 100644
index 000000000000..8ff23649581b
--- /dev/null
+++ b/include/asm-xtensa/spinlock.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/spinlock.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SPINLOCK_H
12#define _XTENSA_SPINLOCK_H
13
14#include <linux/spinlock.h>
15
16#endif /* _XTENSA_SPINLOCK_H */
diff --git a/include/asm-xtensa/stat.h b/include/asm-xtensa/stat.h
new file mode 100644
index 000000000000..2f4662ff6c3a
--- /dev/null
+++ b/include/asm-xtensa/stat.h
@@ -0,0 +1,105 @@
1/*
2 * include/asm-xtensa/stat.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_STAT_H
12#define _XTENSA_STAT_H
13
14#include <linux/types.h>
15
16struct __old_kernel_stat {
17 unsigned short st_dev;
18 unsigned short st_ino;
19 unsigned short st_mode;
20 unsigned short st_nlink;
21 unsigned short st_uid;
22 unsigned short st_gid;
23 unsigned short st_rdev;
24 unsigned long st_size;
25 unsigned long st_atime;
26 unsigned long st_mtime;
27 unsigned long st_ctime;
28};
29
30#define STAT_HAVE_NSEC 1
31
32struct stat {
33 unsigned short st_dev;
34 unsigned short __pad1;
35 unsigned long st_ino;
36 unsigned short st_mode;
37 unsigned short st_nlink;
38 unsigned short st_uid;
39 unsigned short st_gid;
40 unsigned short st_rdev;
41 unsigned short __pad2;
42 unsigned long st_size;
43 unsigned long st_blksize;
44 unsigned long st_blocks;
45 unsigned long st_atime;
46 unsigned long st_atime_nsec;
47 unsigned long st_mtime;
48 unsigned long st_mtime_nsec;
49 unsigned long st_ctime;
50 unsigned long st_ctime_nsec;
51 unsigned long __unused4;
52 unsigned long __unused5;
53};
54
55/* This matches struct stat64 in glibc-2.2.3. */
56
57struct stat64 {
58#ifdef __XTENSA_EL__
59 unsigned short st_dev; /* Device */
60 unsigned char __pad0[10];
61#else
62 unsigned char __pad0[6];
63 unsigned short st_dev;
64 unsigned char __pad1[2];
65#endif
66
67#define STAT64_HAS_BROKEN_ST_INO 1
68 unsigned long __st_ino; /* 32bit file serial number. */
69
70 unsigned int st_mode; /* File mode. */
71 unsigned int st_nlink; /* Link count. */
72 unsigned int st_uid; /* User ID of the file's owner. */
73 unsigned int st_gid; /* Group ID of the file's group. */
74
75#ifdef __XTENSA_EL__
76 unsigned short st_rdev; /* Device number, if device. */
77 unsigned char __pad3[10];
78#else
79 unsigned char __pad2[6];
80 unsigned short st_rdev;
81 unsigned char __pad3[2];
82#endif
83
84 long long int st_size; /* Size of file, in bytes. */
85 long int st_blksize; /* Optimal block size for I/O. */
86
87#ifdef __XTENSA_EL__
88 unsigned long st_blocks; /* Number 512-byte blocks allocated. */
89 unsigned long __pad4;
90#else
91 unsigned long __pad4;
92 unsigned long st_blocks;
93#endif
94
95 unsigned long __pad5;
96 long int st_atime; /* Time of last access. */
97 unsigned long st_atime_nsec;
98 long int st_mtime; /* Time of last modification. */
99 unsigned long st_mtime_nsec;
100 long int st_ctime; /* Time of last status change. */
101 unsigned long st_ctime_nsec;
102 unsigned long long int st_ino; /* File serial number. */
103};
104
105#endif /* _XTENSA_STAT_H */
diff --git a/include/asm-xtensa/statfs.h b/include/asm-xtensa/statfs.h
new file mode 100644
index 000000000000..9c3d1a213136
--- /dev/null
+++ b/include/asm-xtensa/statfs.h
@@ -0,0 +1,17 @@
1/*
2 * include/asm-xtensa/statfs.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_STATFS_H
12#define _XTENSA_STATFS_H
13
14#include <asm-generic/statfs.h>
15
16#endif /* _XTENSA_STATFS_H */
17
diff --git a/include/asm-xtensa/string.h b/include/asm-xtensa/string.h
new file mode 100644
index 000000000000..3f81b27d9809
--- /dev/null
+++ b/include/asm-xtensa/string.h
@@ -0,0 +1,124 @@
1/*
2 * include/asm-xtensa/string.h
3 *
4 * These trivial string functions are considered part of the public domain.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13/* We should optimize these. See arch/xtensa/lib/strncpy_user.S */
14
15#ifndef _XTENSA_STRING_H
16#define _XTENSA_STRING_H
17
18#define __HAVE_ARCH_STRCPY
19extern __inline__ char *strcpy(char *__dest, const char *__src)
20{
21 register char *__xdest = __dest;
22 unsigned long __dummy;
23
24 __asm__ __volatile__("1:\n\t"
25 "l8ui %2, %1, 0\n\t"
26 "s8i %2, %0, 0\n\t"
27 "addi %1, %1, 1\n\t"
28 "addi %0, %0, 1\n\t"
29 "bnez %2, 1b\n\t"
30 : "=r" (__dest), "=r" (__src), "=&r" (__dummy)
31 : "0" (__dest), "1" (__src)
32 : "memory");
33
34 return __xdest;
35}
36
37#define __HAVE_ARCH_STRNCPY
38extern __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
39{
40 register char *__xdest = __dest;
41 unsigned long __dummy;
42
43 if (__n == 0)
44 return __xdest;
45
46 __asm__ __volatile__(
47 "1:\n\t"
48 "l8ui %2, %1, 0\n\t"
49 "s8i %2, %0, 0\n\t"
50 "addi %1, %1, 1\n\t"
51 "addi %0, %0, 1\n\t"
52 "beqz %2, 2f\n\t"
53 "bne %1, %5, 1b\n"
54 "2:"
55 : "=r" (__dest), "=r" (__src), "=&r" (__dummy)
56 : "0" (__dest), "1" (__src), "r" (__src+__n)
57 : "memory");
58
59 return __xdest;
60}
61
62#define __HAVE_ARCH_STRCMP
63extern __inline__ int strcmp(const char *__cs, const char *__ct)
64{
65 register int __res;
66 unsigned long __dummy;
67
68 __asm__ __volatile__(
69 "1:\n\t"
70 "l8ui %3, %1, 0\n\t"
71 "addi %1, %1, 1\n\t"
72 "l8ui %2, %0, 0\n\t"
73 "addi %0, %0, 1\n\t"
74 "beqz %2, 2f\n\t"
75 "beq %2, %3, 1b\n"
76 "2:\n\t"
77 "sub %2, %3, %2"
78 : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
79 : "0" (__cs), "1" (__ct));
80
81 return __res;
82}
83
84#define __HAVE_ARCH_STRNCMP
85extern __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
86{
87 register int __res;
88 unsigned long __dummy;
89
90 __asm__ __volatile__(
91 "mov %2, %3\n"
92 "1:\n\t"
93 "beq %0, %6, 2f\n\t"
94 "l8ui %3, %1, 0\n\t"
95 "addi %1, %1, 1\n\t"
96 "l8ui %2, %0, 0\n\t"
97 "addi %0, %0, 1\n\t"
98 "beqz %2, 2f\n\t"
99 "beqz %3, 2f\n\t"
100 "beq %2, %3, 1b\n"
101 "2:\n\t"
102 "sub %2, %3, %2"
103 : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
104 : "0" (__cs), "1" (__ct), "r" (__cs+__n));
105
106 return __res;
107}
108
109#define __HAVE_ARCH_MEMSET
110extern void *memset(void *__s, int __c, size_t __count);
111
112#define __HAVE_ARCH_MEMCPY
113extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
114
115#define __HAVE_ARCH_MEMMOVE
116extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
117
118/* Don't build bcopy at all ... */
119#define __HAVE_ARCH_BCOPY
120
121#define __HAVE_ARCH_MEMSCAN
122#define memscan memchr
123
124#endif /* _XTENSA_STRING_H */
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
new file mode 100644
index 000000000000..690fe325e671
--- /dev/null
+++ b/include/asm-xtensa/system.h
@@ -0,0 +1,252 @@
1/*
2 * include/asm-xtensa/system.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_SYSTEM_H
12#define _XTENSA_SYSTEM_H
13
14#include <linux/config.h>
15#include <linux/stringify.h>
16
17#include <asm/processor.h>
18
19/* interrupt control */
20
21#define local_save_flags(x) \
22 __asm__ __volatile__ ("rsr %0,"__stringify(PS) : "=a" (x));
23#define local_irq_restore(x) do { \
24 __asm__ __volatile__ ("wsr %0, "__stringify(PS)" ; rsync" \
25 :: "a" (x) : "memory"); } while(0);
26#define local_irq_save(x) do { \
27 __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL) \
28 : "=a" (x) :: "memory");} while(0);
29
30static inline void local_irq_disable(void)
31{
32 unsigned long flags;
33 __asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL)
34 : "=a" (flags) :: "memory");
35}
36static inline void local_irq_enable(void)
37{
38 unsigned long flags;
39 __asm__ __volatile__ ("rsil %0, 0" : "=a" (flags) :: "memory");
40
41}
42
43static inline int irqs_disabled(void)
44{
45 unsigned long flags;
46 local_save_flags(flags);
47 return flags & 0xf;
48}
49
50#define RSR_CPENABLE(x) do { \
51 __asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
52 } while(0);
53#define WSR_CPENABLE(x) do { \
54 __asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" \
55 :: "a" (x));} while(0);
56
57#define clear_cpenable() __clear_cpenable()
58
59extern __inline__ void __clear_cpenable(void)
60{
61#if XCHAL_HAVE_CP
62 unsigned long i = 0;
63 WSR_CPENABLE(i);
64#endif
65}
66
67extern __inline__ void enable_coprocessor(int i)
68{
69#if XCHAL_HAVE_CP
70 int cp;
71 RSR_CPENABLE(cp);
72 cp |= 1 << i;
73 WSR_CPENABLE(cp);
74#endif
75}
76
77extern __inline__ void disable_coprocessor(int i)
78{
79#if XCHAL_HAVE_CP
80 int cp;
81 RSR_CPENABLE(cp);
82 cp &= ~(1 << i);
83 WSR_CPENABLE(cp);
84#endif
85}
86
87#define smp_read_barrier_depends() do { } while(0)
88#define read_barrier_depends() do { } while(0)
89
90#define mb() barrier()
91#define rmb() mb()
92#define wmb() mb()
93
94#ifdef CONFIG_SMP
95#error smp_* not defined
96#else
97#define smp_mb() barrier()
98#define smp_rmb() barrier()
99#define smp_wmb() barrier()
100#endif
101
102#define set_mb(var, value) do { var = value; mb(); } while (0)
103#define set_wmb(var, value) do { var = value; wmb(); } while (0)
104
105#if !defined (__ASSEMBLY__)
106
107/* * switch_to(n) should switch tasks to task nr n, first
108 * checking that n isn't the current task, in which case it does nothing.
109 */
110extern void *_switch_to(void *last, void *next);
111
112#endif /* __ASSEMBLY__ */
113
114#define prepare_to_switch() do { } while(0)
115
116#define switch_to(prev,next,last) \
117do { \
118 clear_cpenable(); \
119 (last) = _switch_to(prev, next); \
120} while(0)
121
122/*
123 * cmpxchg
124 */
125
126extern __inline__ unsigned long
127__cmpxchg_u32(volatile int *p, int old, int new)
128{
129 __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t"
130 "l32i %0, %1, 0 \n\t"
131 "bne %0, %2, 1f \n\t"
132 "s32i %3, %1, 0 \n\t"
133 "1: \n\t"
134 "wsr a15, "__stringify(PS)" \n\t"
135 "rsync \n\t"
136 : "=&a" (old)
137 : "a" (p), "a" (old), "r" (new)
138 : "a15", "memory");
139 return old;
140}
141/* This function doesn't exist, so you'll get a linker error
142 * if something tries to do an invalid cmpxchg(). */
143
144extern void __cmpxchg_called_with_bad_pointer(void);
145
146static __inline__ unsigned long
147__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
148{
149 switch (size) {
150 case 4: return __cmpxchg_u32(ptr, old, new);
151 default: __cmpxchg_called_with_bad_pointer();
152 return old;
153 }
154}
155
156#define cmpxchg(ptr,o,n) \
157 ({ __typeof__(*(ptr)) _o_ = (o); \
158 __typeof__(*(ptr)) _n_ = (n); \
159 (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
160 (unsigned long)_n_, sizeof (*(ptr))); \
161 })
162
163
164
165
166/*
167 * xchg_u32
168 *
169 * Note that a15 is used here because the register allocation
170 * done by the compiler is not guaranteed and a window overflow
171 * may not occur between the rsil and wsr instructions. By using
172 * a15 in the rsil, the machine is guaranteed to be in a state
173 * where no register reference will cause an overflow.
174 */
175
176extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
177{
178 unsigned long tmp;
179 __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t"
180 "l32i %0, %1, 0 \n\t"
181 "s32i %2, %1, 0 \n\t"
182 "wsr a15, "__stringify(PS)" \n\t"
183 "rsync \n\t"
184 : "=&a" (tmp)
185 : "a" (m), "a" (val)
186 : "a15", "memory");
187 return tmp;
188}
189
190#define tas(ptr) (xchg((ptr),1))
191
192#if ( __XCC__ == 1 )
193
194/* xt-xcc processes __inline__ differently than xt-gcc and decides to
195 * insert an out-of-line copy of function __xchg. This presents the
196 * unresolved symbol at link time of __xchg_called_with_bad_pointer,
197 * even though such a function would never be called at run-time.
198 * xt-gcc always inlines __xchg, and optimizes away the undefined
199 * bad_pointer function.
200 */
201
202#define xchg(ptr,x) xchg_u32(ptr,x)
203
204#else /* assume xt-gcc */
205
206#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
207
208/*
209 * This only works if the compiler isn't horribly bad at optimizing.
210 * gcc-2.5.8 reportedly can't handle this, but I define that one to
211 * be dead anyway.
212 */
213
214extern void __xchg_called_with_bad_pointer(void);
215
216static __inline__ unsigned long
217__xchg(unsigned long x, volatile void * ptr, int size)
218{
219 switch (size) {
220 case 4:
221 return xchg_u32(ptr, x);
222 }
223 __xchg_called_with_bad_pointer();
224 return x;
225}
226
227#endif
228
229extern void set_except_vector(int n, void *addr);
230
231static inline void spill_registers(void)
232{
233 unsigned int a0, ps;
234
235 __asm__ __volatile__ (
236 "movi a14," __stringify (PS_EXCM_MASK) " | 1\n\t"
237 "mov a12, a0\n\t"
238 "rsr a13," __stringify(SAR) "\n\t"
239 "xsr a14," __stringify(PS) "\n\t"
240 "movi a0, _spill_registers\n\t"
241 "rsync\n\t"
242 "callx0 a0\n\t"
243 "mov a0, a12\n\t"
244 "wsr a13," __stringify(SAR) "\n\t"
245 "wsr a14," __stringify(PS) "\n\t"
246 :: "a" (&a0), "a" (&ps)
247 : "a2", "a3", "a12", "a13", "a14", "a15", "memory");
248}
249
250#define arch_align_stack(x) (x)
251
252#endif /* _XTENSA_SYSTEM_H */
diff --git a/include/asm-xtensa/termbits.h b/include/asm-xtensa/termbits.h
new file mode 100644
index 000000000000..c780593ff5f9
--- /dev/null
+++ b/include/asm-xtensa/termbits.h
@@ -0,0 +1,194 @@
1/*
2 * include/asm-xtensa/termbits.h
3 *
4 * Copied from SH.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_TERMBITS_H
14#define _XTENSA_TERMBITS_H
15
16
17#include <linux/posix_types.h>
18
19typedef unsigned char cc_t;
20typedef unsigned int speed_t;
21typedef unsigned int tcflag_t;
22
23#define NCCS 19
24struct termios {
25 tcflag_t c_iflag; /* input mode flags */
26 tcflag_t c_oflag; /* output mode flags */
27 tcflag_t c_cflag; /* control mode flags */
28 tcflag_t c_lflag; /* local mode flags */
29 cc_t c_line; /* line discipline */
30 cc_t c_cc[NCCS]; /* control characters */
31};
32
33/* c_cc characters */
34
35#define VINTR 0
36#define VQUIT 1
37#define VERASE 2
38#define VKILL 3
39#define VEOF 4
40#define VTIME 5
41#define VMIN 6
42#define VSWTC 7
43#define VSTART 8
44#define VSTOP 9
45#define VSUSP 10
46#define VEOL 11
47#define VREPRINT 12
48#define VDISCARD 13
49#define VWERASE 14
50#define VLNEXT 15
51#define VEOL2 16
52
53/* c_iflag bits */
54
55#define IGNBRK 0000001
56#define BRKINT 0000002
57#define IGNPAR 0000004
58#define PARMRK 0000010
59#define INPCK 0000020
60#define ISTRIP 0000040
61#define INLCR 0000100
62#define IGNCR 0000200
63#define ICRNL 0000400
64#define IUCLC 0001000
65#define IXON 0002000
66#define IXANY 0004000
67#define IXOFF 0010000
68#define IMAXBEL 0020000
69#define IUTF8 0040000
70
71/* c_oflag bits */
72
73#define OPOST 0000001
74#define OLCUC 0000002
75#define ONLCR 0000004
76#define OCRNL 0000010
77#define ONOCR 0000020
78#define ONLRET 0000040
79#define OFILL 0000100
80#define OFDEL 0000200
81#define NLDLY 0000400
82#define NL0 0000000
83#define NL1 0000400
84#define CRDLY 0003000
85#define CR0 0000000
86#define CR1 0001000
87#define CR2 0002000
88#define CR3 0003000
89#define TABDLY 0014000
90#define TAB0 0000000
91#define TAB1 0004000
92#define TAB2 0010000
93#define TAB3 0014000
94#define XTABS 0014000
95#define BSDLY 0020000
96#define BS0 0000000
97#define BS1 0020000
98#define VTDLY 0040000
99#define VT0 0000000
100#define VT1 0040000
101#define FFDLY 0100000
102#define FF0 0000000
103#define FF1 0100000
104
105/* c_cflag bit meaning */
106
107#define CBAUD 0010017
108#define B0 0000000 /* hang up */
109#define B50 0000001
110#define B75 0000002
111#define B110 0000003
112#define B134 0000004
113#define B150 0000005
114#define B200 0000006
115#define B300 0000007
116#define B600 0000010
117#define B1200 0000011
118#define B1800 0000012
119#define B2400 0000013
120#define B4800 0000014
121#define B9600 0000015
122#define B19200 0000016
123#define B38400 0000017
124#define EXTA B19200
125#define EXTB B38400
126#define CSIZE 0000060
127#define CS5 0000000
128#define CS6 0000020
129#define CS7 0000040
130#define CS8 0000060
131#define CSTOPB 0000100
132#define CREAD 0000200
133#define PARENB 0000400
134#define PARODD 0001000
135#define HUPCL 0002000
136#define CLOCAL 0004000
137#define CBAUDEX 0010000
138#define B57600 0010001
139#define B115200 0010002
140#define B230400 0010003
141#define B460800 0010004
142#define B500000 0010005
143#define B576000 0010006
144#define B921600 0010007
145#define B1000000 0010010
146#define B1152000 0010011
147#define B1500000 0010012
148#define B2000000 0010013
149#define B2500000 0010014
150#define B3000000 0010015
151#define B3500000 0010016
152#define B4000000 0010017
153#define CIBAUD 002003600000 /* input baud rate (not used) */
154#define CMSPAR 010000000000 /* mark or space (stick) parity */
155#define CRTSCTS 020000000000 /* flow control */
156
157/* c_lflag bits */
158
159#define ISIG 0000001
160#define ICANON 0000002
161#define XCASE 0000004
162#define ECHO 0000010
163#define ECHOE 0000020
164#define ECHOK 0000040
165#define ECHONL 0000100
166#define NOFLSH 0000200
167#define TOSTOP 0000400
168#define ECHOCTL 0001000
169#define ECHOPRT 0002000
170#define ECHOKE 0004000
171#define FLUSHO 0010000
172#define PENDIN 0040000
173#define IEXTEN 0100000
174
175/* tcflow() and TCXONC use these */
176
177#define TCOOFF 0
178#define TCOON 1
179#define TCIOFF 2
180#define TCION 3
181
182/* tcflush() and TCFLSH use these */
183
184#define TCIFLUSH 0
185#define TCOFLUSH 1
186#define TCIOFLUSH 2
187
188/* tcsetattr uses these */
189
190#define TCSANOW 0
191#define TCSADRAIN 1
192#define TCSAFLUSH 2
193
194#endif /* _XTENSA_TERMBITS_H */
diff --git a/include/asm-xtensa/termios.h b/include/asm-xtensa/termios.h
new file mode 100644
index 000000000000..83c6aed1d115
--- /dev/null
+++ b/include/asm-xtensa/termios.h
@@ -0,0 +1,122 @@
1/*
2 * include/asm-xtensa/termios.h
3 *
4 * Copied from SH.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_TERMIOS_H
14#define _XTENSA_TERMIOS_H
15
16#include <asm/termbits.h>
17#include <asm/ioctls.h>
18
19struct winsize {
20 unsigned short ws_row;
21 unsigned short ws_col;
22 unsigned short ws_xpixel;
23 unsigned short ws_ypixel;
24};
25
26#define NCC 8
27struct termio {
28 unsigned short c_iflag; /* input mode flags */
29 unsigned short c_oflag; /* output mode flags */
30 unsigned short c_cflag; /* control mode flags */
31 unsigned short c_lflag; /* local mode flags */
32 unsigned char c_line; /* line discipline */
33 unsigned char c_cc[NCC]; /* control characters */
34};
35
36/* Modem lines */
37
38#define TIOCM_LE 0x001
39#define TIOCM_DTR 0x002
40#define TIOCM_RTS 0x004
41#define TIOCM_ST 0x008
42#define TIOCM_SR 0x010
43#define TIOCM_CTS 0x020
44#define TIOCM_CAR 0x040
45#define TIOCM_RNG 0x080
46#define TIOCM_DSR 0x100
47#define TIOCM_CD TIOCM_CAR
48#define TIOCM_RI TIOCM_RNG
49#define TIOCM_OUT1 0x2000
50#define TIOCM_OUT2 0x4000
51#define TIOCM_LOOP 0x8000
52
53/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
54
55/* Line disciplines */
56
57#define N_TTY 0
58#define N_SLIP 1
59#define N_MOUSE 2
60#define N_PPP 3
61#define N_STRIP 4
62#define N_AX25 5
63#define N_X25 6 /* X.25 async */
64#define N_6PACK 7
65#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
66#define N_R3964 9 /* Reserved for Simatic R3964 module */
67#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */
68#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */
69#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */
70#define N_HDLC 13 /* synchronous HDLC */
71#define N_SYNC_PPP 14
72#define N_HCI 15 /* Bluetooth HCI UART */
73
74#ifdef __KERNEL__
75
76/* intr=^C quit=^\ erase=del kill=^U
77 eof=^D vtime=\0 vmin=\1 sxtc=\0
78 start=^Q stop=^S susp=^Z eol=\0
79 reprint=^R discard=^U werase=^W lnext=^V
80 eol2=\0
81*/
82#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
83
84/*
85 * Translate a "termio" structure into a "termios". Ugh.
86 */
87
88#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
89 unsigned short __tmp; \
90 get_user(__tmp,&(termio)->x); \
91 *(unsigned short *) &(termios)->x = __tmp; \
92}
93
94#define user_termio_to_kernel_termios(termios, termio) \
95({ \
96 SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
97 SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
98 SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
99 SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
100 copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
101})
102
103/*
104 * Translate a "termios" structure into a "termio". Ugh.
105 */
106
107#define kernel_termios_to_user_termio(termio, termios) \
108({ \
109 put_user((termios)->c_iflag, &(termio)->c_iflag); \
110 put_user((termios)->c_oflag, &(termio)->c_oflag); \
111 put_user((termios)->c_cflag, &(termio)->c_cflag); \
112 put_user((termios)->c_lflag, &(termio)->c_lflag); \
113 put_user((termios)->c_line, &(termio)->c_line); \
114 copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
115})
116
117#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
118#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
119
120#endif /* __KERNEL__ */
121
122#endif /* _XTENSA_TERMIOS_H */
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
new file mode 100644
index 000000000000..af208d41fd82
--- /dev/null
+++ b/include/asm-xtensa/thread_info.h
@@ -0,0 +1,146 @@
1/*
2 * include/asm-xtensa/thread_info.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_THREAD_INFO_H
12#define _XTENSA_THREAD_INFO_H
13
14#ifdef __KERNEL__
15
16#ifndef __ASSEMBLY__
17# include <asm/processor.h>
18#endif
19
20/*
21 * low level task data that entry.S needs immediate access to
22 * - this struct should fit entirely inside of one cache line
23 * - this struct shares the supervisor stack pages
24 * - if the contents of this structure are changed, the assembly constants
25 * must also be changed
26 */
27
28#ifndef __ASSEMBLY__
29
30struct thread_info {
31 struct task_struct *task; /* main task structure */
32 struct exec_domain *exec_domain; /* execution domain */
33 unsigned long flags; /* low level flags */
34 unsigned long status; /* thread-synchronous flags */
35 __u32 cpu; /* current CPU */
36 __s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/
37
38 mm_segment_t addr_limit; /* thread address space */
39 struct restart_block restart_block;
40
41
42};
43
44#else /* !__ASSEMBLY__ */
45
46/* offsets into the thread_info struct for assembly code access */
47#define TI_TASK 0x00000000
48#define TI_EXEC_DOMAIN 0x00000004
49#define TI_FLAGS 0x00000008
50#define TI_STATUS 0x0000000C
51#define TI_CPU 0x00000010
52#define TI_PRE_COUNT 0x00000014
53#define TI_ADDR_LIMIT 0x00000018
54#define TI_RESTART_BLOCK 0x000001C
55
56#endif
57
58#define PREEMPT_ACTIVE 0x10000000
59
60/*
61 * macros/functions for gaining access to the thread information structure
62 *
63 * preempt_count needs to be 1 initially, until the scheduler is functional.
64 */
65
66#ifndef __ASSEMBLY__
67
68#define INIT_THREAD_INFO(tsk) \
69{ \
70 .task = &tsk, \
71 .exec_domain = &default_exec_domain, \
72 .flags = 0, \
73 .cpu = 0, \
74 .preempt_count = 1, \
75 .addr_limit = KERNEL_DS, \
76 .restart_block = { \
77 .fn = do_no_restart_syscall, \
78 }, \
79}
80
81#define init_thread_info (init_thread_union.thread_info)
82#define init_stack (init_thread_union.stack)
83
84/* how to get the thread information struct from C */
85static inline struct thread_info *current_thread_info(void)
86{
87 struct thread_info *ti;
88 __asm__("extui %0,a1,0,13\n\t"
89 "xor %0, a1, %0" : "=&r" (ti) : );
90 return ti;
91}
92
93/* thread information allocation */
94#define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
95#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
96#define get_thread_info(ti) get_task_struct((ti)->task)
97#define put_thread_info(ti) put_task_struct((ti)->task)
98
99#else /* !__ASSEMBLY__ */
100
101/* how to get the thread information struct from ASM */
102#define GET_THREAD_INFO(reg,sp) \
103 extui reg, sp, 0, 13; \
104 xor reg, sp, reg
105#endif
106
107
108/*
109 * thread information flags
110 * - these are process state flags that various assembly files may need to access
111 * - pending work-to-be-done flags are in LSW
112 * - other flags in MSW
113 */
114#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
115#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
116#define TIF_SIGPENDING 2 /* signal pending */
117#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
118#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
119#define TIF_IRET 5 /* return with iret */
120#define TIF_MEMDIE 6
121#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
122
123#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
124#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
125#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
126#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
127#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
128#define _TIF_IRET (1<<TIF_IRET)
129#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
130
131#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
132#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
133
134/*
135 * Thread-synchronous status.
136 *
137 * This is different from the flags in that nobody else
138 * ever touches our thread-synchronous status, so we don't
139 * have to worry about atomic accesses.
140 */
141#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */
142
143#define THREAD_SIZE 8192 //(2*PAGE_SIZE)
144
145#endif /* __KERNEL__ */
146#endif /* _XTENSA_THREAD_INFO */
diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h
new file mode 100644
index 000000000000..d14a3755a12b
--- /dev/null
+++ b/include/asm-xtensa/timex.h
@@ -0,0 +1,94 @@
1/*
2 * include/asm-xtensa/timex.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_TIMEX_H
12#define _XTENSA_TIMEX_H
13
14#ifdef __KERNEL__
15
16#include <asm/processor.h>
17#include <linux/stringify.h>
18
19#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) == 1
20# define LINUX_TIMER 0
21#elif XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) == 1
22# define LINUX_TIMER 1
23#elif XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) == 1
24# define LINUX_TIMER 2
25#else
26# error "Bad timer number for Linux configurations!"
27#endif
28
29#define LINUX_TIMER_INT XCHAL_TIMER_INTERRUPT(LINUX_TIMER)
30#define LINUX_TIMER_MASK (1L << LINUX_TIMER_INT)
31
32#define CLOCK_TICK_RATE 1193180 /* (everyone is using this value) */
33#define CLOCK_TICK_FACTOR 20 /* Factor of both 10^6 and CLOCK_TICK_RATE */
34#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
35 (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
36 << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
37
38#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
39extern unsigned long ccount_per_jiffy;
40extern unsigned long ccount_nsec;
41#define CCOUNT_PER_JIFFY ccount_per_jiffy
42#define CCOUNT_NSEC ccount_nsec
43#else
44#define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
45#define CCOUNT_NSEC (1000000000UL / CONFIG_XTENSA_CPU_CLOCK)
46#endif
47
48
49typedef unsigned long long cycles_t;
50
51/*
52 * Only used for SMP.
53 */
54
55extern cycles_t cacheflush_time;
56
57#define get_cycles() (0)
58
59
60/*
61 * Register access.
62 */
63
64#define WSR_CCOUNT(r) __asm__("wsr %0,"__stringify(CCOUNT) :: "a" (r))
65#define RSR_CCOUNT(r) __asm__("rsr %0,"__stringify(CCOUNT) : "=a" (r))
66#define WSR_CCOMPARE(x,r) __asm__("wsr %0,"__stringify(CCOMPARE_0)"+"__stringify(x) :: "a"(r))
67#define RSR_CCOMPARE(x,r) __asm__("rsr %0,"__stringify(CCOMPARE_0)"+"__stringify(x) : "=a"(r))
68
69static inline unsigned long get_ccount (void)
70{
71 unsigned long ccount;
72 RSR_CCOUNT(ccount);
73 return ccount;
74}
75
76static inline void set_ccount (unsigned long ccount)
77{
78 WSR_CCOUNT(ccount);
79}
80
81static inline unsigned long get_linux_timer (void)
82{
83 unsigned ccompare;
84 RSR_CCOMPARE(LINUX_TIMER, ccompare);
85 return ccompare;
86}
87
88static inline void set_linux_timer (unsigned long ccompare)
89{
90 WSR_CCOMPARE(LINUX_TIMER, ccompare);
91}
92
93#endif /* __KERNEL__ */
94#endif /* _XTENSA_TIMEX_H */
diff --git a/include/asm-xtensa/tlb.h b/include/asm-xtensa/tlb.h
new file mode 100644
index 000000000000..4562b2dcfbc0
--- /dev/null
+++ b/include/asm-xtensa/tlb.h
@@ -0,0 +1,25 @@
1/*
2 * include/asm-xtensa/tlb.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_TLB_H
12#define _XTENSA_TLB_H
13
14#define tlb_start_vma(tlb,vma) do { } while (0)
15#define tlb_end_vma(tlb,vma) do { } while (0)
16#define __tlb_remove_tlb_entry(tlb,pte,addr) do { } while (0)
17
18#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
19
20#include <asm-generic/tlb.h>
21#include <asm/page.h>
22
23#define __pte_free_tlb(tlb,pte) pte_free(pte)
24
25#endif /* _XTENSA_TLB_H */
diff --git a/include/asm-xtensa/tlbflush.h b/include/asm-xtensa/tlbflush.h
new file mode 100644
index 000000000000..23bfe9db45f5
--- /dev/null
+++ b/include/asm-xtensa/tlbflush.h
@@ -0,0 +1,200 @@
1/*
2 * include/asm-xtensa/tlbflush.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_TLBFLUSH_H
12#define _XTENSA_TLBFLUSH_H
13
14#define DEBUG_TLB
15
16#ifdef __KERNEL__
17
18#include <asm/processor.h>
19#include <linux/stringify.h>
20
21/* TLB flushing:
22 *
23 * - flush_tlb_all() flushes all processes TLB entries
24 * - flush_tlb_mm(mm) flushes the specified mm context TLB entries
25 * - flush_tlb_page(mm, vmaddr) flushes a single page
26 * - flush_tlb_range(mm, start, end) flushes a range of pages
27 */
28
29extern void flush_tlb_all(void);
30extern void flush_tlb_mm(struct mm_struct*);
31extern void flush_tlb_page(struct vm_area_struct*,unsigned long);
32extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long);
33
34#define flush_tlb_kernel_range(start,end) flush_tlb_all()
35
36
37/* This is calld in munmap when we have freed up some page-table pages.
38 * We don't need to do anything here, there's nothing special about our
39 * page-table pages.
40 */
41
42extern inline void flush_tlb_pgtables(struct mm_struct *mm,
43 unsigned long start, unsigned long end)
44{
45}
46
47/* TLB operations. */
48
49#define ITLB_WAYS_LOG2 XCHAL_ITLB_WAY_BITS
50#define DTLB_WAYS_LOG2 XCHAL_DTLB_WAY_BITS
51#define ITLB_PROBE_SUCCESS (1 << ITLB_WAYS_LOG2)
52#define DTLB_PROBE_SUCCESS (1 << DTLB_WAYS_LOG2)
53
54extern inline unsigned long itlb_probe(unsigned long addr)
55{
56 unsigned long tmp;
57 __asm__ __volatile__("pitlb %0, %1\n\t" : "=a" (tmp) : "a" (addr));
58 return tmp;
59}
60
61extern inline unsigned long dtlb_probe(unsigned long addr)
62{
63 unsigned long tmp;
64 __asm__ __volatile__("pdtlb %0, %1\n\t" : "=a" (tmp) : "a" (addr));
65 return tmp;
66}
67
68extern inline void invalidate_itlb_entry (unsigned long probe)
69{
70 __asm__ __volatile__("iitlb %0; isync\n\t" : : "a" (probe));
71}
72
73extern inline void invalidate_dtlb_entry (unsigned long probe)
74{
75 __asm__ __volatile__("idtlb %0; dsync\n\t" : : "a" (probe));
76}
77
78/* Use the .._no_isync functions with caution. Generally, these are
79 * handy for bulk invalidates followed by a single 'isync'. The
80 * caller must follow up with an 'isync', which can be relatively
81 * expensive on some Xtensa implementations.
82 */
83extern inline void invalidate_itlb_entry_no_isync (unsigned entry)
84{
85 /* Caller must follow up with 'isync'. */
86 __asm__ __volatile__ ("iitlb %0\n" : : "a" (entry) );
87}
88
89extern inline void invalidate_dtlb_entry_no_isync (unsigned entry)
90{
91 /* Caller must follow up with 'isync'. */
92 __asm__ __volatile__ ("idtlb %0\n" : : "a" (entry) );
93}
94
95extern inline void set_itlbcfg_register (unsigned long val)
96{
97 __asm__ __volatile__("wsr %0, "__stringify(ITLBCFG)"\n\t" "isync\n\t"
98 : : "a" (val));
99}
100
101extern inline void set_dtlbcfg_register (unsigned long val)
102{
103 __asm__ __volatile__("wsr %0, "__stringify(DTLBCFG)"; dsync\n\t"
104 : : "a" (val));
105}
106
107extern inline void set_ptevaddr_register (unsigned long val)
108{
109 __asm__ __volatile__(" wsr %0, "__stringify(PTEVADDR)"; isync\n"
110 : : "a" (val));
111}
112
113extern inline unsigned long read_ptevaddr_register (void)
114{
115 unsigned long tmp;
116 __asm__ __volatile__("rsr %0, "__stringify(PTEVADDR)"\n\t" : "=a" (tmp));
117 return tmp;
118}
119
120extern inline void write_dtlb_entry (pte_t entry, int way)
121{
122 __asm__ __volatile__("wdtlb %1, %0; dsync\n\t"
123 : : "r" (way), "r" (entry) );
124}
125
126extern inline void write_itlb_entry (pte_t entry, int way)
127{
128 __asm__ __volatile__("witlb %1, %0; isync\n\t"
129 : : "r" (way), "r" (entry) );
130}
131
132extern inline void invalidate_page_directory (void)
133{
134 invalidate_dtlb_entry (DTLB_WAY_PGTABLE);
135}
136
137extern inline void invalidate_itlb_mapping (unsigned address)
138{
139 unsigned long tlb_entry;
140 while ((tlb_entry = itlb_probe (address)) & ITLB_PROBE_SUCCESS)
141 invalidate_itlb_entry (tlb_entry);
142}
143
144extern inline void invalidate_dtlb_mapping (unsigned address)
145{
146 unsigned long tlb_entry;
147 while ((tlb_entry = dtlb_probe (address)) & DTLB_PROBE_SUCCESS)
148 invalidate_dtlb_entry (tlb_entry);
149}
150
151#define check_pgt_cache() do { } while (0)
152
153
154#ifdef DEBUG_TLB
155
156/* DO NOT USE THESE FUNCTIONS. These instructions aren't part of the Xtensa
157 * ISA and exist only for test purposes..
158 * You may find it helpful for MMU debugging, however.
159 *
160 * 'at' is the unmodified input register
161 * 'as' is the output register, as follows (specific to the Linux config):
162 *
163 * as[31..12] contain the virtual address
164 * as[11..08] are meaningless
165 * as[07..00] contain the asid
166 */
167
168extern inline unsigned long read_dtlb_virtual (int way)
169{
170 unsigned long tmp;
171 __asm__ __volatile__("rdtlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way));
172 return tmp;
173}
174
175extern inline unsigned long read_dtlb_translation (int way)
176{
177 unsigned long tmp;
178 __asm__ __volatile__("rdtlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way));
179 return tmp;
180}
181
182extern inline unsigned long read_itlb_virtual (int way)
183{
184 unsigned long tmp;
185 __asm__ __volatile__("ritlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way));
186 return tmp;
187}
188
189extern inline unsigned long read_itlb_translation (int way)
190{
191 unsigned long tmp;
192 __asm__ __volatile__("ritlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way));
193 return tmp;
194}
195
196#endif /* DEBUG_TLB */
197
198
199#endif /* __KERNEL__ */
200#endif /* _XTENSA_PGALLOC_H */
diff --git a/include/asm-xtensa/topology.h b/include/asm-xtensa/topology.h
new file mode 100644
index 000000000000..7309e38a0ccb
--- /dev/null
+++ b/include/asm-xtensa/topology.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/topology.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_TOPOLOGY_H
12#define _XTENSA_TOPOLOGY_H
13
14#include <asm-generic/topology.h>
15
16#endif /* _XTENSA_TOPOLOGY_H */
diff --git a/include/asm-xtensa/types.h b/include/asm-xtensa/types.h
new file mode 100644
index 000000000000..ebac00469852
--- /dev/null
+++ b/include/asm-xtensa/types.h
@@ -0,0 +1,66 @@
1/*
2 * include/asm-xtensa/types.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_TYPES_H
12#define _XTENSA_TYPES_H
13
14#ifndef __ASSEMBLY__
15
16typedef unsigned short umode_t;
17
18/*
19 * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
20 * header files exported to user space
21 */
22
23typedef __signed__ char __s8;
24typedef unsigned char __u8;
25
26typedef __signed__ short __s16;
27typedef unsigned short __u16;
28
29typedef __signed__ int __s32;
30typedef unsigned int __u32;
31
32#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
33typedef __signed__ long long __s64;
34typedef unsigned long long __u64;
35#endif
36
37/*
38 * These aren't exported outside the kernel to avoid name space clashes
39 */
40#ifdef __KERNEL__
41
42typedef __signed__ char s8;
43typedef unsigned char u8;
44
45typedef __signed__ short s16;
46typedef unsigned short u16;
47
48typedef __signed__ int s32;
49typedef unsigned int u32;
50
51typedef __signed__ long long s64;
52typedef unsigned long long u64;
53
54
55#define BITS_PER_LONG 32
56
57/* Dma addresses are 32-bits wide. */
58
59typedef u32 dma_addr_t;
60
61typedef unsigned int kmem_bufctl_t;
62
63#endif /* __KERNEL__ */
64#endif
65
66#endif /* _XTENSA_TYPES_H */
diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
new file mode 100644
index 000000000000..35576b25c7b2
--- /dev/null
+++ b/include/asm-xtensa/uaccess.h
@@ -0,0 +1,532 @@
1/*
2 * include/asm-xtensa/uaccess.h
3 *
4 * User space memory access functions
5 *
6 * These routines provide basic accessing functions to the user memory
7 * space for the kernel. This header file provides fuctions such as:
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 * Copyright (C) 2001 - 2005 Tensilica Inc.
14 */
15
16#ifndef _XTENSA_UACCESS_H
17#define _XTENSA_UACCESS_H
18
19#include <linux/errno.h>
20
21#define VERIFY_READ 0
22#define VERIFY_WRITE 1
23
24#ifdef __ASSEMBLY__
25
26#define _ASMLANGUAGE
27#include <asm/current.h>
28#include <asm/offsets.h>
29#include <asm/processor.h>
30
31/*
32 * These assembly macros mirror the C macros that follow below. They
33 * should always have identical functionality. See
34 * arch/xtensa/kernel/sys.S for usage.
35 */
36
37#define KERNEL_DS 0
38#define USER_DS 1
39
40#define get_ds (KERNEL_DS)
41
42/*
43 * get_fs reads current->thread.current_ds into a register.
44 * On Entry:
45 * <ad> anything
46 * <sp> stack
47 * On Exit:
48 * <ad> contains current->thread.current_ds
49 */
50 .macro get_fs ad, sp
51 GET_CURRENT(\ad,\sp)
52 l32i \ad, \ad, THREAD_CURRENT_DS
53 .endm
54
55/*
56 * set_fs sets current->thread.current_ds to some value.
57 * On Entry:
58 * <at> anything (temp register)
59 * <av> value to write
60 * <sp> stack
61 * On Exit:
62 * <at> destroyed (actually, current)
63 * <av> preserved, value to write
64 */
65 .macro set_fs at, av, sp
66 GET_CURRENT(\at,\sp)
67 s32i \av, \at, THREAD_CURRENT_DS
68 .endm
69
70/*
71 * kernel_ok determines whether we should bypass addr/size checking.
72 * See the equivalent C-macro version below for clarity.
73 * On success, kernel_ok branches to a label indicated by parameter
74 * <success>. This implies that the macro falls through to the next
75 * insruction on an error.
76 *
77 * Note that while this macro can be used independently, we designed
78 * in for optimal use in the access_ok macro below (i.e., we fall
79 * through on error).
80 *
81 * On Entry:
82 * <at> anything (temp register)
83 * <success> label to branch to on success; implies
84 * fall-through macro on error
85 * <sp> stack pointer
86 * On Exit:
87 * <at> destroyed (actually, current->thread.current_ds)
88 */
89
90#if ((KERNEL_DS != 0) || (USER_DS == 0))
91# error Assembly macro kernel_ok fails
92#endif
93 .macro kernel_ok at, sp, success
94 get_fs \at, \sp
95 beqz \at, \success
96 .endm
97
98/*
99 * user_ok determines whether the access to user-space memory is allowed.
100 * See the equivalent C-macro version below for clarity.
101 *
102 * On error, user_ok branches to a label indicated by parameter
103 * <error>. This implies that the macro falls through to the next
104 * instruction on success.
105 *
106 * Note that while this macro can be used independently, we designed
107 * in for optimal use in the access_ok macro below (i.e., we fall
108 * through on success).
109 *
110 * On Entry:
111 * <aa> register containing memory address
112 * <as> register containing memory size
113 * <at> temp register
114 * <error> label to branch to on error; implies fall-through
115 * macro on success
116 * On Exit:
117 * <aa> preserved
118 * <as> preserved
119 * <at> destroyed (actually, (TASK_SIZE + 1 - size))
120 */
121 .macro user_ok aa, as, at, error
122 movi \at, (TASK_SIZE+1)
123 bgeu \as, \at, \error
124 sub \at, \at, \as
125 bgeu \aa, \at, \error
126 .endm
127
128/*
129 * access_ok determines whether a memory access is allowed. See the
130 * equivalent C-macro version below for clarity.
131 *
132 * On error, access_ok branches to a label indicated by parameter
133 * <error>. This implies that the macro falls through to the next
134 * instruction on success.
135 *
136 * Note that we assume success is the common case, and we optimize the
137 * branch fall-through case on success.
138 *
139 * On Entry:
140 * <aa> register containing memory address
141 * <as> register containing memory size
142 * <at> temp register
143 * <sp>
144 * <error> label to branch to on error; implies fall-through
145 * macro on success
146 * On Exit:
147 * <aa> preserved
148 * <as> preserved
149 * <at> destroyed
150 */
151 .macro access_ok aa, as, at, sp, error
152 kernel_ok \at, \sp, .Laccess_ok_\@
153 user_ok \aa, \as, \at, \error
154.Laccess_ok_\@:
155 .endm
156
157/*
158 * verify_area determines whether a memory access is allowed. It's
159 * mostly an unnecessary wrapper for access_ok, but we provide it as a
160 * duplicate of the verify_area() C inline function below. See the
161 * equivalent C version below for clarity.
162 *
163 * On error, verify_area branches to a label indicated by parameter
164 * <error>. This implies that the macro falls through to the next
165 * instruction on success.
166 *
167 * Note that we assume success is the common case, and we optimize the
168 * branch fall-through case on success.
169 *
170 * On Entry:
171 * <aa> register containing memory address
172 * <as> register containing memory size
173 * <at> temp register
174 * <error> label to branch to on error; implies fall-through
175 * macro on success
176 * On Exit:
177 * <aa> preserved
178 * <as> preserved
179 * <at> destroyed
180 */
181 .macro verify_area aa, as, at, sp, error
182 access_ok \at, \aa, \as, \sp, \error
183 .endm
184
185
186#else /* __ASSEMBLY__ not defined */
187
188#include <linux/sched.h>
189#include <asm/types.h>
190
191/*
192 * The fs value determines whether argument validity checking should
193 * be performed or not. If get_fs() == USER_DS, checking is
194 * performed, with get_fs() == KERNEL_DS, checking is bypassed.
195 *
196 * For historical reasons (Data Segment Register?), these macros are
197 * grossly misnamed.
198 */
199
200#define KERNEL_DS ((mm_segment_t) { 0 })
201#define USER_DS ((mm_segment_t) { 1 })
202
203#define get_ds() (KERNEL_DS)
204#define get_fs() (current->thread.current_ds)
205#define set_fs(val) (current->thread.current_ds = (val))
206
207#define segment_eq(a,b) ((a).seg == (b).seg)
208
209#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
210#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
211#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
212#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
213
214extern inline int verify_area(int type, const void * addr, unsigned long size)
215{
216 return access_ok(type,addr,size) ? 0 : -EFAULT;
217}
218
219/*
220 * These are the main single-value transfer routines. They
221 * automatically use the right size if we just have the right pointer
222 * type.
223 *
224 * This gets kind of ugly. We want to return _two_ values in
225 * "get_user()" and yet we don't want to do any pointers, because that
226 * is too much of a performance impact. Thus we have a few rather ugly
227 * macros here, and hide all the uglyness from the user.
228 *
229 * Careful to not
230 * (a) re-use the arguments for side effects (sizeof is ok)
231 * (b) require any knowledge of processes at this stage
232 */
233#define put_user(x,ptr) __put_user_check((x),(ptr),sizeof(*(ptr)))
234#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr)))
235
236/*
237 * The "__xxx" versions of the user access functions are versions that
238 * do not verify the address space, that must have been done previously
239 * with a separate "access_ok()" call (this is used when we do multiple
240 * accesses to the same area of user memory).
241 */
242#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
243#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
244
245
246extern long __put_user_bad(void);
247
248#define __put_user_nocheck(x,ptr,size) \
249({ \
250 long __pu_err; \
251 __put_user_size((x),(ptr),(size),__pu_err); \
252 __pu_err; \
253})
254
255#define __put_user_check(x,ptr,size) \
256({ \
257 long __pu_err = -EFAULT; \
258 __typeof__(*(ptr)) *__pu_addr = (ptr); \
259 if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
260 __put_user_size((x),__pu_addr,(size),__pu_err); \
261 __pu_err; \
262})
263
264#define __put_user_size(x,ptr,size,retval) \
265do { \
266 retval = 0; \
267 switch (size) { \
268 case 1: __put_user_asm(x,ptr,retval,1,"s8i"); break; \
269 case 2: __put_user_asm(x,ptr,retval,2,"s16i"); break; \
270 case 4: __put_user_asm(x,ptr,retval,4,"s32i"); break; \
271 case 8: { \
272 __typeof__(*ptr) __v64 = x; \
273 retval = __copy_to_user(ptr,&__v64,8); \
274 break; \
275 } \
276 default: __put_user_bad(); \
277 } \
278} while (0)
279
280
281/*
282 * Consider a case of a user single load/store would cause both an
283 * unaligned exception and an MMU-related exception (unaligned
284 * exceptions happen first):
285 *
286 * User code passes a bad variable ptr to a system call.
287 * Kernel tries to access the variable.
288 * Unaligned exception occurs.
289 * Unaligned exception handler tries to make aligned accesses.
290 * Double exception occurs for MMU-related cause (e.g., page not mapped).
291 * do_page_fault() thinks the fault address belongs to the kernel, not the
292 * user, and panics.
293 *
294 * The kernel currently prohibits user unaligned accesses. We use the
295 * __check_align_* macros to check for unaligned addresses before
296 * accessing user space so we don't crash the kernel. Both
297 * __put_user_asm and __get_user_asm use these alignment macros, so
298 * macro-specific labels such as 0f, 1f, %0, %2, and %3 must stay in
299 * sync.
300 */
301
302#define __check_align_1 ""
303
304#define __check_align_2 \
305 " _bbci.l %2, 0, 1f \n" \
306 " movi %0, %3 \n" \
307 " _j 2f \n"
308
309#define __check_align_4 \
310 " _bbsi.l %2, 0, 0f \n" \
311 " _bbci.l %2, 1, 1f \n" \
312 "0: movi %0, %3 \n" \
313 " _j 2f \n"
314
315
316/*
317 * We don't tell gcc that we are accessing memory, but this is OK
318 * because we do not write to any memory gcc knows about, so there
319 * are no aliasing issues.
320 *
321 * WARNING: If you modify this macro at all, verify that the
322 * __check_align_* macros still work.
323 */
324#define __put_user_asm(x, addr, err, align, insn) \
325 __asm__ __volatile__( \
326 __check_align_##align \
327 "1: "insn" %1, %2, 0 \n" \
328 "2: \n" \
329 " .section .fixup,\"ax\" \n" \
330 " .align 4 \n" \
331 "4: \n" \
332 " .long 2b \n" \
333 "5: \n" \
334 " l32r %2, 4b \n" \
335 " movi %0, %3 \n" \
336 " jx %2 \n" \
337 " .previous \n" \
338 " .section __ex_table,\"a\" \n" \
339 " .long 1b, 5b \n" \
340 " .previous" \
341 :"=r" (err) \
342 :"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err))
343
344#define __get_user_nocheck(x,ptr,size) \
345({ \
346 long __gu_err, __gu_val; \
347 __get_user_size(__gu_val,(ptr),(size),__gu_err); \
348 (x) = (__typeof__(*(ptr)))__gu_val; \
349 __gu_err; \
350})
351
352#define __get_user_check(x,ptr,size) \
353({ \
354 long __gu_err = -EFAULT, __gu_val = 0; \
355 const __typeof__(*(ptr)) *__gu_addr = (ptr); \
356 if (access_ok(VERIFY_READ,__gu_addr,size)) \
357 __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \
358 (x) = (__typeof__(*(ptr)))__gu_val; \
359 __gu_err; \
360})
361
362extern long __get_user_bad(void);
363
364#define __get_user_size(x,ptr,size,retval) \
365do { \
366 retval = 0; \
367 switch (size) { \
368 case 1: __get_user_asm(x,ptr,retval,1,"l8ui"); break; \
369 case 2: __get_user_asm(x,ptr,retval,2,"l16ui"); break; \
370 case 4: __get_user_asm(x,ptr,retval,4,"l32i"); break; \
371 case 8: retval = __copy_from_user(&x,ptr,8); break; \
372 default: (x) = __get_user_bad(); \
373 } \
374} while (0)
375
376
377/*
378 * WARNING: If you modify this macro at all, verify that the
379 * __check_align_* macros still work.
380 */
381#define __get_user_asm(x, addr, err, align, insn) \
382 __asm__ __volatile__( \
383 __check_align_##align \
384 "1: "insn" %1, %2, 0 \n" \
385 "2: \n" \
386 " .section .fixup,\"ax\" \n" \
387 " .align 4 \n" \
388 "4: \n" \
389 " .long 2b \n" \
390 "5: \n" \
391 " l32r %2, 4b \n" \
392 " movi %1, 0 \n" \
393 " movi %0, %3 \n" \
394 " jx %2 \n" \
395 " .previous \n" \
396 " .section __ex_table,\"a\" \n" \
397 " .long 1b, 5b \n" \
398 " .previous" \
399 :"=r" (err), "=r" (x) \
400 :"r" (addr), "i" (-EFAULT), "0" (err))
401
402
403/*
404 * Copy to/from user space
405 */
406
407/*
408 * We use a generic, arbitrary-sized copy subroutine. The Xtensa
409 * architecture would cause heavy code bloat if we tried to inline
410 * these functions and provide __constant_copy_* equivalents like the
411 * i386 versions. __xtensa_copy_user is quite efficient. See the
412 * .fixup section of __xtensa_copy_user for a discussion on the
413 * X_zeroing equivalents for Xtensa.
414 */
415
416extern unsigned __xtensa_copy_user(void *to, const void *from, unsigned n);
417#define __copy_user(to,from,size) __xtensa_copy_user(to,from,size)
418
419
420static inline unsigned long
421__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
422{
423 return __copy_user(to,from,n);
424}
425
426static inline unsigned long
427__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
428{
429 return __copy_user(to,from,n);
430}
431
432static inline unsigned long
433__generic_copy_to_user(void *to, const void *from, unsigned long n)
434{
435 prefetch(from);
436 if (access_ok(VERIFY_WRITE, to, n))
437 return __copy_user(to,from,n);
438 return n;
439}
440
441static inline unsigned long
442__generic_copy_from_user(void *to, const void *from, unsigned long n)
443{
444 prefetchw(to);
445 if (access_ok(VERIFY_READ, from, n))
446 return __copy_user(to,from,n);
447 else
448 memset(to, 0, n);
449 return n;
450}
451
452#define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n))
453#define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n))
454#define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n))
455#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n))
456#define __copy_to_user_inatomic __copy_to_user
457#define __copy_from_user_inatomic __copy_from_user
458
459
460/*
461 * We need to return the number of bytes not cleared. Our memset()
462 * returns zero if a problem occurs while accessing user-space memory.
463 * In that event, return no memory cleared. Otherwise, zero for
464 * success.
465 */
466
467extern inline unsigned long
468__xtensa_clear_user(void *addr, unsigned long size)
469{
470 if ( ! memset(addr, 0, size) )
471 return size;
472 return 0;
473}
474
475extern inline unsigned long
476clear_user(void *addr, unsigned long size)
477{
478 if (access_ok(VERIFY_WRITE, addr, size))
479 return __xtensa_clear_user(addr, size);
480 return size ? -EFAULT : 0;
481}
482
483#define __clear_user __xtensa_clear_user
484
485
486extern long __strncpy_user(char *, const char *, long);
487#define __strncpy_from_user __strncpy_user
488
489extern inline long
490strncpy_from_user(char *dst, const char *src, long count)
491{
492 if (access_ok(VERIFY_READ, src, 1))
493 return __strncpy_from_user(dst, src, count);
494 return -EFAULT;
495}
496
497
498#define strlen_user(str) strnlen_user((str), TASK_SIZE - 1)
499
500/*
501 * Return the size of a string (including the ending 0!)
502 */
503extern long __strnlen_user(const char *, long);
504
505extern inline long strnlen_user(const char *str, long len)
506{
507 unsigned long top = __kernel_ok ? ~0UL : TASK_SIZE - 1;
508
509 if ((unsigned long)str > top)
510 return 0;
511 return __strnlen_user(str, len);
512}
513
514
515struct exception_table_entry
516{
517 unsigned long insn, fixup;
518};
519
520/* Returns 0 if exception not found and fixup.unit otherwise. */
521
522extern unsigned long search_exception_table(unsigned long addr);
523extern void sort_exception_table(void);
524
525/* Returns the new pc */
526#define fixup_exception(map_reg, fixup_unit, pc) \
527({ \
528 fixup_unit; \
529})
530
531#endif /* __ASSEMBLY__ */
532#endif /* _XTENSA_UACCESS_H */
diff --git a/include/asm-xtensa/ucontext.h b/include/asm-xtensa/ucontext.h
new file mode 100644
index 000000000000..94c94ed3e00a
--- /dev/null
+++ b/include/asm-xtensa/ucontext.h
@@ -0,0 +1,22 @@
1/*
2 * include/asm-xtensa/ucontext.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_UCONTEXT_H
12#define _XTENSA_UCONTEXT_H
13
14struct ucontext {
15 unsigned long uc_flags;
16 struct ucontext *uc_link;
17 stack_t uc_stack;
18 struct sigcontext uc_mcontext;
19 sigset_t uc_sigmask; /* mask last for extensibility */
20};
21
22#endif /* _XTENSA_UCONTEXT_H */
diff --git a/include/asm-xtensa/unaligned.h b/include/asm-xtensa/unaligned.h
new file mode 100644
index 000000000000..28220890d0a6
--- /dev/null
+++ b/include/asm-xtensa/unaligned.h
@@ -0,0 +1,28 @@
1/*
2 * include/asm-xtensa/unaligned.h
3 *
4 * Xtensa doesn't handle unaligned accesses efficiently.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_UNALIGNED_H
14#define _XTENSA_UNALIGNED_H
15
16#include <linux/string.h>
17
18/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
19
20#define get_unaligned(ptr) \
21 ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
22
23#define put_unaligned(val, ptr) \
24 ({ __typeof__(*(ptr)) __tmp = (val); \
25 memmove((ptr), &__tmp, sizeof(*(ptr))); \
26 (void)0; })
27
28#endif /* _XTENSA_UNALIGNED_H */
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h
new file mode 100644
index 000000000000..64c64dd83ba4
--- /dev/null
+++ b/include/asm-xtensa/unistd.h
@@ -0,0 +1,537 @@
1/*
2 * include/asm-xtensa/unistd.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_UNISTD_H
12#define _XTENSA_UNISTD_H
13
14#include <linux/linkage.h>
15
16//#define __NR_setup 0 /* used only by init, to get system going */
17#define __NR_spill 0
18#define __NR_exit 1
19#define __NR_fork 2
20#define __NR_read 3
21#define __NR_write 4
22#define __NR_open 5
23#define __NR_close 6
24#define __NR_waitpid 7
25#define __NR_creat 8
26#define __NR_link 9
27#define __NR_unlink 10
28#define __NR_execve 11
29#define __NR_chdir 12
30#define __NR_time 13
31#define __NR_mknod 14
32#define __NR_chmod 15
33#define __NR_lchown 16
34#define __NR_break 17
35#define __NR_oldstat 18
36#define __NR_lseek 19
37#define __NR_getpid 20
38#define __NR_mount 21
39#define __NR_oldumount 22
40#define __NR_setuid 23
41#define __NR_getuid 24
42#define __NR_stime 25
43#define __NR_ptrace 26
44#define __NR_alarm 27
45#define __NR_oldfstat 28
46#define __NR_pause 29
47#define __NR_utime 30
48#define __NR_stty 31
49#define __NR_gtty 32
50#define __NR_access 33
51#define __NR_nice 34
52#define __NR_ftime 35
53#define __NR_sync 36
54#define __NR_kill 37
55#define __NR_rename 38
56#define __NR_mkdir 39
57#define __NR_rmdir 40
58#define __NR_dup 41
59#define __NR_pipe 42
60#define __NR_times 43
61#define __NR_prof 44
62#define __NR_brk 45
63#define __NR_setgid 46
64#define __NR_getgid 47
65#define __NR_signal 48
66#define __NR_geteuid 49
67#define __NR_getegid 50
68#define __NR_acct 51
69#define __NR_umount 52
70#define __NR_lock 53
71#define __NR_ioctl 54
72#define __NR_fcntl 55
73#define __NR_mpx 56
74#define __NR_setpgid 57
75#define __NR_ulimit 58
76#define __NR_oldolduname 59
77#define __NR_umask 60
78#define __NR_chroot 61
79#define __NR_ustat 62
80#define __NR_dup2 63
81#define __NR_getppid 64
82#define __NR_getpgrp 65
83#define __NR_setsid 66
84#define __NR_sigaction 67
85#define __NR_sgetmask 68
86#define __NR_ssetmask 69
87#define __NR_setreuid 70
88#define __NR_setregid 71
89#define __NR_sigsuspend 72
90#define __NR_sigpending 73
91#define __NR_sethostname 74
92#define __NR_setrlimit 75
93#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
94#define __NR_getrusage 77
95#define __NR_gettimeofday 78
96#define __NR_settimeofday 79
97#define __NR_getgroups 80
98#define __NR_setgroups 81
99#define __NR_select 82
100#define __NR_symlink 83
101#define __NR_oldlstat 84
102#define __NR_readlink 85
103#define __NR_uselib 86
104#define __NR_swapon 87
105#define __NR_reboot 88
106#define __NR_readdir 89
107#define __NR_mmap 90
108#define __NR_munmap 91
109#define __NR_truncate 92
110#define __NR_ftruncate 93
111#define __NR_fchmod 94
112#define __NR_fchown 95
113#define __NR_getpriority 96
114#define __NR_setpriority 97
115#define __NR_profil 98
116#define __NR_statfs 99
117#define __NR_fstatfs 100
118#define __NR_ioperm 101
119#define __NR_socketcall 102
120#define __NR_syslog 103
121#define __NR_setitimer 104
122#define __NR_getitimer 105
123#define __NR_stat 106
124#define __NR_lstat 107
125#define __NR_fstat 108
126#define __NR_olduname 109
127#define __NR_iopl 110
128#define __NR_vhangup 111
129#define __NR_idle 112
130#define __NR_vm86 113
131#define __NR_wait4 114
132#define __NR_swapoff 115
133#define __NR_sysinfo 116
134#define __NR_ipc 117
135#define __NR_fsync 118
136#define __NR_sigreturn 119
137#define __NR_clone 120
138#define __NR_setdomainname 121
139#define __NR_uname 122
140#define __NR_modify_ldt 123
141#define __NR_adjtimex 124
142#define __NR_mprotect 125
143#define __NR_sigprocmask 126
144#define __NR_create_module 127
145#define __NR_init_module 128
146#define __NR_delete_module 129
147#define __NR_get_kernel_syms 130
148#define __NR_quotactl 131
149#define __NR_getpgid 132
150#define __NR_fchdir 133
151#define __NR_bdflush 134
152#define __NR_sysfs 135
153#define __NR_personality 136
154#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
155#define __NR_setfsuid 138
156#define __NR_setfsgid 139
157#define __NR__llseek 140
158#define __NR_getdents 141
159#define __NR__newselect 142
160#define __NR_flock 143
161#define __NR_msync 144
162#define __NR_readv 145
163#define __NR_writev 146
164#define __NR_cacheflush 147
165#define __NR_cachectl 148
166#define __NR_sysxtensa 149
167#define __NR_sysdummy 150
168#define __NR_getsid 151
169#define __NR_fdatasync 152
170#define __NR__sysctl 153
171#define __NR_mlock 154
172#define __NR_munlock 155
173#define __NR_mlockall 156
174#define __NR_munlockall 157
175#define __NR_sched_setparam 158
176#define __NR_sched_getparam 159
177#define __NR_sched_setscheduler 160
178#define __NR_sched_getscheduler 161
179#define __NR_sched_yield 162
180#define __NR_sched_get_priority_max 163
181#define __NR_sched_get_priority_min 164
182#define __NR_sched_rr_get_interval 165
183#define __NR_nanosleep 166
184#define __NR_mremap 167
185#define __NR_accept 168
186#define __NR_bind 169
187#define __NR_connect 170
188#define __NR_getpeername 171
189#define __NR_getsockname 172
190#define __NR_getsockopt 173
191#define __NR_listen 174
192#define __NR_recv 175
193#define __NR_recvfrom 176
194#define __NR_recvmsg 177
195#define __NR_send 178
196#define __NR_sendmsg 179
197#define __NR_sendto 180
198#define __NR_setsockopt 181
199#define __NR_shutdown 182
200#define __NR_socket 183
201#define __NR_socketpair 184
202#define __NR_setresuid 185
203#define __NR_getresuid 186
204#define __NR_query_module 187
205#define __NR_poll 188
206#define __NR_nfsservctl 189
207#define __NR_setresgid 190
208#define __NR_getresgid 191
209#define __NR_prctl 192
210#define __NR_rt_sigreturn 193
211#define __NR_rt_sigaction 194
212#define __NR_rt_sigprocmask 195
213#define __NR_rt_sigpending 196
214#define __NR_rt_sigtimedwait 197
215#define __NR_rt_sigqueueinfo 198
216#define __NR_rt_sigsuspend 199
217#define __NR_pread 200
218#define __NR_pwrite 201
219#define __NR_chown 202
220#define __NR_getcwd 203
221#define __NR_capget 204
222#define __NR_capset 205
223#define __NR_sigaltstack 206
224#define __NR_sendfile 207
225#define __NR_streams1 208 /* some people actually want it */
226#define __NR_streams2 209 /* some people actually want it */
227#define __NR_mmap2 210
228#define __NR_truncate64 211
229#define __NR_ftruncate64 212
230#define __NR_stat64 213
231#define __NR_lstat64 214
232#define __NR_fstat64 215
233#define __NR_pivot_root 216
234#define __NR_mincore 217
235#define __NR_madvise 218
236#define __NR_getdents64 219
237#define __NR_vfork 220
238
239/* Keep this last; should always equal the last valid call number. */
240#define __NR_Linux_syscalls 220
241
242/* user-visible error numbers are in the range -1 - -125: see
243 * <asm-xtensa/errno.h> */
244
245#define SYSXTENSA_RESERVED 0 /* don't use this */
246#define SYSXTENSA_ATOMIC_SET 1 /* set variable */
247#define SYSXTENSA_ATOMIC_EXG_ADD 2 /* exchange memory and add */
248#define SYSXTENSA_ATOMIC_ADD 3 /* add to memory */
249#define SYSXTENSA_ATOMIC_CMP_SWP 4 /* compare and swap */
250
251#define SYSXTENSA_COUNT 5 /* count of syscall0 functions*/
252
253#ifdef __KERNEL__
254#define __syscall_return(type, res) return ((type)(res))
255#else
256#define __syscall_return(type, res) \
257do { \
258 if ((unsigned long)(res) >= (unsigned long)(-125)) { \
259 /* Avoid using "res" which is declared to be in register r2; \
260 * errno might expand to a function call and clobber it. */ \
261 int __err = -(res); \
262 errno = __err; \
263 res = -1; \
264 } \
265 return (type) (res); \
266} while (0)
267#endif
268
269
270/* Tensilica's xt-xcc compiler is much more agressive at code
271 * optimization than gcc. Multiple __asm__ statements are
272 * insufficient for xt-xcc because subsequent optimization passes
273 * (beyond the front-end that knows of __asm__ statements and other
274 * such GNU Extensions to C) can modify the register selection for
275 * containment of C variables.
276 *
277 * xt-xcc cannot modify the contents of a single __asm__ statement, so
278 * we create single-asm versions of the syscall macros that are
279 * suitable and optimal for both xt-xcc and gcc.
280 *
281 * Linux takes system-call arguments in registers. The following
282 * design is optimized for user-land apps (e.g., glibc) which
283 * typically have a function wrapper around the "syscall" assembly
284 * instruction. It satisfies the Xtensa ABI while minizing argument
285 * shifting.
286 *
287 * The Xtensa ABI and software conventions require the system-call
288 * number in a2. If an argument exists in a2, we move it to the next
289 * available register. Note that for improved efficiency, we do NOT
290 * shift all parameters down one register to maintain the original
291 * order.
292 *
293 * At best case (zero arguments), we just write the syscall number to
294 * a2. At worst case (1 to 6 arguments), we move the argument in a2
295 * to the next available register, then write the syscall number to
296 * a2.
297 *
298 * For clarity, the following truth table enumerates all possibilities.
299 *
300 * arguments syscall number arg0, arg1, arg2, arg3, arg4, arg5
301 * --------- -------------- ----------------------------------
302 * 0 a2
303 * 1 a2 a3
304 * 2 a2 a4, a3
305 * 3 a2 a5, a3, a4
306 * 4 a2 a6, a3, a4, a5
307 * 5 a2 a7, a3, a4, a5, a6
308 * 6 a2 a8, a3, a4, a5, a6, a7
309 */
310
311#define _syscall0(type,name) \
312type name(void) \
313{ \
314long __res; \
315__asm__ __volatile__ ( \
316 " movi a2, %1 \n" \
317 " syscall \n" \
318 " mov %0, a2 \n" \
319 : "=a" (__res) \
320 : "i" (__NR_##name) \
321 : "a2" \
322 ); \
323__syscall_return(type,__res); \
324}
325
326#define _syscall1(type,name,type0,arg0) \
327type name(type0 arg0) \
328{ \
329long __res; \
330__asm__ __volatile__ ( \
331 " mov a3, %2 \n" \
332 " movi a2, %1 \n" \
333 " syscall \n" \
334 " mov %0, a2 \n" \
335 : "=a" (__res) \
336 : "i" (__NR_##name), "a" (arg0) \
337 : "a2", "a3" \
338 ); \
339__syscall_return(type,__res); \
340}
341
342#define _syscall2(type,name,type0,arg0,type1,arg1) \
343type name(type0 arg0,type1 arg1) \
344{ \
345long __res; \
346__asm__ __volatile__ ( \
347 " mov a4, %2 \n" \
348 " mov a3, %3 \n" \
349 " movi a2, %1 \n" \
350 " syscall \n" \
351 " mov %0, a2 \n" \
352 : "=a" (__res) \
353 : "i" (__NR_##name), "a" (arg0), "a" (arg1) \
354 : "a2", "a3", "a4" \
355 ); \
356__syscall_return(type,__res); \
357}
358
359#define _syscall3(type,name,type0,arg0,type1,arg1,type2,arg2) \
360type name(type0 arg0,type1 arg1,type2 arg2) \
361{ \
362long __res; \
363__asm__ __volatile__ ( \
364 " mov a5, %2 \n" \
365 " mov a4, %4 \n" \
366 " mov a3, %3 \n" \
367 " movi a2, %1 \n" \
368 " syscall \n" \
369 " mov %0, a2 \n" \
370 : "=a" (__res) \
371 : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2) \
372 : "a2", "a3", "a4", "a5" \
373 ); \
374__syscall_return(type,__res); \
375}
376
377#define _syscall4(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3) \
378type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3) \
379{ \
380long __res; \
381__asm__ __volatile__ ( \
382 " mov a6, %2 \n" \
383 " mov a5, %5 \n" \
384 " mov a4, %4 \n" \
385 " mov a3, %3 \n" \
386 " movi a2, %1 \n" \
387 " syscall \n" \
388 " mov %0, a2 \n" \
389 : "=a" (__res) \
390 : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), "a" (arg3) \
391 : "a2", "a3", "a4", "a5", "a6" \
392 ); \
393__syscall_return(type,__res); \
394}
395
396/* Note that we save and restore the a7 frame pointer.
397 * Including a7 in the clobber list doesn't do what you'd expect.
398 */
399#define _syscall5(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
400type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
401{ \
402long __res; \
403__asm__ __volatile__ ( \
404 " mov a9, a7 \n" \
405 " mov a7, %2 \n" \
406 " mov a6, %6 \n" \
407 " mov a5, %5 \n" \
408 " mov a4, %4 \n" \
409 " mov a3, %3 \n" \
410 " movi a2, %1 \n" \
411 " syscall \n" \
412 " mov a7, a9 \n" \
413 " mov %0, a2 \n" \
414 : "=a" (__res) \
415 : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \
416 "a" (arg3), "a" (arg4) \
417 : "a2", "a3", "a4", "a5", "a6", "a9" \
418 ); \
419__syscall_return(type,__res); \
420}
421
422/* Note that we save and restore the a7 frame pointer.
423 * Including a7 in the clobber list doesn't do what you'd expect.
424 */
425#define _syscall6(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
426type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
427{ \
428long __res; \
429__asm__ __volatile__ ( \
430 " mov a9, a7 \n" \
431 " mov a8, %2 \n" \
432 " mov a7, %7 \n" \
433 " mov a6, %6 \n" \
434 " mov a5, %5 \n" \
435 " mov a4, %4 \n" \
436 " mov a3, %3 \n" \
437 " movi a2, %1 \n" \
438 " syscall \n" \
439 " mov a7, a9 \n" \
440 " mov %0, a2 \n" \
441 : "=a" (__res) \
442 : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \
443 "a" (arg3), "a" (arg4), "a" (arg5) \
444 : "a2", "a3", "a4", "a5", "a6", "a8", "a9" \
445 ); \
446__syscall_return(type,__res); \
447}
448
449
450#ifdef __KERNEL_SYSCALLS__
451
452#include <linux/compiler.h>
453#include <linux/types.h>
454#include <linux/syscalls.h>
455
456/*
457 * we need this inline - forking from kernel space will result
458 * in NO COPY ON WRITE (!!!), until an execve is executed. This
459 * is no problem, but for the stack. This is handled by not letting
460 * main() use the stack at all after fork(). Thus, no function
461 * calls - which means inline code for fork too, as otherwise we
462 * would use the stack upon exit from 'fork()'.
463 *
464 * Actually only pause and fork are needed inline, so that there
465 * won't be any messing with the stack from main(), but we define
466 * some others too.
467 */
468
469#define __NR__exit __NR_exit
470
471static __inline__ _syscall0(int,pause)
472//static __inline__ _syscall1(int,setup,int,magic) FIXME
473static __inline__ _syscall0(int,sync)
474static __inline__ _syscall0(pid_t,setsid)
475static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count)
476static __inline__ _syscall3(int,read,int,fd,char *,buf,off_t,count)
477static __inline__ _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
478static __inline__ _syscall1(int,dup,int,fd)
479static __inline__ _syscall3(int,execve,const char*,file,char**,argv,char**,envp)
480static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode)
481static __inline__ _syscall1(int,close,int,fd)
482static __inline__ _syscall1(int,_exit,int,exitcode)
483static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
484static __inline__ _syscall1(int,delete_module,const char *,name)
485
486struct stat;
487static __inline__ _syscall2(int,fstat,int,fd,struct stat *,buf)
488static __inline__ _syscall0(pid_t,getpid)
489static __inline__ _syscall2(int,kill,int,pid,int,sig)
490static __inline__ _syscall2(int,stat,const char *, path,struct stat *,buf)
491static __inline__ _syscall1(int,unlink,char *,pathname)
492
493
494
495extern pid_t waitpid(int, int*, int );
496static __inline__ pid_t wait(int * wait_stat)
497{
498 return waitpid(-1,wait_stat,0);
499}
500#endif
501
502/*
503 * "Conditional" syscalls
504 *
505 * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
506 * but it doesn't work on all toolchains, so we just do it by hand
507 */
508#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
509
510#ifdef __KERNEL__
511#define __ARCH_WANT_IPC_PARSE_VERSION
512#define __ARCH_WANT_OLD_READDIR
513#define __ARCH_WANT_OLD_STAT
514#define __ARCH_WANT_STAT64
515#define __ARCH_WANT_SYS_ALARM
516#define __ARCH_WANT_SYS_GETHOSTNAME
517#define __ARCH_WANT_SYS_PAUSE
518#define __ARCH_WANT_SYS_SGETMASK
519#define __ARCH_WANT_SYS_SIGNAL
520#define __ARCH_WANT_SYS_TIME
521#define __ARCH_WANT_SYS_UTIME
522#define __ARCH_WANT_SYS_WAITPID
523#define __ARCH_WANT_SYS_SOCKETCALL
524#define __ARCH_WANT_SYS_FADVISE64
525#define __ARCH_WANT_SYS_GETPGRP
526#define __ARCH_WANT_SYS_LLSEEK
527#define __ARCH_WANT_SYS_NICE
528#define __ARCH_WANT_SYS_OLD_GETRLIMIT
529#define __ARCH_WANT_SYS_OLDUMOUNT
530#define __ARCH_WANT_SYS_SIGPENDING
531#define __ARCH_WANT_SYS_SIGPROCMASK
532#define __ARCH_WANT_SYS_RT_SIGACTION
533#endif
534
535
536
537#endif /* _XTENSA_UNISTD_H */
diff --git a/include/asm-xtensa/user.h b/include/asm-xtensa/user.h
new file mode 100644
index 000000000000..2c3ed23354a8
--- /dev/null
+++ b/include/asm-xtensa/user.h
@@ -0,0 +1,20 @@
1/*
2 * include/asm-xtensa/user.h
3 *
4 * Xtensa Processor version.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_USER_H
14#define _XTENSA_USER_H
15
16/* This file usually defines a 'struct user' structure. However, it it only
17 * used for a.out file, which are not supported on Xtensa.
18 */
19
20#endif /* _XTENSA_USER_H */
diff --git a/include/asm-xtensa/vga.h b/include/asm-xtensa/vga.h
new file mode 100644
index 000000000000..23d82f6acb57
--- /dev/null
+++ b/include/asm-xtensa/vga.h
@@ -0,0 +1,19 @@
1/*
2 * include/asm-xtensa/vga.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_VGA_H
12#define _XTENSA_VGA_H
13
14#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x)
15
16#define vga_readb(x) (*(x))
17#define vga_writeb(x,y) (*(y) = (x))
18
19#endif
diff --git a/include/asm-xtensa/xor.h b/include/asm-xtensa/xor.h
new file mode 100644
index 000000000000..e7b1f083991d
--- /dev/null
+++ b/include/asm-xtensa/xor.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-xtensa/xor.h
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_XOR_H
12#define _XTENSA_XOR_H
13
14#include <asm-generic/xor.h>
15
16#endif
diff --git a/include/asm-xtensa/xtensa/cacheasm.h b/include/asm-xtensa/xtensa/cacheasm.h
new file mode 100644
index 000000000000..0cdbb0bf180e
--- /dev/null
+++ b/include/asm-xtensa/xtensa/cacheasm.h
@@ -0,0 +1,708 @@
1#ifndef XTENSA_CACHEASM_H
2#define XTENSA_CACHEASM_H
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * include/asm-xtensa/xtensa/cacheasm.h -- assembler-specific cache
8 * related definitions that depend on CORE configuration.
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 *
14 * Copyright (C) 2002 Tensilica Inc.
15 */
16
17
18#include <xtensa/coreasm.h>
19
20
21/*
22 * This header file defines assembler macros of the form:
23 * <x>cache_<func>
24 * where <x> is 'i' or 'd' for instruction and data caches,
25 * and <func> indicates the function of the macro.
26 *
27 * The following functions <func> are defined,
28 * and apply only to the specified cache (I or D):
29 *
30 * reset
31 * Resets the cache.
32 *
33 * sync
34 * Makes sure any previous cache instructions have been completed;
35 * ie. makes sure any previous cache control operations
36 * have had full effect and been synchronized to memory.
37 * Eg. any invalidate completed [so as not to generate a hit],
38 * any writebacks or other pipelined writes written to memory, etc.
39 *
40 * invalidate_line (single cache line)
41 * invalidate_region (specified memory range)
42 * invalidate_all (entire cache)
43 * Invalidates all cache entries that cache
44 * data from the specified memory range.
45 * NOTE: locked entries are not invalidated.
46 *
47 * writeback_line (single cache line)
48 * writeback_region (specified memory range)
49 * writeback_all (entire cache)
50 * Writes back to memory all dirty cache entries
51 * that cache data from the specified memory range,
52 * and marks these entries as clean.
53 * NOTE: on some future implementations, this might
54 * also invalidate.
55 * NOTE: locked entries are written back, but never invalidated.
56 * NOTE: instruction caches never implement writeback.
57 *
58 * writeback_inv_line (single cache line)
59 * writeback_inv_region (specified memory range)
60 * writeback_inv_all (entire cache)
61 * Writes back to memory all dirty cache entries
62 * that cache data from the specified memory range,
63 * and invalidates these entries (including all clean
64 * cache entries that cache data from that range).
65 * NOTE: locked entries are written back but not invalidated.
66 * NOTE: instruction caches never implement writeback.
67 *
68 * lock_line (single cache line)
69 * lock_region (specified memory range)
70 * Prefetch and lock the specified memory range into cache.
71 * NOTE: if any part of the specified memory range cannot
72 * be locked, a ??? exception occurs. These macros don't
73 * do anything special (yet anyway) to handle this situation.
74 *
75 * unlock_line (single cache line)
76 * unlock_region (specified memory range)
77 * unlock_all (entire cache)
78 * Unlock cache entries that cache the specified memory range.
79 * Entries not already locked are unaffected.
80 */
81
82
83
84/*************************** GENERIC -- ALL CACHES ***************************/
85
86
87/*
88 * The following macros assume the following cache size/parameter limits
89 * in the current Xtensa core implementation:
90 * cache size: 1024 bytes minimum
91 * line size: 16 - 64 bytes
92 * way count: 1 - 4
93 *
94 * Minimum entries per way (ie. per associativity) = 1024 / 64 / 4 = 4
95 * Hence the assumption that each loop can execute four cache instructions.
96 *
97 * Correspondingly, the offset range of instructions is assumed able to cover
98 * four lines, ie. offsets {0,1,2,3} * line_size are assumed valid for
99 * both hit and indexed cache instructions. Ie. these offsets are all
100 * valid: 0, 16, 32, 48, 64, 96, 128, 192 (for line sizes 16, 32, 64).
101 * This is true of all original cache instructions
102 * (dhi, ihi, dhwb, dhwbi, dii, iii) which have offsets
103 * of 0 to 1020 in multiples of 4 (ie. 8 bits shifted by 2).
104 * This is also true of subsequent cache instructions
105 * (dhu, ihu, diu, iiu, diwb, diwbi, dpfl, ipfl) which have offsets
106 * of 0 to 240 in multiples of 16 (ie. 4 bits shifted by 4).
107 *
108 * (Maximum cache size, currently 32k, doesn't affect the following macros.
109 * Cache ways > MMU min page size cause aliasing but that's another matter.)
110 */
111
112
113
114/*
115 * Macro to apply an 'indexed' cache instruction to the entire cache.
116 *
117 * Parameters:
118 * cainst instruction/ that takes an address register parameter
119 * and an offset parameter (in range 0 .. 3*linesize).
120 * size size of cache in bytes
121 * linesize size of cache line in bytes
122 * assoc_or1 number of associativities (ways/sets) in cache
123 * if all sets affected by cainst,
124 * or 1 if only one set (or not all sets) of the cache
125 * is affected by cainst (eg. DIWB or DIWBI [not yet ISA defined]).
126 * aa, ab unique address registers (temporaries)
127 */
128
129 .macro cache_index_all cainst, size, linesize, assoc_or1, aa, ab
130
131 // Sanity-check on cache parameters:
132 .ifne (\size % (\linesize * \assoc_or1 * 4))
133 .err // cache configuration outside expected/supported range!
134 .endif
135
136 // \size byte cache, \linesize byte lines, \assoc_or1 way(s) affected by each \cainst.
137 movi \aa, (\size / (\linesize * \assoc_or1 * 4))
138 // Possible improvement: need only loop if \aa > 1 ;
139 // however that particular condition is highly unlikely.
140 movi \ab, 0 // to iterate over cache
141 floop \aa, cachex\@
142 \cainst \ab, 0*\linesize
143 \cainst \ab, 1*\linesize
144 \cainst \ab, 2*\linesize
145 \cainst \ab, 3*\linesize
146 addi \ab, \ab, 4*\linesize // move to next line
147 floopend \aa, cachex\@
148
149 .endm
150
151
152/*
153 * Macro to apply a 'hit' cache instruction to a memory region,
154 * ie. to any cache entries that cache a specified portion (region) of memory.
155 * Takes care of the unaligned cases, ie. may apply to one
156 * more cache line than $asize / lineSize if $aaddr is not aligned.
157 *
158 *
159 * Parameters are:
160 * cainst instruction/macro that takes an address register parameter
161 * and an offset parameter (currently always zero)
162 * and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.)
163 * linesize_log2 log2(size of cache line in bytes)
164 * addr register containing start address of region (clobbered)
165 * asize register containing size of the region in bytes (clobbered)
166 * askew unique register used as temporary
167 *
168 * !?!?! 2DO: optimization: iterate max(cache_size and \asize) / linesize
169 */
170
171 .macro cache_hit_region cainst, linesize_log2, addr, asize, askew
172
173 // Make \asize the number of iterations:
174 extui \askew, \addr, 0, \linesize_log2 // get unalignment amount of \addr
175 add \asize, \asize, \askew // ... and add it to \asize
176 addi \asize, \asize, (1 << \linesize_log2) - 1 // round up!
177 srli \asize, \asize, \linesize_log2
178
179 // Iterate over region:
180 floopnez \asize, cacheh\@
181 \cainst \addr, 0
182 addi \addr, \addr, (1 << \linesize_log2) // move to next line
183 floopend \asize, cacheh\@
184
185 .endm
186
187
188
189
190
191/*************************** INSTRUCTION CACHE ***************************/
192
193
194/*
195 * Reset/initialize the instruction cache by simply invalidating it:
196 * (need to unlock first also, if cache locking implemented):
197 *
198 * Parameters:
199 * aa, ab unique address registers (temporaries)
200 */
201 .macro icache_reset aa, ab
202 icache_unlock_all \aa, \ab
203 icache_invalidate_all \aa, \ab
204 .endm
205
206
207/*
208 * Synchronize after an instruction cache operation,
209 * to be sure everything is in sync with memory as to be
210 * expected following any previous instruction cache control operations.
211 *
212 * Parameters are:
213 * ar an address register (temporary) (currently unused, but may be used in future)
214 */
215 .macro icache_sync ar
216#if XCHAL_ICACHE_SIZE > 0
217 isync
218#endif
219 .endm
220
221
222
223/*
224 * Invalidate a single line of the instruction cache.
225 * Parameters are:
226 * ar address register that contains (virtual) address to invalidate
227 * (may get clobbered in a future implementation, but not currently)
228 * offset (optional) offset to add to \ar to compute effective address to invalidate
229 * (note: some number of lsbits are ignored)
230 */
231 .macro icache_invalidate_line ar, offset
232#if XCHAL_ICACHE_SIZE > 0
233 ihi \ar, \offset // invalidate icache line
234 /*
235 * NOTE: in some version of the silicon [!!!SHOULD HAVE BEEN DOCUMENTED!!!]
236 * 'ihi' doesn't work, so it had been replaced with 'iii'
237 * (which would just invalidate more than it should,
238 * which should be okay other than the performance hit
239 * because cache locking did not exist in that version,
240 * unless user somehow relies on something being cached).
241 * [WHAT VERSION IS IT!!?!?
242 * IS THERE ANY WAY TO TEST FOR THAT HERE, TO OUTPUT 'III' ONLY IF NEEDED!?!?].
243 *
244 * iii \ar, \offset
245 */
246 icache_sync \ar
247#endif
248 .endm
249
250
251
252
253/*
254 * Invalidate instruction cache entries that cache a specified portion of memory.
255 * Parameters are:
256 * astart start address (register gets clobbered)
257 * asize size of the region in bytes (register gets clobbered)
258 * ac unique register used as temporary
259 */
260 .macro icache_invalidate_region astart, asize, ac
261#if XCHAL_ICACHE_SIZE > 0
262 // Instruction cache region invalidation:
263 cache_hit_region ihi, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
264 icache_sync \ac
265 // End of instruction cache region invalidation
266#endif
267 .endm
268
269
270
271/*
272 * Invalidate entire instruction cache.
273 *
274 * Parameters:
275 * aa, ab unique address registers (temporaries)
276 */
277 .macro icache_invalidate_all aa, ab
278#if XCHAL_ICACHE_SIZE > 0
279 // Instruction cache invalidation:
280 cache_index_all iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, XCHAL_ICACHE_WAYS, \aa, \ab
281 icache_sync \aa
282 // End of instruction cache invalidation
283#endif
284 .endm
285
286
287
288/*
289 * Lock (prefetch & lock) a single line of the instruction cache.
290 *
291 * Parameters are:
292 * ar address register that contains (virtual) address to lock
293 * (may get clobbered in a future implementation, but not currently)
294 * offset offset to add to \ar to compute effective address to lock
295 * (note: some number of lsbits are ignored)
296 */
297 .macro icache_lock_line ar, offset
298#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
299 ipfl \ar, \offset /* prefetch and lock icache line */
300 icache_sync \ar
301#endif
302 .endm
303
304
305
306/*
307 * Lock (prefetch & lock) a specified portion of memory into the instruction cache.
308 * Parameters are:
309 * astart start address (register gets clobbered)
310 * asize size of the region in bytes (register gets clobbered)
311 * ac unique register used as temporary
312 */
313 .macro icache_lock_region astart, asize, ac
314#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
315 // Instruction cache region lock:
316 cache_hit_region ipfl, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
317 icache_sync \ac
318 // End of instruction cache region lock
319#endif
320 .endm
321
322
323
324/*
325 * Unlock a single line of the instruction cache.
326 *
327 * Parameters are:
328 * ar address register that contains (virtual) address to unlock
329 * (may get clobbered in a future implementation, but not currently)
330 * offset offset to add to \ar to compute effective address to unlock
331 * (note: some number of lsbits are ignored)
332 */
333 .macro icache_unlock_line ar, offset
334#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
335 ihu \ar, \offset /* unlock icache line */
336 icache_sync \ar
337#endif
338 .endm
339
340
341
342/*
343 * Unlock a specified portion of memory from the instruction cache.
344 * Parameters are:
345 * astart start address (register gets clobbered)
346 * asize size of the region in bytes (register gets clobbered)
347 * ac unique register used as temporary
348 */
349 .macro icache_unlock_region astart, asize, ac
350#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
351 // Instruction cache region unlock:
352 cache_hit_region ihu, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
353 icache_sync \ac
354 // End of instruction cache region unlock
355#endif
356 .endm
357
358
359
360/*
361 * Unlock entire instruction cache.
362 *
363 * Parameters:
364 * aa, ab unique address registers (temporaries)
365 */
366 .macro icache_unlock_all aa, ab
367#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
368 // Instruction cache unlock:
369 cache_index_all iiu, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, 1, \aa, \ab
370 icache_sync \aa
371 // End of instruction cache unlock
372#endif
373 .endm
374
375
376
377
378
379/*************************** DATA CACHE ***************************/
380
381
382
383/*
384 * Reset/initialize the data cache by simply invalidating it
385 * (need to unlock first also, if cache locking implemented):
386 *
387 * Parameters:
388 * aa, ab unique address registers (temporaries)
389 */
390 .macro dcache_reset aa, ab
391 dcache_unlock_all \aa, \ab
392 dcache_invalidate_all \aa, \ab
393 .endm
394
395
396
397
398/*
399 * Synchronize after a data cache operation,
400 * to be sure everything is in sync with memory as to be
401 * expected following any previous data cache control operations.
402 *
403 * Parameters are:
404 * ar an address register (temporary) (currently unused, but may be used in future)
405 */
406 .macro dcache_sync ar
407#if XCHAL_DCACHE_SIZE > 0
408 // This previous sequence errs on the conservative side (too much so); a DSYNC should be sufficient:
409 //memw // synchronize data cache changes relative to subsequent memory accesses
410 //isync // be conservative and ISYNC as well (just to be sure)
411
412 dsync
413#endif
414 .endm
415
416
417
418/*
419 * Synchronize after a data store operation,
420 * to be sure the stored data is completely off the processor
421 * (and assuming there is no buffering outside the processor,
422 * that the data is in memory). This may be required to
423 * ensure that the processor's write buffers are emptied.
424 * A MEMW followed by a read guarantees this, by definition.
425 * We also try to make sure the read itself completes.
426 *
427 * Parameters are:
428 * ar an address register (temporary)
429 */
430 .macro write_sync ar
431 memw // ensure previous memory accesses are complete prior to subsequent memory accesses
432 l32i \ar, sp, 0 // completing this read ensures any previous write has completed, because of MEMW
433 //slot
434 add \ar, \ar, \ar // use the result of the read to help ensure the read completes (in future architectures)
435 .endm
436
437
438/*
439 * Invalidate a single line of the data cache.
440 * Parameters are:
441 * ar address register that contains (virtual) address to invalidate
442 * (may get clobbered in a future implementation, but not currently)
443 * offset (optional) offset to add to \ar to compute effective address to invalidate
444 * (note: some number of lsbits are ignored)
445 */
446 .macro dcache_invalidate_line ar, offset
447#if XCHAL_DCACHE_SIZE > 0
448 dhi \ar, \offset
449 dcache_sync \ar
450#endif
451 .endm
452
453
454
455
456
457/*
458 * Invalidate data cache entries that cache a specified portion of memory.
459 * Parameters are:
460 * astart start address (register gets clobbered)
461 * asize size of the region in bytes (register gets clobbered)
462 * ac unique register used as temporary
463 */
464 .macro dcache_invalidate_region astart, asize, ac
465#if XCHAL_DCACHE_SIZE > 0
466 // Data cache region invalidation:
467 cache_hit_region dhi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
468 dcache_sync \ac
469 // End of data cache region invalidation
470#endif
471 .endm
472
473
474
475#if 0
476/*
477 * This is a work-around for a bug in SiChip1 (???).
478 * There should be a proper mechanism for not outputting
479 * these instructions when not needed.
480 * To enable work-around, uncomment this and replace 'dii'
481 * with 'dii_s1' everywhere, eg. in dcache_invalidate_all
482 * macro below.
483 */
484 .macro dii_s1 ar, offset
485 dii \ar, \offset
486 or \ar, \ar, \ar
487 or \ar, \ar, \ar
488 or \ar, \ar, \ar
489 or \ar, \ar, \ar
490 .endm
491#endif
492
493
494/*
495 * Invalidate entire data cache.
496 *
497 * Parameters:
498 * aa, ab unique address registers (temporaries)
499 */
500 .macro dcache_invalidate_all aa, ab
501#if XCHAL_DCACHE_SIZE > 0
502 // Data cache invalidation:
503 cache_index_all dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, XCHAL_DCACHE_WAYS, \aa, \ab
504 dcache_sync \aa
505 // End of data cache invalidation
506#endif
507 .endm
508
509
510
511/*
512 * Writeback a single line of the data cache.
513 * Parameters are:
514 * ar address register that contains (virtual) address to writeback
515 * (may get clobbered in a future implementation, but not currently)
516 * offset offset to add to \ar to compute effective address to writeback
517 * (note: some number of lsbits are ignored)
518 */
519 .macro dcache_writeback_line ar, offset
520#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
521 dhwb \ar, \offset
522 dcache_sync \ar
523#endif
524 .endm
525
526
527
528/*
529 * Writeback dirty data cache entries that cache a specified portion of memory.
530 * Parameters are:
531 * astart start address (register gets clobbered)
532 * asize size of the region in bytes (register gets clobbered)
533 * ac unique register used as temporary
534 */
535 .macro dcache_writeback_region astart, asize, ac
536#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
537 // Data cache region writeback:
538 cache_hit_region dhwb, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
539 dcache_sync \ac
540 // End of data cache region writeback
541#endif
542 .endm
543
544
545
546/*
547 * Writeback entire data cache.
548 * Parameters:
549 * aa, ab unique address registers (temporaries)
550 */
551 .macro dcache_writeback_all aa, ab
552#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
553 // Data cache writeback:
554 cache_index_all diwb, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab
555 dcache_sync \aa
556 // End of data cache writeback
557#endif
558 .endm
559
560
561
562/*
563 * Writeback and invalidate a single line of the data cache.
564 * Parameters are:
565 * ar address register that contains (virtual) address to writeback and invalidate
566 * (may get clobbered in a future implementation, but not currently)
567 * offset offset to add to \ar to compute effective address to writeback and invalidate
568 * (note: some number of lsbits are ignored)
569 */
570 .macro dcache_writeback_inv_line ar, offset
571#if XCHAL_DCACHE_SIZE > 0
572 dhwbi \ar, \offset /* writeback and invalidate dcache line */
573 dcache_sync \ar
574#endif
575 .endm
576
577
578
579/*
580 * Writeback and invalidate data cache entries that cache a specified portion of memory.
581 * Parameters are:
582 * astart start address (register gets clobbered)
583 * asize size of the region in bytes (register gets clobbered)
584 * ac unique register used as temporary
585 */
586 .macro dcache_writeback_inv_region astart, asize, ac
587#if XCHAL_DCACHE_SIZE > 0
588 // Data cache region writeback and invalidate:
589 cache_hit_region dhwbi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
590 dcache_sync \ac
591 // End of data cache region writeback and invalidate
592#endif
593 .endm
594
595
596
597/*
598 * Writeback and invalidate entire data cache.
599 * Parameters:
600 * aa, ab unique address registers (temporaries)
601 */
602 .macro dcache_writeback_inv_all aa, ab
603#if XCHAL_DCACHE_SIZE > 0
604 // Data cache writeback and invalidate:
605#if XCHAL_DCACHE_IS_WRITEBACK
606 cache_index_all diwbi, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab
607 dcache_sync \aa
608#else /*writeback*/
609 // Data cache does not support writeback, so just invalidate: */
610 dcache_invalidate_all \aa, \ab
611#endif /*writeback*/
612 // End of data cache writeback and invalidate
613#endif
614 .endm
615
616
617
618
619/*
620 * Lock (prefetch & lock) a single line of the data cache.
621 *
622 * Parameters are:
623 * ar address register that contains (virtual) address to lock
624 * (may get clobbered in a future implementation, but not currently)
625 * offset offset to add to \ar to compute effective address to lock
626 * (note: some number of lsbits are ignored)
627 */
628 .macro dcache_lock_line ar, offset
629#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
630 dpfl \ar, \offset /* prefetch and lock dcache line */
631 dcache_sync \ar
632#endif
633 .endm
634
635
636
637/*
638 * Lock (prefetch & lock) a specified portion of memory into the data cache.
639 * Parameters are:
640 * astart start address (register gets clobbered)
641 * asize size of the region in bytes (register gets clobbered)
642 * ac unique register used as temporary
643 */
644 .macro dcache_lock_region astart, asize, ac
645#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
646 // Data cache region lock:
647 cache_hit_region dpfl, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
648 dcache_sync \ac
649 // End of data cache region lock
650#endif
651 .endm
652
653
654
655/*
656 * Unlock a single line of the data cache.
657 *
658 * Parameters are:
659 * ar address register that contains (virtual) address to unlock
660 * (may get clobbered in a future implementation, but not currently)
661 * offset offset to add to \ar to compute effective address to unlock
662 * (note: some number of lsbits are ignored)
663 */
664 .macro dcache_unlock_line ar, offset
665#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
666 dhu \ar, \offset /* unlock dcache line */
667 dcache_sync \ar
668#endif
669 .endm
670
671
672
673/*
674 * Unlock a specified portion of memory from the data cache.
675 * Parameters are:
676 * astart start address (register gets clobbered)
677 * asize size of the region in bytes (register gets clobbered)
678 * ac unique register used as temporary
679 */
680 .macro dcache_unlock_region astart, asize, ac
681#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
682 // Data cache region unlock:
683 cache_hit_region dhu, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
684 dcache_sync \ac
685 // End of data cache region unlock
686#endif
687 .endm
688
689
690
691/*
692 * Unlock entire data cache.
693 *
694 * Parameters:
695 * aa, ab unique address registers (temporaries)
696 */
697 .macro dcache_unlock_all aa, ab
698#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
699 // Data cache unlock:
700 cache_index_all diu, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab
701 dcache_sync \aa
702 // End of data cache unlock
703#endif
704 .endm
705
706
707#endif /*XTENSA_CACHEASM_H*/
708
diff --git a/include/asm-xtensa/xtensa/cacheattrasm.h b/include/asm-xtensa/xtensa/cacheattrasm.h
new file mode 100644
index 000000000000..1c3e117b3592
--- /dev/null
+++ b/include/asm-xtensa/xtensa/cacheattrasm.h
@@ -0,0 +1,432 @@
1#ifndef XTENSA_CACHEATTRASM_H
2#define XTENSA_CACHEATTRASM_H
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * include/asm-xtensa/xtensa/cacheattrasm.h -- assembler-specific
8 * CACHEATTR register related definitions that depend on CORE
9 * configuration.
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 *
15 * Copyright (C) 2002 Tensilica Inc.
16 */
17
18
19#include <xtensa/coreasm.h>
20
21
22/*
23 * This header file defines assembler macros of the form:
24 * <x>cacheattr_<func>
25 * where:
26 * <x> is 'i', 'd' or absent for instruction, data
27 * or both caches; and
28 * <func> indicates the function of the macro.
29 *
30 * The following functions are defined:
31 *
32 * icacheattr_get
33 * Reads I-cache CACHEATTR into a2 (clobbers a3-a5).
34 *
35 * dcacheattr_get
36 * Reads D-cache CACHEATTR into a2 (clobbers a3-a5).
37 * (Note: for configs with a real CACHEATTR register, the
38 * above two macros are identical.)
39 *
40 * cacheattr_set
41 * Writes both I-cache and D-cache CACHEATTRs from a2 (a3-a8 clobbered).
42 * Works even when changing one's own code's attributes.
43 *
44 * icacheattr_is_enabled label
45 * Branches to \label if I-cache appears to have been enabled
46 * (eg. if CACHEATTR contains a cache-enabled attribute).
47 * (clobbers a2-a5,SAR)
48 *
49 * dcacheattr_is_enabled label
50 * Branches to \label if D-cache appears to have been enabled
51 * (eg. if CACHEATTR contains a cache-enabled attribute).
52 * (clobbers a2-a5,SAR)
53 *
54 * cacheattr_is_enabled label
55 * Branches to \label if either I-cache or D-cache appears to have been enabled
56 * (eg. if CACHEATTR contains a cache-enabled attribute).
57 * (clobbers a2-a5,SAR)
58 *
59 * The following macros are only defined under certain conditions:
60 *
61 * icacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR)
62 * Writes I-cache CACHEATTR from a2 (a3-a8 clobbered).
63 *
64 * dcacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR)
65 * Writes D-cache CACHEATTR from a2 (a3-a8 clobbered).
66 */
67
68
69
70/*************************** GENERIC -- ALL CACHES ***************************/
71
72/*
73 * _cacheattr_get
74 *
75 * (Internal macro.)
76 * Returns value of CACHEATTR register (or closest equivalent) in a2.
77 *
78 * Entry:
79 * (none)
80 * Exit:
81 * a2 value read from CACHEATTR
82 * a3-a5 clobbered (temporaries)
83 */
84 .macro _cacheattr_get tlb
85#if XCHAL_HAVE_CACHEATTR
86 rsr a2, CACHEATTR
87#elif XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
88 // We have a config that "mimics" CACHEATTR using a simplified
89 // "MMU" composed of a single statically-mapped way.
90 // DTLB and ITLB are independent, so there's no single
91 // cache attribute that can describe both. So for now
92 // just return the DTLB state.
93 movi a5, 0xE0000000
94 movi a2, 0
95 movi a3, 0
961: add a3, a3, a5 // next segment
97 r&tlb&1 a4, a3 // get PPN+CA of segment at 0xE0000000, 0xC0000000, ..., 0
98 dsync // interlock???
99 slli a2, a2, 4
100 extui a4, a4, 0, 4 // extract CA
101 or a2, a2, a4
102 bnez a3, 1b
103#else
104 // This macro isn't applicable to arbitrary MMU configurations.
105 // Just return zero.
106 movi a2, 0
107#endif
108 .endm
109
110 .macro icacheattr_get
111 _cacheattr_get itlb
112 .endm
113
114 .macro dcacheattr_get
115 _cacheattr_get dtlb
116 .endm
117
118
119#define XCHAL_CACHEATTR_ALL_BYPASS 0x22222222 /* default (powerup/reset) value of CACHEATTR, all BYPASS
120 mode (ie. disabled/bypassed caches) */
121
122#if XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
123
124#define XCHAL_FCA_ENAMASK 0x001A /* bitmap of fetch attributes that require enabled icache */
125#define XCHAL_LCA_ENAMASK 0x0003 /* bitmap of load attributes that require enabled dcache */
126#define XCHAL_SCA_ENAMASK 0x0003 /* bitmap of store attributes that require enabled dcache */
127#define XCHAL_LSCA_ENAMASK (XCHAL_LCA_ENAMASK|XCHAL_SCA_ENAMASK) /* l/s attrs requiring enabled dcache */
128#define XCHAL_ALLCA_ENAMASK (XCHAL_FCA_ENAMASK|XCHAL_LSCA_ENAMASK) /* all attrs requiring enabled caches */
129
130/*
131 * _cacheattr_is_enabled
132 *
133 * (Internal macro.)
134 * Branches to \label if CACHEATTR in a2 indicates an enabled
135 * cache, using mask in a3.
136 *
137 * Parameters:
138 * label where to branch to if cache is enabled
139 * Entry:
140 * a2 contains CACHEATTR value used to determine whether
141 * caches are enabled
142 * a3 16-bit constant where each bit correspond to
143 * one of the 16 possible CA values (in a CACHEATTR mask);
144 * CA values that indicate the cache is enabled
145 * have their corresponding bit set in this mask
146 * (eg. use XCHAL_xCA_ENAMASK , above)
147 * Exit:
148 * a2,a4,a5 clobbered
149 * SAR clobbered
150 */
151 .macro _cacheattr_is_enabled label
152 movi a4, 8 // loop 8 times
153.Lcaife\@:
154 extui a5, a2, 0, 4 // get CA nibble
155 ssr a5 // index into mask according to CA...
156 srl a5, a3 // ...and get CA's mask bit in a5 bit 0
157 bbsi.l a5, 0, \label // if CA indicates cache enabled, jump to label
158 srli a2, a2, 4 // next nibble
159 addi a4, a4, -1
160 bnez a4, .Lcaife\@ // loop for each nibble
161 .endm
162
163#else /* XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR */
164 .macro _cacheattr_is_enabled label
165 j \label // macro not applicable, assume caches always enabled
166 .endm
167#endif /* XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR */
168
169
170
171/*
172 * icacheattr_is_enabled
173 *
174 * Branches to \label if I-cache is enabled.
175 *
176 * Parameters:
177 * label where to branch to if icache is enabled
178 * Entry:
179 * (none)
180 * Exit:
181 * a2-a5, SAR clobbered (temporaries)
182 */
183 .macro icacheattr_is_enabled label
184#if XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
185 icacheattr_get
186 movi a3, XCHAL_FCA_ENAMASK
187#endif
188 _cacheattr_is_enabled \label
189 .endm
190
191/*
192 * dcacheattr_is_enabled
193 *
194 * Branches to \label if D-cache is enabled.
195 *
196 * Parameters:
197 * label where to branch to if dcache is enabled
198 * Entry:
199 * (none)
200 * Exit:
201 * a2-a5, SAR clobbered (temporaries)
202 */
203 .macro dcacheattr_is_enabled label
204#if XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
205 dcacheattr_get
206 movi a3, XCHAL_LSCA_ENAMASK
207#endif
208 _cacheattr_is_enabled \label
209 .endm
210
211/*
212 * cacheattr_is_enabled
213 *
214 * Branches to \label if either I-cache or D-cache is enabled.
215 *
216 * Parameters:
217 * label where to branch to if a cache is enabled
218 * Entry:
219 * (none)
220 * Exit:
221 * a2-a5, SAR clobbered (temporaries)
222 */
223 .macro cacheattr_is_enabled label
224#if XCHAL_HAVE_CACHEATTR
225 rsr a2, CACHEATTR
226 movi a3, XCHAL_ALLCA_ENAMASK
227#elif XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
228 icacheattr_get
229 movi a3, XCHAL_FCA_ENAMASK
230 _cacheattr_is_enabled \label
231 dcacheattr_get
232 movi a3, XCHAL_LSCA_ENAMASK
233#endif
234 _cacheattr_is_enabled \label
235 .endm
236
237
238
239/*
240 * The ISA does not have a defined way to change the
241 * instruction cache attributes of the running code,
242 * ie. of the memory area that encloses the current PC.
243 * However, each micro-architecture (or class of
244 * configurations within a micro-architecture)
245 * provides a way to deal with this issue.
246 *
247 * Here are a few macros used to implement the relevant
248 * approach taken.
249 */
250
251#if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
252 // We have a config that "mimics" CACHEATTR using a simplified
253 // "MMU" composed of a single statically-mapped way.
254
255/*
256 * icacheattr_set
257 *
258 * Entry:
259 * a2 cacheattr value to set
260 * Exit:
261 * a2 unchanged
262 * a3-a8 clobbered (temporaries)
263 */
264 .macro icacheattr_set
265
266 movi a5, 0xE0000000 // mask of upper 3 bits
267 movi a6, 3f // PC where ITLB is set
268 movi a3, 0 // start at region 0 (0 .. 7)
269 and a6, a6, a5 // upper 3 bits of local PC area
270 mov a7, a2 // copy a2 so it doesn't get clobbered
271 j 3f
272
273# if XCHAL_HAVE_XLT_CACHEATTR
274 // Can do translations, use generic method:
2751: sub a6, a3, a5 // address of some other segment
276 ritlb1 a8, a6 // save its PPN+CA
277 dsync // interlock??
278 witlb a4, a6 // make it translate to this code area
279 movi a6, 5f // where to jump into it
280 isync
281 sub a6, a6, a5 // adjust jump address within that other segment
282 jx a6
283
284 // Note that in the following code snippet, which runs at a different virtual
285 // address than it is assembled for, we avoid using literals (eg. via movi/l32r)
286 // just in case literals end up in a different 512 MB segment, and we avoid
287 // instructions that rely on the current PC being what is expected.
288 //
289 .align 4
290 _j 6f // this is at label '5' minus 4 bytes
291 .align 4
2925: witlb a4, a3 // we're in other segment, now can write previous segment's CA
293 isync
294 add a6, a6, a5 // back to previous segment
295 addi a6, a6, -4 // next jump label
296 jx a6
297
2986: sub a6, a3, a5 // address of some other segment
299 witlb a8, a6 // restore PPN+CA of other segment
300 mov a6, a3 // restore a6
301 isync
302# else /* XCHAL_HAVE_XLT_CACHEATTR */
303 // Use micro-architecture specific method.
304 // The following 4-instruction sequence is aligned such that
305 // it all fits within a single I-cache line. Sixteen byte
306 // alignment is sufficient for this (using XCHAL_ICACHE_LINESIZE
307 // actually causes problems because that can be greater than
308 // the alignment of the reset vector, where this macro is often
309 // invoked, which would cause the linker to align the reset
310 // vector code away from the reset vector!!).
311 .align 16 /*XCHAL_ICACHE_LINESIZE*/
3121: _witlb a4, a3 // write wired PTE (CA, no PPN) of 512MB segment to ITLB
313 _isync
314 nop
315 nop
316# endif /* XCHAL_HAVE_XLT_CACHEATTR */
317 beq a3, a5, 4f // done?
318
319 // Note that in the WITLB loop, we don't do any load/stores
320 // (may not be an issue here, but it is important in the DTLB case).
3212: srli a7, a7, 4 // next CA
322 sub a3, a3, a5 // next segment (add 0x20000000)
3233:
324# if XCHAL_HAVE_XLT_CACHEATTR /* if have translation, preserve it */
325 ritlb1 a8, a3 // get current PPN+CA of segment
326 dsync // interlock???
327 extui a4, a7, 0, 4 // extract CA to set
328 srli a8, a8, 4 // clear CA but keep PPN ...
329 slli a8, a8, 4 // ...
330 add a4, a4, a8 // combine new CA with PPN to preserve
331# else
332 extui a4, a7, 0, 4 // extract CA
333# endif
334 beq a3, a6, 1b // current PC's region? if so, do it in a safe way
335 witlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to ITLB
336 bne a3, a5, 2b
337 isync // make sure all ifetch changes take effect
3384:
339 .endm // icacheattr_set
340
341
342/*
343 * dcacheattr_set
344 *
345 * Entry:
346 * a2 cacheattr value to set
347 * Exit:
348 * a2 unchanged
349 * a3-a8 clobbered (temporaries)
350 */
351
352 .macro dcacheattr_set
353
354 movi a5, 0xE0000000 // mask of upper 3 bits
355 movi a3, 0 // start at region 0 (0 .. 7)
356 mov a7, a2 // copy a2 so it doesn't get clobbered
357 j 3f
358 // Note that in the WDTLB loop, we don't do any load/stores
359 // (including implicit l32r via movi) because it isn't safe.
3602: srli a7, a7, 4 // next CA
361 sub a3, a3, a5 // next segment (add 0x20000000)
3623:
363# if XCHAL_HAVE_XLT_CACHEATTR /* if have translation, preserve it */
364 rdtlb1 a8, a3 // get current PPN+CA of segment
365 dsync // interlock???
366 extui a4, a7, 0, 4 // extract CA to set
367 srli a8, a8, 4 // clear CA but keep PPN ...
368 slli a8, a8, 4 // ...
369 add a4, a4, a8 // combine new CA with PPN to preserve
370# else
371 extui a4, a7, 0, 4 // extract CA to set
372# endif
373 wdtlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to DTLB
374 bne a3, a5, 2b
375 dsync // make sure all data path changes take effect
376 .endm // dcacheattr_set
377
378#endif /* XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR */
379
380
381
382/*
383 * cacheattr_set
384 *
385 * Macro that sets the current CACHEATTR safely
386 * (both i and d) according to the current contents of a2.
387 * It works even when changing the cache attributes of
388 * the currently running code.
389 *
390 * Entry:
391 * a2 cacheattr value to set
392 * Exit:
393 * a2 unchanged
394 * a3-a8 clobbered (temporaries)
395 */
396 .macro cacheattr_set
397
398#if XCHAL_HAVE_CACHEATTR
399# if XCHAL_ICACHE_LINESIZE < 4
400 // No i-cache, so can always safely write to CACHEATTR:
401 wsr a2, CACHEATTR
402# else
403 // The Athens micro-architecture, when using the old
404 // exception architecture option (ie. with the CACHEATTR register)
405 // allows changing the cache attributes of the running code
406 // using the following exact sequence aligned to be within
407 // an instruction cache line. (NOTE: using XCHAL_ICACHE_LINESIZE
408 // alignment actually causes problems because that can be greater
409 // than the alignment of the reset vector, where this macro is often
410 // invoked, which would cause the linker to align the reset
411 // vector code away from the reset vector!!).
412 j 1f
413 .align 16 /*XCHAL_ICACHE_LINESIZE*/ // align to within an I-cache line
4141: _wsr a2, CACHEATTR
415 _isync
416 nop
417 nop
418# endif
419#elif XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
420 // DTLB and ITLB are independent, but to keep semantics
421 // of this macro we simply write to both.
422 icacheattr_set
423 dcacheattr_set
424#else
425 // This macro isn't applicable to arbitrary MMU configurations.
426 // Do nothing in this case.
427#endif
428 .endm
429
430
431#endif /*XTENSA_CACHEATTRASM_H*/
432
diff --git a/include/asm-xtensa/xtensa/config-linux_be/core.h b/include/asm-xtensa/xtensa/config-linux_be/core.h
new file mode 100644
index 000000000000..d54fe5eb1064
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/core.h
@@ -0,0 +1,1270 @@
1/*
2 * xtensa/config/core.h -- HAL definitions that are dependent on CORE configuration
3 *
4 * This header file is sometimes referred to as the "compile-time HAL" or CHAL.
5 * It was generated for a specific Xtensa processor configuration.
6 *
7 * Source for configuration-independent binaries (which link in a
8 * configuration-specific HAL library) must NEVER include this file.
9 * It is perfectly normal, however, for the HAL source itself to include this file.
10 */
11
12/*
13 * Copyright (c) 2003 Tensilica, Inc. All Rights Reserved.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of version 2.1 of the GNU Lesser General Public
17 * License as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it would be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22 *
23 * Further, this software is distributed without any warranty that it is
24 * free of the rightful claim of any third person regarding infringement
25 * or the like. Any license provided herein, whether implied or
26 * otherwise, applies only to this software file. Patent licenses, if
27 * any, provided herein do not apply to combinations of this program with
28 * other software, or any other product whatsoever.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this program; if not, write the Free Software
32 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
33 * USA.
34 */
35
36
37#ifndef XTENSA_CONFIG_CORE_H
38#define XTENSA_CONFIG_CORE_H
39
40#include <xtensa/hal.h>
41
42
43/*----------------------------------------------------------------------
44 GENERAL
45 ----------------------------------------------------------------------*/
46
47/*
48 * Separators for macros that expand into arrays.
49 * These can be predefined by files that #include this one,
50 * when different separators are required.
51 */
52/* Element separator for macros that expand into 1-dimensional arrays: */
53#ifndef XCHAL_SEP
54#define XCHAL_SEP ,
55#endif
56/* Array separator for macros that expand into 2-dimensional arrays: */
57#ifndef XCHAL_SEP2
58#define XCHAL_SEP2 },{
59#endif
60
61
62/*----------------------------------------------------------------------
63 ENDIANNESS
64 ----------------------------------------------------------------------*/
65
66#define XCHAL_HAVE_BE 1
67#define XCHAL_HAVE_LE 0
68#define XCHAL_MEMORY_ORDER XTHAL_BIGENDIAN
69
70
71/*----------------------------------------------------------------------
72 REGISTER WINDOWS
73 ----------------------------------------------------------------------*/
74
75#define XCHAL_HAVE_WINDOWED 1 /* 1 if windowed registers option configured, 0 otherwise */
76#define XCHAL_NUM_AREGS 64 /* number of physical address regs */
77#define XCHAL_NUM_AREGS_LOG2 6 /* log2(XCHAL_NUM_AREGS) */
78
79
80/*----------------------------------------------------------------------
81 ADDRESS ALIGNMENT
82 ----------------------------------------------------------------------*/
83
84/* These apply to a selected set of core load and store instructions only (see ISA): */
85#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* 1 if unaligned loads cause an exception, 0 otherwise */
86#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* 1 if unaligned stores cause an exception, 0 otherwise */
87
88
89/*----------------------------------------------------------------------
90 INTERRUPTS
91 ----------------------------------------------------------------------*/
92
93#define XCHAL_HAVE_INTERRUPTS 1 /* 1 if interrupt option configured, 0 otherwise */
94#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* 1 if high-priority interrupt option configured, 0 otherwise */
95#define XCHAL_HAVE_HIGHLEVEL_INTERRUPTS XCHAL_HAVE_HIGHPRI_INTERRUPTS
96#define XCHAL_HAVE_NMI 0 /* 1 if NMI option configured, 0 otherwise */
97#define XCHAL_NUM_INTERRUPTS 17 /* number of interrupts */
98#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* number of bits to hold an interrupt number: roundup(log2(number of interrupts)) */
99#define XCHAL_NUM_EXTINTERRUPTS 10 /* number of external interrupts */
100#define XCHAL_NUM_INTLEVELS 4 /* number of interrupt levels (not including level zero!) */
101#define XCHAL_NUM_LOWPRI_LEVELS 1 /* number of low-priority interrupt levels (always 1) */
102#define XCHAL_FIRST_HIGHPRI_LEVEL (XCHAL_NUM_LOWPRI_LEVELS+1) /* level of first high-priority interrupt (always 2) */
103#define XCHAL_EXCM_LEVEL 1 /* level of interrupts masked by PS.EXCM (XEA2 only; always 1 in T10xx);
104 for XEA1, where there is no PS.EXCM, this is always 1;
105 interrupts at levels FIRST_HIGHPRI <= n <= EXCM_LEVEL, if any,
106 are termed "medium priority" interrupts (post T10xx only) */
107/* Note: 1 <= LOWPRI_LEVELS <= EXCM_LEVEL < DEBUGLEVEL <= NUM_INTLEVELS < NMILEVEL <= 15 */
108
109/* Masks of interrupts at each interrupt level: */
110#define XCHAL_INTLEVEL0_MASK 0x00000000
111#define XCHAL_INTLEVEL1_MASK 0x000064F9
112#define XCHAL_INTLEVEL2_MASK 0x00008902
113#define XCHAL_INTLEVEL3_MASK 0x00011204
114#define XCHAL_INTLEVEL4_MASK 0x00000000
115#define XCHAL_INTLEVEL5_MASK 0x00000000
116#define XCHAL_INTLEVEL6_MASK 0x00000000
117#define XCHAL_INTLEVEL7_MASK 0x00000000
118#define XCHAL_INTLEVEL8_MASK 0x00000000
119#define XCHAL_INTLEVEL9_MASK 0x00000000
120#define XCHAL_INTLEVEL10_MASK 0x00000000
121#define XCHAL_INTLEVEL11_MASK 0x00000000
122#define XCHAL_INTLEVEL12_MASK 0x00000000
123#define XCHAL_INTLEVEL13_MASK 0x00000000
124#define XCHAL_INTLEVEL14_MASK 0x00000000
125#define XCHAL_INTLEVEL15_MASK 0x00000000
126/* As an array of entries (eg. for C constant arrays): */
127#define XCHAL_INTLEVEL_MASKS 0x00000000 XCHAL_SEP \
128 0x000064F9 XCHAL_SEP \
129 0x00008902 XCHAL_SEP \
130 0x00011204 XCHAL_SEP \
131 0x00000000 XCHAL_SEP \
132 0x00000000 XCHAL_SEP \
133 0x00000000 XCHAL_SEP \
134 0x00000000 XCHAL_SEP \
135 0x00000000 XCHAL_SEP \
136 0x00000000 XCHAL_SEP \
137 0x00000000 XCHAL_SEP \
138 0x00000000 XCHAL_SEP \
139 0x00000000 XCHAL_SEP \
140 0x00000000 XCHAL_SEP \
141 0x00000000 XCHAL_SEP \
142 0x00000000
143
144/* Masks of interrupts at each range 1..n of interrupt levels: */
145#define XCHAL_INTLEVEL0_ANDBELOW_MASK 0x00000000
146#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x000064F9
147#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x0000EDFB
148#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x0001FFFF
149#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x0001FFFF
150#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x0001FFFF
151#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x0001FFFF
152#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x0001FFFF
153#define XCHAL_INTLEVEL8_ANDBELOW_MASK 0x0001FFFF
154#define XCHAL_INTLEVEL9_ANDBELOW_MASK 0x0001FFFF
155#define XCHAL_INTLEVEL10_ANDBELOW_MASK 0x0001FFFF
156#define XCHAL_INTLEVEL11_ANDBELOW_MASK 0x0001FFFF
157#define XCHAL_INTLEVEL12_ANDBELOW_MASK 0x0001FFFF
158#define XCHAL_INTLEVEL13_ANDBELOW_MASK 0x0001FFFF
159#define XCHAL_INTLEVEL14_ANDBELOW_MASK 0x0001FFFF
160#define XCHAL_INTLEVEL15_ANDBELOW_MASK 0x0001FFFF
161#define XCHAL_LOWPRI_MASK XCHAL_INTLEVEL1_ANDBELOW_MASK /* mask of all low-priority interrupts */
162#define XCHAL_EXCM_MASK XCHAL_INTLEVEL1_ANDBELOW_MASK /* mask of all interrupts masked by PS.EXCM (or CEXCM) */
163/* As an array of entries (eg. for C constant arrays): */
164#define XCHAL_INTLEVEL_ANDBELOW_MASKS 0x00000000 XCHAL_SEP \
165 0x000064F9 XCHAL_SEP \
166 0x0000EDFB XCHAL_SEP \
167 0x0001FFFF XCHAL_SEP \
168 0x0001FFFF XCHAL_SEP \
169 0x0001FFFF XCHAL_SEP \
170 0x0001FFFF XCHAL_SEP \
171 0x0001FFFF XCHAL_SEP \
172 0x0001FFFF XCHAL_SEP \
173 0x0001FFFF XCHAL_SEP \
174 0x0001FFFF XCHAL_SEP \
175 0x0001FFFF XCHAL_SEP \
176 0x0001FFFF XCHAL_SEP \
177 0x0001FFFF XCHAL_SEP \
178 0x0001FFFF XCHAL_SEP \
179 0x0001FFFF
180
181/* Interrupt numbers for each interrupt level at which only one interrupt was configured: */
182/*#define XCHAL_INTLEVEL1_NUM ...more than one interrupt at this level...*/
183/*#define XCHAL_INTLEVEL2_NUM ...more than one interrupt at this level...*/
184/*#define XCHAL_INTLEVEL3_NUM ...more than one interrupt at this level...*/
185
186/* Level of each interrupt: */
187#define XCHAL_INT0_LEVEL 1
188#define XCHAL_INT1_LEVEL 2
189#define XCHAL_INT2_LEVEL 3
190#define XCHAL_INT3_LEVEL 1
191#define XCHAL_INT4_LEVEL 1
192#define XCHAL_INT5_LEVEL 1
193#define XCHAL_INT6_LEVEL 1
194#define XCHAL_INT7_LEVEL 1
195#define XCHAL_INT8_LEVEL 2
196#define XCHAL_INT9_LEVEL 3
197#define XCHAL_INT10_LEVEL 1
198#define XCHAL_INT11_LEVEL 2
199#define XCHAL_INT12_LEVEL 3
200#define XCHAL_INT13_LEVEL 1
201#define XCHAL_INT14_LEVEL 1
202#define XCHAL_INT15_LEVEL 2
203#define XCHAL_INT16_LEVEL 3
204#define XCHAL_INT17_LEVEL 0
205#define XCHAL_INT18_LEVEL 0
206#define XCHAL_INT19_LEVEL 0
207#define XCHAL_INT20_LEVEL 0
208#define XCHAL_INT21_LEVEL 0
209#define XCHAL_INT22_LEVEL 0
210#define XCHAL_INT23_LEVEL 0
211#define XCHAL_INT24_LEVEL 0
212#define XCHAL_INT25_LEVEL 0
213#define XCHAL_INT26_LEVEL 0
214#define XCHAL_INT27_LEVEL 0
215#define XCHAL_INT28_LEVEL 0
216#define XCHAL_INT29_LEVEL 0
217#define XCHAL_INT30_LEVEL 0
218#define XCHAL_INT31_LEVEL 0
219/* As an array of entries (eg. for C constant arrays): */
220#define XCHAL_INT_LEVELS 1 XCHAL_SEP \
221 2 XCHAL_SEP \
222 3 XCHAL_SEP \
223 1 XCHAL_SEP \
224 1 XCHAL_SEP \
225 1 XCHAL_SEP \
226 1 XCHAL_SEP \
227 1 XCHAL_SEP \
228 2 XCHAL_SEP \
229 3 XCHAL_SEP \
230 1 XCHAL_SEP \
231 2 XCHAL_SEP \
232 3 XCHAL_SEP \
233 1 XCHAL_SEP \
234 1 XCHAL_SEP \
235 2 XCHAL_SEP \
236 3 XCHAL_SEP \
237 0 XCHAL_SEP \
238 0 XCHAL_SEP \
239 0 XCHAL_SEP \
240 0 XCHAL_SEP \
241 0 XCHAL_SEP \
242 0 XCHAL_SEP \
243 0 XCHAL_SEP \
244 0 XCHAL_SEP \
245 0 XCHAL_SEP \
246 0 XCHAL_SEP \
247 0 XCHAL_SEP \
248 0 XCHAL_SEP \
249 0 XCHAL_SEP \
250 0 XCHAL_SEP \
251 0
252
253/* Type of each interrupt: */
254#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
255#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
256#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
257#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
258#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
259#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
260#define XCHAL_INT6_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
261#define XCHAL_INT7_TYPE XTHAL_INTTYPE_EXTERN_EDGE
262#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_EDGE
263#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_EDGE
264#define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER
265#define XCHAL_INT11_TYPE XTHAL_INTTYPE_TIMER
266#define XCHAL_INT12_TYPE XTHAL_INTTYPE_TIMER
267#define XCHAL_INT13_TYPE XTHAL_INTTYPE_SOFTWARE
268#define XCHAL_INT14_TYPE XTHAL_INTTYPE_SOFTWARE
269#define XCHAL_INT15_TYPE XTHAL_INTTYPE_SOFTWARE
270#define XCHAL_INT16_TYPE XTHAL_INTTYPE_SOFTWARE
271#define XCHAL_INT17_TYPE XTHAL_INTTYPE_UNCONFIGURED
272#define XCHAL_INT18_TYPE XTHAL_INTTYPE_UNCONFIGURED
273#define XCHAL_INT19_TYPE XTHAL_INTTYPE_UNCONFIGURED
274#define XCHAL_INT20_TYPE XTHAL_INTTYPE_UNCONFIGURED
275#define XCHAL_INT21_TYPE XTHAL_INTTYPE_UNCONFIGURED
276#define XCHAL_INT22_TYPE XTHAL_INTTYPE_UNCONFIGURED
277#define XCHAL_INT23_TYPE XTHAL_INTTYPE_UNCONFIGURED
278#define XCHAL_INT24_TYPE XTHAL_INTTYPE_UNCONFIGURED
279#define XCHAL_INT25_TYPE XTHAL_INTTYPE_UNCONFIGURED
280#define XCHAL_INT26_TYPE XTHAL_INTTYPE_UNCONFIGURED
281#define XCHAL_INT27_TYPE XTHAL_INTTYPE_UNCONFIGURED
282#define XCHAL_INT28_TYPE XTHAL_INTTYPE_UNCONFIGURED
283#define XCHAL_INT29_TYPE XTHAL_INTTYPE_UNCONFIGURED
284#define XCHAL_INT30_TYPE XTHAL_INTTYPE_UNCONFIGURED
285#define XCHAL_INT31_TYPE XTHAL_INTTYPE_UNCONFIGURED
286/* As an array of entries (eg. for C constant arrays): */
287#define XCHAL_INT_TYPES XTHAL_INTTYPE_EXTERN_LEVEL XCHAL_SEP \
288 XTHAL_INTTYPE_EXTERN_LEVEL XCHAL_SEP \
289 XTHAL_INTTYPE_EXTERN_LEVEL XCHAL_SEP \
290 XTHAL_INTTYPE_EXTERN_LEVEL XCHAL_SEP \
291 XTHAL_INTTYPE_EXTERN_LEVEL XCHAL_SEP \
292 XTHAL_INTTYPE_EXTERN_LEVEL XCHAL_SEP \
293 XTHAL_INTTYPE_EXTERN_LEVEL XCHAL_SEP \
294 XTHAL_INTTYPE_EXTERN_EDGE XCHAL_SEP \
295 XTHAL_INTTYPE_EXTERN_EDGE XCHAL_SEP \
296 XTHAL_INTTYPE_EXTERN_EDGE XCHAL_SEP \
297 XTHAL_INTTYPE_TIMER XCHAL_SEP \
298 XTHAL_INTTYPE_TIMER XCHAL_SEP \
299 XTHAL_INTTYPE_TIMER XCHAL_SEP \
300 XTHAL_INTTYPE_SOFTWARE XCHAL_SEP \
301 XTHAL_INTTYPE_SOFTWARE XCHAL_SEP \
302 XTHAL_INTTYPE_SOFTWARE XCHAL_SEP \
303 XTHAL_INTTYPE_SOFTWARE XCHAL_SEP \
304 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
305 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
306 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
307 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
308 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
309 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
310 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
311 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
312 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
313 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
314 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
315 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
316 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
317 XTHAL_INTTYPE_UNCONFIGURED XCHAL_SEP \
318 XTHAL_INTTYPE_UNCONFIGURED
319
320/* Masks of interrupts for each type of interrupt: */
321#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFFE0000
322#define XCHAL_INTTYPE_MASK_SOFTWARE 0x0001E000
323#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000380
324#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000007F
325#define XCHAL_INTTYPE_MASK_TIMER 0x00001C00
326#define XCHAL_INTTYPE_MASK_NMI 0x00000000
327/* As an array of entries (eg. for C constant arrays): */
328#define XCHAL_INTTYPE_MASKS 0xFFFE0000 XCHAL_SEP \
329 0x0001E000 XCHAL_SEP \
330 0x00000380 XCHAL_SEP \
331 0x0000007F XCHAL_SEP \
332 0x00001C00 XCHAL_SEP \
333 0x00000000
334
335/* Interrupts assigned to each timer (CCOMPARE0 to CCOMPARE3), -1 if unassigned */
336#define XCHAL_TIMER0_INTERRUPT 10
337#define XCHAL_TIMER1_INTERRUPT 11
338#define XCHAL_TIMER2_INTERRUPT 12
339#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED
340/* As an array of entries (eg. for C constant arrays): */
341#define XCHAL_TIMER_INTERRUPTS 10 XCHAL_SEP \
342 11 XCHAL_SEP \
343 12 XCHAL_SEP \
344 XTHAL_TIMER_UNCONFIGURED
345
346/* Indexing macros: */
347#define _XCHAL_INTLEVEL_MASK(n) XCHAL_INTLEVEL ## n ## _MASK
348#define XCHAL_INTLEVEL_MASK(n) _XCHAL_INTLEVEL_MASK(n) /* n = 0 .. 15 */
349#define _XCHAL_INTLEVEL_ANDBELOWMASK(n) XCHAL_INTLEVEL ## n ## _ANDBELOW_MASK
350#define XCHAL_INTLEVEL_ANDBELOW_MASK(n) _XCHAL_INTLEVEL_ANDBELOWMASK(n) /* n = 0 .. 15 */
351#define _XCHAL_INT_LEVEL(n) XCHAL_INT ## n ## _LEVEL
352#define XCHAL_INT_LEVEL(n) _XCHAL_INT_LEVEL(n) /* n = 0 .. 31 */
353#define _XCHAL_INT_TYPE(n) XCHAL_INT ## n ## _TYPE
354#define XCHAL_INT_TYPE(n) _XCHAL_INT_TYPE(n) /* n = 0 .. 31 */
355#define _XCHAL_TIMER_INTERRUPT(n) XCHAL_TIMER ## n ## _INTERRUPT
356#define XCHAL_TIMER_INTERRUPT(n) _XCHAL_TIMER_INTERRUPT(n) /* n = 0 .. 3 */
357
358
359
360/*
361 * External interrupt vectors/levels.
362 * These macros describe how Xtensa processor interrupt numbers
363 * (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
364 * map to external BInterrupt<n> pins, for those interrupts
365 * configured as external (level-triggered, edge-triggered, or NMI).
366 * See the Xtensa processor databook for more details.
367 */
368
369/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */
370#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */
371#define XCHAL_EXTINT1_NUM 1 /* (intlevel 2) */
372#define XCHAL_EXTINT2_NUM 2 /* (intlevel 3) */
373#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */
374#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */
375#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */
376#define XCHAL_EXTINT6_NUM 6 /* (intlevel 1) */
377#define XCHAL_EXTINT7_NUM 7 /* (intlevel 1) */
378#define XCHAL_EXTINT8_NUM 8 /* (intlevel 2) */
379#define XCHAL_EXTINT9_NUM 9 /* (intlevel 3) */
380
381/* Corresponding interrupt masks: */
382#define XCHAL_EXTINT0_MASK 0x00000001
383#define XCHAL_EXTINT1_MASK 0x00000002
384#define XCHAL_EXTINT2_MASK 0x00000004
385#define XCHAL_EXTINT3_MASK 0x00000008
386#define XCHAL_EXTINT4_MASK 0x00000010
387#define XCHAL_EXTINT5_MASK 0x00000020
388#define XCHAL_EXTINT6_MASK 0x00000040
389#define XCHAL_EXTINT7_MASK 0x00000080
390#define XCHAL_EXTINT8_MASK 0x00000100
391#define XCHAL_EXTINT9_MASK 0x00000200
392
393/* Core config interrupt levels mapped to each external interrupt: */
394#define XCHAL_EXTINT0_LEVEL 1 /* (int number 0) */
395#define XCHAL_EXTINT1_LEVEL 2 /* (int number 1) */
396#define XCHAL_EXTINT2_LEVEL 3 /* (int number 2) */
397#define XCHAL_EXTINT3_LEVEL 1 /* (int number 3) */
398#define XCHAL_EXTINT4_LEVEL 1 /* (int number 4) */
399#define XCHAL_EXTINT5_LEVEL 1 /* (int number 5) */
400#define XCHAL_EXTINT6_LEVEL 1 /* (int number 6) */
401#define XCHAL_EXTINT7_LEVEL 1 /* (int number 7) */
402#define XCHAL_EXTINT8_LEVEL 2 /* (int number 8) */
403#define XCHAL_EXTINT9_LEVEL 3 /* (int number 9) */
404
405
406/*----------------------------------------------------------------------
407 EXCEPTIONS and VECTORS
408 ----------------------------------------------------------------------*/
409
410#define XCHAL_HAVE_EXCEPTIONS 1 /* 1 if exception option configured, 0 otherwise */
411
412#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture number: 1 for XEA1 (old), 2 for XEA2 (new) */
413#define XCHAL_HAVE_XEA1 0 /* 1 if XEA1, 0 otherwise */
414#define XCHAL_HAVE_XEA2 1 /* 1 if XEA2, 0 otherwise */
415/* For backward compatibility ONLY -- DO NOT USE (will be removed in future release): */
416#define XCHAL_HAVE_OLD_EXC_ARCH XCHAL_HAVE_XEA1 /* (DEPRECATED) 1 if old exception architecture (XEA1), 0 otherwise (eg. XEA2) */
417#define XCHAL_HAVE_EXCM XCHAL_HAVE_XEA2 /* (DEPRECATED) 1 if PS.EXCM bit exists (currently equals XCHAL_HAVE_TLBS) */
418
419#define XCHAL_RESET_VECTOR_VADDR 0xFE000020
420#define XCHAL_RESET_VECTOR_PADDR 0xFE000020
421#define XCHAL_USER_VECTOR_VADDR 0xD0000220
422#define XCHAL_PROGRAMEXC_VECTOR_VADDR XCHAL_USER_VECTOR_VADDR /* for backward compatibility */
423#define XCHAL_USEREXC_VECTOR_VADDR XCHAL_USER_VECTOR_VADDR /* for backward compatibility */
424#define XCHAL_USER_VECTOR_PADDR 0x00000220
425#define XCHAL_PROGRAMEXC_VECTOR_PADDR XCHAL_USER_VECTOR_PADDR /* for backward compatibility */
426#define XCHAL_USEREXC_VECTOR_PADDR XCHAL_USER_VECTOR_PADDR /* for backward compatibility */
427#define XCHAL_KERNEL_VECTOR_VADDR 0xD0000200
428#define XCHAL_STACKEDEXC_VECTOR_VADDR XCHAL_KERNEL_VECTOR_VADDR /* for backward compatibility */
429#define XCHAL_KERNELEXC_VECTOR_VADDR XCHAL_KERNEL_VECTOR_VADDR /* for backward compatibility */
430#define XCHAL_KERNEL_VECTOR_PADDR 0x00000200
431#define XCHAL_STACKEDEXC_VECTOR_PADDR XCHAL_KERNEL_VECTOR_PADDR /* for backward compatibility */
432#define XCHAL_KERNELEXC_VECTOR_PADDR XCHAL_KERNEL_VECTOR_PADDR /* for backward compatibility */
433#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0xD0000290
434#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x00000290
435#define XCHAL_WINDOW_VECTORS_VADDR 0xD0000000
436#define XCHAL_WINDOW_VECTORS_PADDR 0x00000000
437#define XCHAL_INTLEVEL2_VECTOR_VADDR 0xD0000240
438#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00000240
439#define XCHAL_INTLEVEL3_VECTOR_VADDR 0xD0000250
440#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x00000250
441#define XCHAL_INTLEVEL4_VECTOR_VADDR 0xFE000520
442#define XCHAL_INTLEVEL4_VECTOR_PADDR 0xFE000520
443#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL4_VECTOR_VADDR
444#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL4_VECTOR_PADDR
445
446/* Indexing macros: */
447#define _XCHAL_INTLEVEL_VECTOR_VADDR(n) XCHAL_INTLEVEL ## n ## _VECTOR_VADDR
448#define XCHAL_INTLEVEL_VECTOR_VADDR(n) _XCHAL_INTLEVEL_VECTOR_VADDR(n) /* n = 0 .. 15 */
449
450/*
451 * General Exception Causes
452 * (values of EXCCAUSE special register set by general exceptions,
453 * which vector to the user, kernel, or double-exception vectors):
454 */
455#define XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION 0 /* Illegal Instruction (IllegalInstruction) */
456#define XCHAL_EXCCAUSE_SYSTEM_CALL 1 /* System Call (SystemCall) */
457#define XCHAL_EXCCAUSE_INSTRUCTION_FETCH_ERROR 2 /* Instruction Fetch Error (InstructionFetchError) */
458#define XCHAL_EXCCAUSE_LOAD_STORE_ERROR 3 /* Load Store Error (LoadStoreError) */
459#define XCHAL_EXCCAUSE_LEVEL1_INTERRUPT 4 /* Level 1 Interrupt (Level1Interrupt) */
460#define XCHAL_EXCCAUSE_ALLOCA 5 /* Stack Extension Assist (Alloca) */
461#define XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO 6 /* Integer Divide by Zero (IntegerDivideByZero) */
462#define XCHAL_EXCCAUSE_SPECULATION 7 /* Speculation (Speculation) */
463#define XCHAL_EXCCAUSE_PRIVILEGED 8 /* Privileged Instruction (Privileged) */
464#define XCHAL_EXCCAUSE_UNALIGNED 9 /* Unaligned Load Store (Unaligned) */
465#define XCHAL_EXCCAUSE_ITLB_MISS 16 /* ITlb Miss Exception (ITlbMiss) */
466#define XCHAL_EXCCAUSE_ITLB_MULTIHIT 17 /* ITlb Mutltihit Exception (ITlbMultihit) */
467#define XCHAL_EXCCAUSE_ITLB_PRIVILEGE 18 /* ITlb Privilege Exception (ITlbPrivilege) */
468#define XCHAL_EXCCAUSE_ITLB_SIZE_RESTRICTION 19 /* ITlb Size Restriction Exception (ITlbSizeRestriction) */
469#define XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE 20 /* Fetch Cache Attribute Exception (FetchCacheAttribute) */
470#define XCHAL_EXCCAUSE_DTLB_MISS 24 /* DTlb Miss Exception (DTlbMiss) */
471#define XCHAL_EXCCAUSE_DTLB_MULTIHIT 25 /* DTlb Multihit Exception (DTlbMultihit) */
472#define XCHAL_EXCCAUSE_DTLB_PRIVILEGE 26 /* DTlb Privilege Exception (DTlbPrivilege) */
473#define XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION 27 /* DTlb Size Restriction Exception (DTlbSizeRestriction) */
474#define XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28 /* Load Cache Attribute Exception (LoadCacheAttribute) */
475#define XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE 29 /* Store Cache Attribute Exception (StoreCacheAttribute) */
476#define XCHAL_EXCCAUSE_FLOATING_POINT 40 /* Floating Point Exception (FloatingPoint) */
477
478
479
480/*----------------------------------------------------------------------
481 TIMERS
482 ----------------------------------------------------------------------*/
483
484#define XCHAL_HAVE_CCOUNT 1 /* 1 if have CCOUNT, 0 otherwise */
485/*#define XCHAL_HAVE_TIMERS XCHAL_HAVE_CCOUNT*/
486#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */
487
488
489
490/*----------------------------------------------------------------------
491 DEBUG
492 ----------------------------------------------------------------------*/
493
494#define XCHAL_HAVE_DEBUG 1 /* 1 if debug option configured, 0 otherwise */
495#define XCHAL_HAVE_OCD 1 /* 1 if OnChipDebug option configured, 0 otherwise */
496#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */
497#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */
498#define XCHAL_DEBUGLEVEL 4 /* debug interrupt level */
499/*DebugExternalInterrupt 0 0|1*/
500/*DebugUseDIRArray 0 0|1*/
501
502
503
504
505/*----------------------------------------------------------------------
506 COPROCESSORS and EXTRA STATE
507 ----------------------------------------------------------------------*/
508
509#define XCHAL_HAVE_CP 0 /* 1 if coprocessor option configured (CPENABLE present) */
510#define XCHAL_CP_MAXCFG 0 /* max allowed cp id plus one (per cfg) */
511
512#include <xtensa/config/tie.h>
513
514
515
516
517/*----------------------------------------------------------------------
518 INTERNAL I/D RAM/ROMs and XLMI
519 ----------------------------------------------------------------------*/
520
521#define XCHAL_NUM_INSTROM 0 /* number of core instruction ROMs configured */
522#define XCHAL_NUM_INSTRAM 0 /* number of core instruction RAMs configured */
523#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs configured */
524#define XCHAL_NUM_DATARAM 0 /* number of core data RAMs configured */
525#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports configured */
526#define XCHAL_NUM_IROM XCHAL_NUM_INSTROM /* (DEPRECATED) */
527#define XCHAL_NUM_IRAM XCHAL_NUM_INSTRAM /* (DEPRECATED) */
528#define XCHAL_NUM_DROM XCHAL_NUM_DATAROM /* (DEPRECATED) */
529#define XCHAL_NUM_DRAM XCHAL_NUM_DATARAM /* (DEPRECATED) */
530
531
532
533/*----------------------------------------------------------------------
534 CACHE
535 ----------------------------------------------------------------------*/
536
537/* Size of the cache lines in log2(bytes): */
538#define XCHAL_ICACHE_LINEWIDTH 4
539#define XCHAL_DCACHE_LINEWIDTH 4
540/* Size of the cache lines in bytes: */
541#define XCHAL_ICACHE_LINESIZE 16
542#define XCHAL_DCACHE_LINESIZE 16
543/* Max for both I-cache and D-cache (used for general alignment): */
544#define XCHAL_CACHE_LINEWIDTH_MAX 4
545#define XCHAL_CACHE_LINESIZE_MAX 16
546
547/* Number of cache sets in log2(lines per way): */
548#define XCHAL_ICACHE_SETWIDTH 8
549#define XCHAL_DCACHE_SETWIDTH 8
550/* Max for both I-cache and D-cache (used for general cache-coherency page alignment): */
551#define XCHAL_CACHE_SETWIDTH_MAX 8
552#define XCHAL_CACHE_SETSIZE_MAX 256
553
554/* Cache set associativity (number of ways): */
555#define XCHAL_ICACHE_WAYS 2
556#define XCHAL_DCACHE_WAYS 2
557
558/* Size of the caches in bytes (ways * 2^(linewidth + setwidth)): */
559#define XCHAL_ICACHE_SIZE 8192
560#define XCHAL_DCACHE_SIZE 8192
561
562/* Cache features: */
563#define XCHAL_DCACHE_IS_WRITEBACK 0
564/* Whether cache locking feature is available: */
565#define XCHAL_ICACHE_LINE_LOCKABLE 0
566#define XCHAL_DCACHE_LINE_LOCKABLE 0
567
568/* Number of (encoded) cache attribute bits: */
569#define XCHAL_CA_BITS 4 /* number of bits needed to hold cache attribute encoding */
570/* (The number of access mode bits (decoded cache attribute bits) is defined by the architecture; see xtensa/hal.h?) */
571
572
573/* Cache Attribute encodings -- lists of access modes for each cache attribute: */
574#define XCHAL_FCA_LIST XTHAL_FAM_EXCEPTION XCHAL_SEP \
575 XTHAL_FAM_BYPASS XCHAL_SEP \
576 XTHAL_FAM_EXCEPTION XCHAL_SEP \
577 XTHAL_FAM_BYPASS XCHAL_SEP \
578 XTHAL_FAM_EXCEPTION XCHAL_SEP \
579 XTHAL_FAM_CACHED XCHAL_SEP \
580 XTHAL_FAM_EXCEPTION XCHAL_SEP \
581 XTHAL_FAM_CACHED XCHAL_SEP \
582 XTHAL_FAM_EXCEPTION XCHAL_SEP \
583 XTHAL_FAM_CACHED XCHAL_SEP \
584 XTHAL_FAM_EXCEPTION XCHAL_SEP \
585 XTHAL_FAM_CACHED XCHAL_SEP \
586 XTHAL_FAM_EXCEPTION XCHAL_SEP \
587 XTHAL_FAM_EXCEPTION XCHAL_SEP \
588 XTHAL_FAM_EXCEPTION XCHAL_SEP \
589 XTHAL_FAM_EXCEPTION
590#define XCHAL_LCA_LIST XTHAL_LAM_EXCEPTION XCHAL_SEP \
591 XTHAL_LAM_BYPASSG XCHAL_SEP \
592 XTHAL_LAM_EXCEPTION XCHAL_SEP \
593 XTHAL_LAM_BYPASSG XCHAL_SEP \
594 XTHAL_LAM_EXCEPTION XCHAL_SEP \
595 XTHAL_LAM_CACHED XCHAL_SEP \
596 XTHAL_LAM_EXCEPTION XCHAL_SEP \
597 XTHAL_LAM_CACHED XCHAL_SEP \
598 XTHAL_LAM_EXCEPTION XCHAL_SEP \
599 XTHAL_LAM_NACACHED XCHAL_SEP \
600 XTHAL_LAM_EXCEPTION XCHAL_SEP \
601 XTHAL_LAM_NACACHED XCHAL_SEP \
602 XTHAL_LAM_EXCEPTION XCHAL_SEP \
603 XTHAL_LAM_ISOLATE XCHAL_SEP \
604 XTHAL_LAM_EXCEPTION XCHAL_SEP \
605 XTHAL_LAM_CACHED
606#define XCHAL_SCA_LIST XTHAL_SAM_EXCEPTION XCHAL_SEP \
607 XTHAL_SAM_EXCEPTION XCHAL_SEP \
608 XTHAL_SAM_EXCEPTION XCHAL_SEP \
609 XTHAL_SAM_BYPASS XCHAL_SEP \
610 XTHAL_SAM_EXCEPTION XCHAL_SEP \
611 XTHAL_SAM_EXCEPTION XCHAL_SEP \
612 XTHAL_SAM_EXCEPTION XCHAL_SEP \
613 XTHAL_SAM_WRITETHRU XCHAL_SEP \
614 XTHAL_SAM_EXCEPTION XCHAL_SEP \
615 XTHAL_SAM_EXCEPTION XCHAL_SEP \
616 XTHAL_SAM_EXCEPTION XCHAL_SEP \
617 XTHAL_SAM_WRITETHRU XCHAL_SEP \
618 XTHAL_SAM_EXCEPTION XCHAL_SEP \
619 XTHAL_SAM_ISOLATE XCHAL_SEP \
620 XTHAL_SAM_EXCEPTION XCHAL_SEP \
621 XTHAL_SAM_WRITETHRU
622
623/* Test:
624 read/only: 0 + 1 + 2 + 4 + 5 + 6 + 8 + 9 + 10 + 12 + 14
625 read/only: 0 + 1 + 2 + 4 + 5 + 6 + 8 + 9 + 10 + 12 + 14
626 all: 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15
627 fault: 0 + 2 + 4 + 6 + 8 + 10 + 12 + 14
628 r/w/x cached:
629 r/w/x dcached:
630 I-bypass: 1 + 3
631
632 load guard bit set: 1 + 3
633 load guard bit clr: 0 + 2 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15
634 hit-cache r/w/x: 7 + 11
635
636 fams: 5
637 fams: 0 / 6 / 18 / 1 / 2
638 fams: Bypass / Isolate / Cached / Exception / NACached
639
640 MMU okay: yes
641*/
642
643
644/*----------------------------------------------------------------------
645 MMU
646 ----------------------------------------------------------------------*/
647
648/*
649 * General notes on MMU parameters.
650 *
651 * Terminology:
652 * ASID = address-space ID (acts as an "extension" of virtual addresses)
653 * VPN = virtual page number
654 * PPN = physical page number
655 * CA = encoded cache attribute (access modes)
656 * TLB = translation look-aside buffer (term is stretched somewhat here)
657 * I = instruction (fetch accesses)
658 * D = data (load and store accesses)
659 * way = each TLB (ITLB and DTLB) consists of a number of "ways"
660 * that simultaneously match the virtual address of an access;
661 * a TLB successfully translates a virtual address if exactly
662 * one way matches the vaddr; if none match, it is a miss;
663 * if multiple match, one gets a "multihit" exception;
664 * each way can be independently configured in terms of number of
665 * entries, page sizes, which fields are writable or constant, etc.
666 * set = group of contiguous ways with exactly identical parameters
667 * ARF = auto-refill; hardware services a 1st-level miss by loading a PTE
668 * from the page table and storing it in one of the auto-refill ways;
669 * if this PTE load also misses, a miss exception is posted for s/w.
670 * min-wired = a "min-wired" way can be used to map a single (minimum-sized)
671 * page arbitrarily under program control; it has a single entry,
672 * is non-auto-refill (some other way(s) must be auto-refill),
673 * all its fields (VPN, PPN, ASID, CA) are all writable, and it
674 * supports the XCHAL_MMU_MIN_PTE_PAGE_SIZE page size (a current
675 * restriction is that this be the only page size it supports).
676 *
677 * TLB way entries are virtually indexed.
678 * TLB ways that support multiple page sizes:
679 * - must have all writable VPN and PPN fields;
680 * - can only use one page size at any given time (eg. setup at startup),
681 * selected by the respective ITLBCFG or DTLBCFG special register,
682 * whose bits n*4+3 .. n*4 index the list of page sizes for way n
683 * (XCHAL_xTLB_SETm_PAGESZ_LOG2_LIST for set m corresponding to way n);
684 * this list may be sparse for auto-refill ways because auto-refill
685 * ways have independent lists of supported page sizes sharing a
686 * common encoding with PTE entries; the encoding is the index into
687 * this list; unsupported sizes for a given way are zero in the list;
688 * selecting unsupported sizes results in undefined hardware behaviour;
689 * - is only possible for ways 0 thru 7 (due to ITLBCFG/DTLBCFG definition).
690 */
691
692#define XCHAL_HAVE_CACHEATTR 0 /* 1 if CACHEATTR register present, 0 if TLBs present instead */
693#define XCHAL_HAVE_TLBS 1 /* 1 if TLBs present, 0 if CACHEATTR present instead */
694#define XCHAL_HAVE_MMU XCHAL_HAVE_TLBS /* (DEPRECATED; use XCHAL_HAVE_TLBS instead; will be removed in future release) */
695#define XCHAL_HAVE_SPANNING_WAY 0 /* 1 if single way maps entire virtual address space in I+D */
696#define XCHAL_HAVE_IDENTITY_MAP 0 /* 1 if virtual addr == physical addr always, 0 otherwise */
697#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* 1 if have MMU that mimics a CACHEATTR config (CaMMU) */
698#define XCHAL_HAVE_XLT_CACHEATTR 0 /* 1 if have MMU that mimics a CACHEATTR config, but with translation (CaXltMMU) */
699
700#define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs (address space IDs) */
701#define XCHAL_MMU_ASID_INVALID 0 /* ASID value indicating invalid address space */
702#define XCHAL_MMU_ASID_KERNEL 1 /* ASID value indicating kernel (ring 0) address space */
703#define XCHAL_MMU_RINGS 4 /* number of rings supported (1..4) */
704#define XCHAL_MMU_RING_BITS 2 /* number of bits needed to hold ring number */
705#define XCHAL_MMU_SR_BITS 0 /* number of size-restriction bits supported */
706#define XCHAL_MMU_CA_BITS 4 /* number of bits needed to hold cache attribute encoding */
707#define XCHAL_MMU_MAX_PTE_PAGE_SIZE 12 /* max page size in a PTE structure (log2) */
708#define XCHAL_MMU_MIN_PTE_PAGE_SIZE 12 /* min page size in a PTE structure (log2) */
709
710
711/*** Instruction TLB: ***/
712
713#define XCHAL_ITLB_WAY_BITS 3 /* number of bits holding the ways */
714#define XCHAL_ITLB_WAYS 7 /* number of ways (n-way set-associative TLB) */
715#define XCHAL_ITLB_ARF_WAYS 4 /* number of auto-refill ways */
716#define XCHAL_ITLB_SETS 4 /* number of sets (groups of ways with identical settings) */
717
718/* Way set to which each way belongs: */
719#define XCHAL_ITLB_WAY0_SET 0
720#define XCHAL_ITLB_WAY1_SET 0
721#define XCHAL_ITLB_WAY2_SET 0
722#define XCHAL_ITLB_WAY3_SET 0
723#define XCHAL_ITLB_WAY4_SET 1
724#define XCHAL_ITLB_WAY5_SET 2
725#define XCHAL_ITLB_WAY6_SET 3
726
727/* Ways sets that are used by hardware auto-refill (ARF): */
728#define XCHAL_ITLB_ARF_SETS 1 /* number of auto-refill sets */
729#define XCHAL_ITLB_ARF_SET0 0 /* index of n'th auto-refill set */
730
731/* Way sets that are "min-wired" (see terminology comment above): */
732#define XCHAL_ITLB_MINWIRED_SETS 0 /* number of "min-wired" sets */
733
734
735/* ITLB way set 0 (group of ways 0 thru 3): */
736#define XCHAL_ITLB_SET0_WAY 0 /* index of first way in this way set */
737#define XCHAL_ITLB_SET0_WAYS 4 /* number of (contiguous) ways in this way set */
738#define XCHAL_ITLB_SET0_ENTRIES_LOG2 2 /* log2(number of entries in this way) */
739#define XCHAL_ITLB_SET0_ENTRIES 4 /* number of entries in this way (always a power of 2) */
740#define XCHAL_ITLB_SET0_ARF 1 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
741#define XCHAL_ITLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */
742#define XCHAL_ITLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */
743#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MIN 12 /* log2(minimum supported page size) */
744#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MAX 12 /* log2(maximum supported page size) */
745#define XCHAL_ITLB_SET0_PAGESZ_LOG2_LIST 12 /* list of log2(page size)s, separated by XCHAL_SEP;
746 2^PAGESZ_BITS entries in list, unsupported entries are zero */
747#define XCHAL_ITLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */
748#define XCHAL_ITLB_SET0_VPN_CONSTMASK 0 /* constant VPN bits, not including entry index bits; 0 if all writable */
749#define XCHAL_ITLB_SET0_PPN_CONSTMASK 0 /* constant PPN bits, including entry index bits; 0 if all writable */
750#define XCHAL_ITLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */
751#define XCHAL_ITLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
752#define XCHAL_ITLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
753#define XCHAL_ITLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
754#define XCHAL_ITLB_SET0_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
755
756/* ITLB way set 1 (group of ways 4 thru 4): */
757#define XCHAL_ITLB_SET1_WAY 4 /* index of first way in this way set */
758#define XCHAL_ITLB_SET1_WAYS 1 /* number of (contiguous) ways in this way set */
759#define XCHAL_ITLB_SET1_ENTRIES_LOG2 2 /* log2(number of entries in this way) */
760#define XCHAL_ITLB_SET1_ENTRIES 4 /* number of entries in this way (always a power of 2) */
761#define XCHAL_ITLB_SET1_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
762#define XCHAL_ITLB_SET1_PAGESIZES 4 /* number of supported page sizes in this way */
763#define XCHAL_ITLB_SET1_PAGESZ_BITS 2 /* number of bits to encode the page size */
764#define XCHAL_ITLB_SET1_PAGESZ_LOG2_MIN 20 /* log2(minimum supported page size) */
765#define XCHAL_ITLB_SET1_PAGESZ_LOG2_MAX 26 /* log2(maximum supported page size) */
766#define XCHAL_ITLB_SET1_PAGESZ_LOG2_LIST 20 XCHAL_SEP 22 XCHAL_SEP 24 XCHAL_SEP 26 /* list of log2(page size)s, separated by XCHAL_SEP;
767 2^PAGESZ_BITS entries in list, unsupported entries are zero */
768#define XCHAL_ITLB_SET1_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */
769#define XCHAL_ITLB_SET1_VPN_CONSTMASK 0 /* constant VPN bits, not including entry index bits; 0 if all writable */
770#define XCHAL_ITLB_SET1_PPN_CONSTMASK 0 /* constant PPN bits, including entry index bits; 0 if all writable */
771#define XCHAL_ITLB_SET1_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */
772#define XCHAL_ITLB_SET1_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
773#define XCHAL_ITLB_SET1_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
774#define XCHAL_ITLB_SET1_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
775#define XCHAL_ITLB_SET1_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
776
777/* ITLB way set 2 (group of ways 5 thru 5): */
778#define XCHAL_ITLB_SET2_WAY 5 /* index of first way in this way set */
779#define XCHAL_ITLB_SET2_WAYS 1 /* number of (contiguous) ways in this way set */
780#define XCHAL_ITLB_SET2_ENTRIES_LOG2 1 /* log2(number of entries in this way) */
781#define XCHAL_ITLB_SET2_ENTRIES 2 /* number of entries in this way (always a power of 2) */
782#define XCHAL_ITLB_SET2_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
783#define XCHAL_ITLB_SET2_PAGESIZES 1 /* number of supported page sizes in this way */
784#define XCHAL_ITLB_SET2_PAGESZ_BITS 0 /* number of bits to encode the page size */
785#define XCHAL_ITLB_SET2_PAGESZ_LOG2_MIN 27 /* log2(minimum supported page size) */
786#define XCHAL_ITLB_SET2_PAGESZ_LOG2_MAX 27 /* log2(maximum supported page size) */
787#define XCHAL_ITLB_SET2_PAGESZ_LOG2_LIST 27 /* list of log2(page size)s, separated by XCHAL_SEP;
788 2^PAGESZ_BITS entries in list, unsupported entries are zero */
789#define XCHAL_ITLB_SET2_ASID_CONSTMASK 0xFF /* constant ASID bits; 0 if all writable */
790#define XCHAL_ITLB_SET2_VPN_CONSTMASK 0xF0000000 /* constant VPN bits, not including entry index bits; 0 if all writable */
791#define XCHAL_ITLB_SET2_PPN_CONSTMASK 0xF8000000 /* constant PPN bits, including entry index bits; 0 if all writable */
792#define XCHAL_ITLB_SET2_CA_CONSTMASK 0x0000000F /* constant CA bits; 0 if all writable */
793#define XCHAL_ITLB_SET2_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
794#define XCHAL_ITLB_SET2_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
795#define XCHAL_ITLB_SET2_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
796#define XCHAL_ITLB_SET2_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
797/* Constant ASID values for each entry of ITLB way set 2 (because ASID_CONSTMASK is non-zero): */
798#define XCHAL_ITLB_SET2_E0_ASID_CONST 0x01
799#define XCHAL_ITLB_SET2_E1_ASID_CONST 0x01
800/* Constant VPN values for each entry of ITLB way set 2 (because VPN_CONSTMASK is non-zero): */
801#define XCHAL_ITLB_SET2_E0_VPN_CONST 0xD0000000
802#define XCHAL_ITLB_SET2_E1_VPN_CONST 0xD8000000
803/* Constant PPN values for each entry of ITLB way set 2 (because PPN_CONSTMASK is non-zero): */
804#define XCHAL_ITLB_SET2_E0_PPN_CONST 0x00000000
805#define XCHAL_ITLB_SET2_E1_PPN_CONST 0x00000000
806/* Constant CA values for each entry of ITLB way set 2 (because CA_CONSTMASK is non-zero): */
807#define XCHAL_ITLB_SET2_E0_CA_CONST 0x07
808#define XCHAL_ITLB_SET2_E1_CA_CONST 0x03
809
810/* ITLB way set 3 (group of ways 6 thru 6): */
811#define XCHAL_ITLB_SET3_WAY 6 /* index of first way in this way set */
812#define XCHAL_ITLB_SET3_WAYS 1 /* number of (contiguous) ways in this way set */
813#define XCHAL_ITLB_SET3_ENTRIES_LOG2 1 /* log2(number of entries in this way) */
814#define XCHAL_ITLB_SET3_ENTRIES 2 /* number of entries in this way (always a power of 2) */
815#define XCHAL_ITLB_SET3_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
816#define XCHAL_ITLB_SET3_PAGESIZES 1 /* number of supported page sizes in this way */
817#define XCHAL_ITLB_SET3_PAGESZ_BITS 0 /* number of bits to encode the page size */
818#define XCHAL_ITLB_SET3_PAGESZ_LOG2_MIN 28 /* log2(minimum supported page size) */
819#define XCHAL_ITLB_SET3_PAGESZ_LOG2_MAX 28 /* log2(maximum supported page size) */
820#define XCHAL_ITLB_SET3_PAGESZ_LOG2_LIST 28 /* list of log2(page size)s, separated by XCHAL_SEP;
821 2^PAGESZ_BITS entries in list, unsupported entries are zero */
822#define XCHAL_ITLB_SET3_ASID_CONSTMASK 0xFF /* constant ASID bits; 0 if all writable */
823#define XCHAL_ITLB_SET3_VPN_CONSTMASK 0xE0000000 /* constant VPN bits, not including entry index bits; 0 if all writable */
824#define XCHAL_ITLB_SET3_PPN_CONSTMASK 0xF0000000 /* constant PPN bits, including entry index bits; 0 if all writable */
825#define XCHAL_ITLB_SET3_CA_CONSTMASK 0x0000000F /* constant CA bits; 0 if all writable */
826#define XCHAL_ITLB_SET3_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
827#define XCHAL_ITLB_SET3_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
828#define XCHAL_ITLB_SET3_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
829#define XCHAL_ITLB_SET3_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
830/* Constant ASID values for each entry of ITLB way set 3 (because ASID_CONSTMASK is non-zero): */
831#define XCHAL_ITLB_SET3_E0_ASID_CONST 0x01
832#define XCHAL_ITLB_SET3_E1_ASID_CONST 0x01
833/* Constant VPN values for each entry of ITLB way set 3 (because VPN_CONSTMASK is non-zero): */
834#define XCHAL_ITLB_SET3_E0_VPN_CONST 0xE0000000
835#define XCHAL_ITLB_SET3_E1_VPN_CONST 0xF0000000
836/* Constant PPN values for each entry of ITLB way set 3 (because PPN_CONSTMASK is non-zero): */
837#define XCHAL_ITLB_SET3_E0_PPN_CONST 0xF0000000
838#define XCHAL_ITLB_SET3_E1_PPN_CONST 0xF0000000
839/* Constant CA values for each entry of ITLB way set 3 (because CA_CONSTMASK is non-zero): */
840#define XCHAL_ITLB_SET3_E0_CA_CONST 0x07
841#define XCHAL_ITLB_SET3_E1_CA_CONST 0x03
842
843/* Indexing macros: */
844#define _XCHAL_ITLB_SET(n,_what) XCHAL_ITLB_SET ## n ## _what
845#define XCHAL_ITLB_SET(n,what) _XCHAL_ITLB_SET(n, _ ## what )
846#define _XCHAL_ITLB_SET_E(n,i,_what) XCHAL_ITLB_SET ## n ## _E ## i ## _what
847#define XCHAL_ITLB_SET_E(n,i,what) _XCHAL_ITLB_SET_E(n,i, _ ## what )
848/*
849 * Example use: XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,ENTRIES)
850 * to get the value of XCHAL_ITLB_SET<n>_ENTRIES where <n> is the first auto-refill set.
851 */
852
853
854/*** Data TLB: ***/
855
856#define XCHAL_DTLB_WAY_BITS 4 /* number of bits holding the ways */
857#define XCHAL_DTLB_WAYS 10 /* number of ways (n-way set-associative TLB) */
858#define XCHAL_DTLB_ARF_WAYS 4 /* number of auto-refill ways */
859#define XCHAL_DTLB_SETS 5 /* number of sets (groups of ways with identical settings) */
860
861/* Way set to which each way belongs: */
862#define XCHAL_DTLB_WAY0_SET 0
863#define XCHAL_DTLB_WAY1_SET 0
864#define XCHAL_DTLB_WAY2_SET 0
865#define XCHAL_DTLB_WAY3_SET 0
866#define XCHAL_DTLB_WAY4_SET 1
867#define XCHAL_DTLB_WAY5_SET 2
868#define XCHAL_DTLB_WAY6_SET 3
869#define XCHAL_DTLB_WAY7_SET 4
870#define XCHAL_DTLB_WAY8_SET 4
871#define XCHAL_DTLB_WAY9_SET 4
872
873/* Ways sets that are used by hardware auto-refill (ARF): */
874#define XCHAL_DTLB_ARF_SETS 1 /* number of auto-refill sets */
875#define XCHAL_DTLB_ARF_SET0 0 /* index of n'th auto-refill set */
876
877/* Way sets that are "min-wired" (see terminology comment above): */
878#define XCHAL_DTLB_MINWIRED_SETS 1 /* number of "min-wired" sets */
879#define XCHAL_DTLB_MINWIRED_SET0 4 /* index of n'th "min-wired" set */
880
881
882/* DTLB way set 0 (group of ways 0 thru 3): */
883#define XCHAL_DTLB_SET0_WAY 0 /* index of first way in this way set */
884#define XCHAL_DTLB_SET0_WAYS 4 /* number of (contiguous) ways in this way set */
885#define XCHAL_DTLB_SET0_ENTRIES_LOG2 2 /* log2(number of entries in this way) */
886#define XCHAL_DTLB_SET0_ENTRIES 4 /* number of entries in this way (always a power of 2) */
887#define XCHAL_DTLB_SET0_ARF 1 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
888#define XCHAL_DTLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */
889#define XCHAL_DTLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */
890#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MIN 12 /* log2(minimum supported page size) */
891#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MAX 12 /* log2(maximum supported page size) */
892#define XCHAL_DTLB_SET0_PAGESZ_LOG2_LIST 12 /* list of log2(page size)s, separated by XCHAL_SEP;
893 2^PAGESZ_BITS entries in list, unsupported entries are zero */
894#define XCHAL_DTLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */
895#define XCHAL_DTLB_SET0_VPN_CONSTMASK 0 /* constant VPN bits, not including entry index bits; 0 if all writable */
896#define XCHAL_DTLB_SET0_PPN_CONSTMASK 0 /* constant PPN bits, including entry index bits; 0 if all writable */
897#define XCHAL_DTLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */
898#define XCHAL_DTLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
899#define XCHAL_DTLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
900#define XCHAL_DTLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
901#define XCHAL_DTLB_SET0_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
902
903/* DTLB way set 1 (group of ways 4 thru 4): */
904#define XCHAL_DTLB_SET1_WAY 4 /* index of first way in this way set */
905#define XCHAL_DTLB_SET1_WAYS 1 /* number of (contiguous) ways in this way set */
906#define XCHAL_DTLB_SET1_ENTRIES_LOG2 2 /* log2(number of entries in this way) */
907#define XCHAL_DTLB_SET1_ENTRIES 4 /* number of entries in this way (always a power of 2) */
908#define XCHAL_DTLB_SET1_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
909#define XCHAL_DTLB_SET1_PAGESIZES 4 /* number of supported page sizes in this way */
910#define XCHAL_DTLB_SET1_PAGESZ_BITS 2 /* number of bits to encode the page size */
911#define XCHAL_DTLB_SET1_PAGESZ_LOG2_MIN 20 /* log2(minimum supported page size) */
912#define XCHAL_DTLB_SET1_PAGESZ_LOG2_MAX 26 /* log2(maximum supported page size) */
913#define XCHAL_DTLB_SET1_PAGESZ_LOG2_LIST 20 XCHAL_SEP 22 XCHAL_SEP 24 XCHAL_SEP 26 /* list of log2(page size)s, separated by XCHAL_SEP;
914 2^PAGESZ_BITS entries in list, unsupported entries are zero */
915#define XCHAL_DTLB_SET1_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */
916#define XCHAL_DTLB_SET1_VPN_CONSTMASK 0 /* constant VPN bits, not including entry index bits; 0 if all writable */
917#define XCHAL_DTLB_SET1_PPN_CONSTMASK 0 /* constant PPN bits, including entry index bits; 0 if all writable */
918#define XCHAL_DTLB_SET1_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */
919#define XCHAL_DTLB_SET1_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
920#define XCHAL_DTLB_SET1_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
921#define XCHAL_DTLB_SET1_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
922#define XCHAL_DTLB_SET1_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
923
924/* DTLB way set 2 (group of ways 5 thru 5): */
925#define XCHAL_DTLB_SET2_WAY 5 /* index of first way in this way set */
926#define XCHAL_DTLB_SET2_WAYS 1 /* number of (contiguous) ways in this way set */
927#define XCHAL_DTLB_SET2_ENTRIES_LOG2 1 /* log2(number of entries in this way) */
928#define XCHAL_DTLB_SET2_ENTRIES 2 /* number of entries in this way (always a power of 2) */
929#define XCHAL_DTLB_SET2_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
930#define XCHAL_DTLB_SET2_PAGESIZES 1 /* number of supported page sizes in this way */
931#define XCHAL_DTLB_SET2_PAGESZ_BITS 0 /* number of bits to encode the page size */
932#define XCHAL_DTLB_SET2_PAGESZ_LOG2_MIN 27 /* log2(minimum supported page size) */
933#define XCHAL_DTLB_SET2_PAGESZ_LOG2_MAX 27 /* log2(maximum supported page size) */
934#define XCHAL_DTLB_SET2_PAGESZ_LOG2_LIST 27 /* list of log2(page size)s, separated by XCHAL_SEP;
935 2^PAGESZ_BITS entries in list, unsupported entries are zero */
936#define XCHAL_DTLB_SET2_ASID_CONSTMASK 0xFF /* constant ASID bits; 0 if all writable */
937#define XCHAL_DTLB_SET2_VPN_CONSTMASK 0xF0000000 /* constant VPN bits, not including entry index bits; 0 if all writable */
938#define XCHAL_DTLB_SET2_PPN_CONSTMASK 0xF8000000 /* constant PPN bits, including entry index bits; 0 if all writable */
939#define XCHAL_DTLB_SET2_CA_CONSTMASK 0x0000000F /* constant CA bits; 0 if all writable */
940#define XCHAL_DTLB_SET2_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
941#define XCHAL_DTLB_SET2_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
942#define XCHAL_DTLB_SET2_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
943#define XCHAL_DTLB_SET2_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
944/* Constant ASID values for each entry of DTLB way set 2 (because ASID_CONSTMASK is non-zero): */
945#define XCHAL_DTLB_SET2_E0_ASID_CONST 0x01
946#define XCHAL_DTLB_SET2_E1_ASID_CONST 0x01
947/* Constant VPN values for each entry of DTLB way set 2 (because VPN_CONSTMASK is non-zero): */
948#define XCHAL_DTLB_SET2_E0_VPN_CONST 0xD0000000
949#define XCHAL_DTLB_SET2_E1_VPN_CONST 0xD8000000
950/* Constant PPN values for each entry of DTLB way set 2 (because PPN_CONSTMASK is non-zero): */
951#define XCHAL_DTLB_SET2_E0_PPN_CONST 0x00000000
952#define XCHAL_DTLB_SET2_E1_PPN_CONST 0x00000000
953/* Constant CA values for each entry of DTLB way set 2 (because CA_CONSTMASK is non-zero): */
954#define XCHAL_DTLB_SET2_E0_CA_CONST 0x07
955#define XCHAL_DTLB_SET2_E1_CA_CONST 0x03
956
957/* DTLB way set 3 (group of ways 6 thru 6): */
958#define XCHAL_DTLB_SET3_WAY 6 /* index of first way in this way set */
959#define XCHAL_DTLB_SET3_WAYS 1 /* number of (contiguous) ways in this way set */
960#define XCHAL_DTLB_SET3_ENTRIES_LOG2 1 /* log2(number of entries in this way) */
961#define XCHAL_DTLB_SET3_ENTRIES 2 /* number of entries in this way (always a power of 2) */
962#define XCHAL_DTLB_SET3_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
963#define XCHAL_DTLB_SET3_PAGESIZES 1 /* number of supported page sizes in this way */
964#define XCHAL_DTLB_SET3_PAGESZ_BITS 0 /* number of bits to encode the page size */
965#define XCHAL_DTLB_SET3_PAGESZ_LOG2_MIN 28 /* log2(minimum supported page size) */
966#define XCHAL_DTLB_SET3_PAGESZ_LOG2_MAX 28 /* log2(maximum supported page size) */
967#define XCHAL_DTLB_SET3_PAGESZ_LOG2_LIST 28 /* list of log2(page size)s, separated by XCHAL_SEP;
968 2^PAGESZ_BITS entries in list, unsupported entries are zero */
969#define XCHAL_DTLB_SET3_ASID_CONSTMASK 0xFF /* constant ASID bits; 0 if all writable */
970#define XCHAL_DTLB_SET3_VPN_CONSTMASK 0xE0000000 /* constant VPN bits, not including entry index bits; 0 if all writable */
971#define XCHAL_DTLB_SET3_PPN_CONSTMASK 0xF0000000 /* constant PPN bits, including entry index bits; 0 if all writable */
972#define XCHAL_DTLB_SET3_CA_CONSTMASK 0x0000000F /* constant CA bits; 0 if all writable */
973#define XCHAL_DTLB_SET3_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
974#define XCHAL_DTLB_SET3_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
975#define XCHAL_DTLB_SET3_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
976#define XCHAL_DTLB_SET3_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
977/* Constant ASID values for each entry of DTLB way set 3 (because ASID_CONSTMASK is non-zero): */
978#define XCHAL_DTLB_SET3_E0_ASID_CONST 0x01
979#define XCHAL_DTLB_SET3_E1_ASID_CONST 0x01
980/* Constant VPN values for each entry of DTLB way set 3 (because VPN_CONSTMASK is non-zero): */
981#define XCHAL_DTLB_SET3_E0_VPN_CONST 0xE0000000
982#define XCHAL_DTLB_SET3_E1_VPN_CONST 0xF0000000
983/* Constant PPN values for each entry of DTLB way set 3 (because PPN_CONSTMASK is non-zero): */
984#define XCHAL_DTLB_SET3_E0_PPN_CONST 0xF0000000
985#define XCHAL_DTLB_SET3_E1_PPN_CONST 0xF0000000
986/* Constant CA values for each entry of DTLB way set 3 (because CA_CONSTMASK is non-zero): */
987#define XCHAL_DTLB_SET3_E0_CA_CONST 0x07
988#define XCHAL_DTLB_SET3_E1_CA_CONST 0x03
989
990/* DTLB way set 4 (group of ways 7 thru 9): */
991#define XCHAL_DTLB_SET4_WAY 7 /* index of first way in this way set */
992#define XCHAL_DTLB_SET4_WAYS 3 /* number of (contiguous) ways in this way set */
993#define XCHAL_DTLB_SET4_ENTRIES_LOG2 0 /* log2(number of entries in this way) */
994#define XCHAL_DTLB_SET4_ENTRIES 1 /* number of entries in this way (always a power of 2) */
995#define XCHAL_DTLB_SET4_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
996#define XCHAL_DTLB_SET4_PAGESIZES 1 /* number of supported page sizes in this way */
997#define XCHAL_DTLB_SET4_PAGESZ_BITS 0 /* number of bits to encode the page size */
998#define XCHAL_DTLB_SET4_PAGESZ_LOG2_MIN 12 /* log2(minimum supported page size) */
999#define XCHAL_DTLB_SET4_PAGESZ_LOG2_MAX 12 /* log2(maximum supported page size) */
1000#define XCHAL_DTLB_SET4_PAGESZ_LOG2_LIST 12 /* list of log2(page size)s, separated by XCHAL_SEP;
1001 2^PAGESZ_BITS entries in list, unsupported entries are zero */
1002#define XCHAL_DTLB_SET4_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */
1003#define XCHAL_DTLB_SET4_VPN_CONSTMASK 0 /* constant VPN bits, not including entry index bits; 0 if all writable */
1004#define XCHAL_DTLB_SET4_PPN_CONSTMASK 0 /* constant PPN bits, including entry index bits; 0 if all writable */
1005#define XCHAL_DTLB_SET4_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */
1006#define XCHAL_DTLB_SET4_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */
1007#define XCHAL_DTLB_SET4_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */
1008#define XCHAL_DTLB_SET4_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */
1009#define XCHAL_DTLB_SET4_CA_RESET 0 /* 1 if CA reset values defined (and all writable); 0 otherwise */
1010
1011/* Indexing macros: */
1012#define _XCHAL_DTLB_SET(n,_what) XCHAL_DTLB_SET ## n ## _what
1013#define XCHAL_DTLB_SET(n,what) _XCHAL_DTLB_SET(n, _ ## what )
1014#define _XCHAL_DTLB_SET_E(n,i,_what) XCHAL_DTLB_SET ## n ## _E ## i ## _what
1015#define XCHAL_DTLB_SET_E(n,i,what) _XCHAL_DTLB_SET_E(n,i, _ ## what )
1016/*
1017 * Example use: XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,ENTRIES)
1018 * to get the value of XCHAL_DTLB_SET<n>_ENTRIES where <n> is the first auto-refill set.
1019 */
1020
1021
1022/*
1023 * Determine whether we have a full MMU (with Page Table and Protection)
1024 * usable for an MMU-based OS:
1025 */
1026#if XCHAL_HAVE_TLBS && !XCHAL_HAVE_SPANNING_WAY && XCHAL_ITLB_ARF_WAYS > 0 && XCHAL_DTLB_ARF_WAYS > 0 && XCHAL_MMU_RINGS >= 2
1027# define XCHAL_HAVE_PTP_MMU 1 /* have full MMU (with page table [autorefill] and protection) */
1028#else
1029# define XCHAL_HAVE_PTP_MMU 0 /* don't have full MMU */
1030#endif
1031
1032/*
1033 * For full MMUs, report kernel RAM segment and kernel I/O segment static page mappings:
1034 */
1035#if XCHAL_HAVE_PTP_MMU
1036#define XCHAL_KSEG_CACHED_VADDR 0xD0000000 /* virt.addr of kernel RAM cached static map */
1037#define XCHAL_KSEG_CACHED_PADDR 0x00000000 /* phys.addr of kseg_cached */
1038#define XCHAL_KSEG_CACHED_SIZE 0x08000000 /* size in bytes of kseg_cached (assumed power of 2!!!) */
1039#define XCHAL_KSEG_BYPASS_VADDR 0xD8000000 /* virt.addr of kernel RAM bypass (uncached) static map */
1040#define XCHAL_KSEG_BYPASS_PADDR 0x00000000 /* phys.addr of kseg_bypass */
1041#define XCHAL_KSEG_BYPASS_SIZE 0x08000000 /* size in bytes of kseg_bypass (assumed power of 2!!!) */
1042
1043#define XCHAL_KIO_CACHED_VADDR 0xE0000000 /* virt.addr of kernel I/O cached static map */
1044#define XCHAL_KIO_CACHED_PADDR 0xF0000000 /* phys.addr of kio_cached */
1045#define XCHAL_KIO_CACHED_SIZE 0x10000000 /* size in bytes of kio_cached (assumed power of 2!!!) */
1046#define XCHAL_KIO_BYPASS_VADDR 0xF0000000 /* virt.addr of kernel I/O bypass (uncached) static map */
1047#define XCHAL_KIO_BYPASS_PADDR 0xF0000000 /* phys.addr of kio_bypass */
1048#define XCHAL_KIO_BYPASS_SIZE 0x10000000 /* size in bytes of kio_bypass (assumed power of 2!!!) */
1049
1050#define XCHAL_SEG_MAPPABLE_VADDR 0x00000000 /* start of largest non-static-mapped virtual addr area */
1051#define XCHAL_SEG_MAPPABLE_SIZE 0xD0000000 /* size in bytes of " */
1052/* define XCHAL_SEG_MAPPABLE2_xxx if more areas present, sorted in order of descending size. */
1053#endif
1054
1055
1056/*----------------------------------------------------------------------
1057 MISC
1058 ----------------------------------------------------------------------*/
1059
1060#define XCHAL_NUM_WRITEBUFFER_ENTRIES 4 /* number of write buffer entries */
1061
1062#define XCHAL_CORE_ID "linux_be" /* configuration's alphanumeric core identifier
1063 (CoreID) set in the Xtensa Processor Generator */
1064
1065#define XCHAL_BUILD_UNIQUE_ID 0x00003256 /* software build-unique ID (22-bit) */
1066
1067/* These definitions describe the hardware targeted by this software: */
1068#define XCHAL_HW_CONFIGID0 0xC103D1FF /* config ID reg 0 value (upper 32 of 64 bits) */
1069#define XCHAL_HW_CONFIGID1 0x00803256 /* config ID reg 1 value (lower 32 of 64 bits) */
1070#define XCHAL_CONFIGID0 XCHAL_HW_CONFIGID0 /* for backward compatibility only -- don't use! */
1071#define XCHAL_CONFIGID1 XCHAL_HW_CONFIGID1 /* for backward compatibility only -- don't use! */
1072#define XCHAL_HW_RELEASE_MAJOR 1050 /* major release of targeted hardware */
1073#define XCHAL_HW_RELEASE_MINOR 1 /* minor release of targeted hardware */
1074#define XCHAL_HW_RELEASE_NAME "T1050.1" /* full release name of targeted hardware */
1075#define XTHAL_HW_REL_T1050 1
1076#define XTHAL_HW_REL_T1050_1 1
1077#define XCHAL_HW_CONFIGID_RELIABLE 1
1078
1079
1080/*
1081 * Miscellaneous special register fields:
1082 */
1083
1084
1085/* DBREAKC (special register number 160): */
1086#define XCHAL_DBREAKC_VALIDMASK 0xC000003F /* bits of DBREAKC that are defined */
1087/* MASK field: */
1088#define XCHAL_DBREAKC_MASK_BITS 6 /* number of bits in MASK field */
1089#define XCHAL_DBREAKC_MASK_NUM 64 /* max number of possible causes (2^bits) */
1090#define XCHAL_DBREAKC_MASK_SHIFT 0 /* position of MASK bits in DBREAKC, starting from lsbit */
1091#define XCHAL_DBREAKC_MASK_MASK 0x0000003F /* mask of bits in MASK field of DBREAKC */
1092/* LOADBREAK field: */
1093#define XCHAL_DBREAKC_LOADBREAK_BITS 1 /* number of bits in LOADBREAK field */
1094#define XCHAL_DBREAKC_LOADBREAK_NUM 2 /* max number of possible causes (2^bits) */
1095#define XCHAL_DBREAKC_LOADBREAK_SHIFT 30 /* position of LOADBREAK bits in DBREAKC, starting from lsbit */
1096#define XCHAL_DBREAKC_LOADBREAK_MASK 0x40000000 /* mask of bits in LOADBREAK field of DBREAKC */
1097/* STOREBREAK field: */
1098#define XCHAL_DBREAKC_STOREBREAK_BITS 1 /* number of bits in STOREBREAK field */
1099#define XCHAL_DBREAKC_STOREBREAK_NUM 2 /* max number of possible causes (2^bits) */
1100#define XCHAL_DBREAKC_STOREBREAK_SHIFT 31 /* position of STOREBREAK bits in DBREAKC, starting from lsbit */
1101#define XCHAL_DBREAKC_STOREBREAK_MASK 0x80000000 /* mask of bits in STOREBREAK field of DBREAKC */
1102
1103/* PS (special register number 230): */
1104#define XCHAL_PS_VALIDMASK 0x00070FFF /* bits of PS that are defined */
1105/* INTLEVEL field: */
1106#define XCHAL_PS_INTLEVEL_BITS 4 /* number of bits in INTLEVEL field */
1107#define XCHAL_PS_INTLEVEL_NUM 16 /* max number of possible causes (2^bits) */
1108#define XCHAL_PS_INTLEVEL_SHIFT 0 /* position of INTLEVEL bits in PS, starting from lsbit */
1109#define XCHAL_PS_INTLEVEL_MASK 0x0000000F /* mask of bits in INTLEVEL field of PS */
1110/* EXCM field: */
1111#define XCHAL_PS_EXCM_BITS 1 /* number of bits in EXCM field */
1112#define XCHAL_PS_EXCM_NUM 2 /* max number of possible causes (2^bits) */
1113#define XCHAL_PS_EXCM_SHIFT 4 /* position of EXCM bits in PS, starting from lsbit */
1114#define XCHAL_PS_EXCM_MASK 0x00000010 /* mask of bits in EXCM field of PS */
1115/* PROGSTACK field: */
1116#define XCHAL_PS_PROGSTACK_BITS 1 /* number of bits in PROGSTACK field */
1117#define XCHAL_PS_PROGSTACK_NUM 2 /* max number of possible causes (2^bits) */
1118#define XCHAL_PS_PROGSTACK_SHIFT 5 /* position of PROGSTACK bits in PS, starting from lsbit */
1119#define XCHAL_PS_PROGSTACK_MASK 0x00000020 /* mask of bits in PROGSTACK field of PS */
1120/* RING field: */
1121#define XCHAL_PS_RING_BITS 2 /* number of bits in RING field */
1122#define XCHAL_PS_RING_NUM 4 /* max number of possible causes (2^bits) */
1123#define XCHAL_PS_RING_SHIFT 6 /* position of RING bits in PS, starting from lsbit */
1124#define XCHAL_PS_RING_MASK 0x000000C0 /* mask of bits in RING field of PS */
1125/* OWB field: */
1126#define XCHAL_PS_OWB_BITS 4 /* number of bits in OWB field */
1127#define XCHAL_PS_OWB_NUM 16 /* max number of possible causes (2^bits) */
1128#define XCHAL_PS_OWB_SHIFT 8 /* position of OWB bits in PS, starting from lsbit */
1129#define XCHAL_PS_OWB_MASK 0x00000F00 /* mask of bits in OWB field of PS */
1130/* CALLINC field: */
1131#define XCHAL_PS_CALLINC_BITS 2 /* number of bits in CALLINC field */
1132#define XCHAL_PS_CALLINC_NUM 4 /* max number of possible causes (2^bits) */
1133#define XCHAL_PS_CALLINC_SHIFT 16 /* position of CALLINC bits in PS, starting from lsbit */
1134#define XCHAL_PS_CALLINC_MASK 0x00030000 /* mask of bits in CALLINC field of PS */
1135/* WOE field: */
1136#define XCHAL_PS_WOE_BITS 1 /* number of bits in WOE field */
1137#define XCHAL_PS_WOE_NUM 2 /* max number of possible causes (2^bits) */
1138#define XCHAL_PS_WOE_SHIFT 18 /* position of WOE bits in PS, starting from lsbit */
1139#define XCHAL_PS_WOE_MASK 0x00040000 /* mask of bits in WOE field of PS */
1140
1141/* EXCCAUSE (special register number 232): */
1142#define XCHAL_EXCCAUSE_VALIDMASK 0x0000003F /* bits of EXCCAUSE that are defined */
1143/* EXCCAUSE field: */
1144#define XCHAL_EXCCAUSE_BITS 6 /* number of bits in EXCCAUSE register */
1145#define XCHAL_EXCCAUSE_NUM 64 /* max number of possible causes (2^bits) */
1146#define XCHAL_EXCCAUSE_SHIFT 0 /* position of EXCCAUSE bits in register, starting from lsbit */
1147#define XCHAL_EXCCAUSE_MASK 0x0000003F /* mask of bits in EXCCAUSE register */
1148
1149/* DEBUGCAUSE (special register number 233): */
1150#define XCHAL_DEBUGCAUSE_VALIDMASK 0x0000003F /* bits of DEBUGCAUSE that are defined */
1151/* ICOUNT field: */
1152#define XCHAL_DEBUGCAUSE_ICOUNT_BITS 1 /* number of bits in ICOUNT field */
1153#define XCHAL_DEBUGCAUSE_ICOUNT_NUM 2 /* max number of possible causes (2^bits) */
1154#define XCHAL_DEBUGCAUSE_ICOUNT_SHIFT 0 /* position of ICOUNT bits in DEBUGCAUSE, starting from lsbit */
1155#define XCHAL_DEBUGCAUSE_ICOUNT_MASK 0x00000001 /* mask of bits in ICOUNT field of DEBUGCAUSE */
1156/* IBREAK field: */
1157#define XCHAL_DEBUGCAUSE_IBREAK_BITS 1 /* number of bits in IBREAK field */
1158#define XCHAL_DEBUGCAUSE_IBREAK_NUM 2 /* max number of possible causes (2^bits) */
1159#define XCHAL_DEBUGCAUSE_IBREAK_SHIFT 1 /* position of IBREAK bits in DEBUGCAUSE, starting from lsbit */
1160#define XCHAL_DEBUGCAUSE_IBREAK_MASK 0x00000002 /* mask of bits in IBREAK field of DEBUGCAUSE */
1161/* DBREAK field: */
1162#define XCHAL_DEBUGCAUSE_DBREAK_BITS 1 /* number of bits in DBREAK field */
1163#define XCHAL_DEBUGCAUSE_DBREAK_NUM 2 /* max number of possible causes (2^bits) */
1164#define XCHAL_DEBUGCAUSE_DBREAK_SHIFT 2 /* position of DBREAK bits in DEBUGCAUSE, starting from lsbit */
1165#define XCHAL_DEBUGCAUSE_DBREAK_MASK 0x00000004 /* mask of bits in DBREAK field of DEBUGCAUSE */
1166/* BREAK field: */
1167#define XCHAL_DEBUGCAUSE_BREAK_BITS 1 /* number of bits in BREAK field */
1168#define XCHAL_DEBUGCAUSE_BREAK_NUM 2 /* max number of possible causes (2^bits) */
1169#define XCHAL_DEBUGCAUSE_BREAK_SHIFT 3 /* position of BREAK bits in DEBUGCAUSE, starting from lsbit */
1170#define XCHAL_DEBUGCAUSE_BREAK_MASK 0x00000008 /* mask of bits in BREAK field of DEBUGCAUSE */
1171/* BREAKN field: */
1172#define XCHAL_DEBUGCAUSE_BREAKN_BITS 1 /* number of bits in BREAKN field */
1173#define XCHAL_DEBUGCAUSE_BREAKN_NUM 2 /* max number of possible causes (2^bits) */
1174#define XCHAL_DEBUGCAUSE_BREAKN_SHIFT 4 /* position of BREAKN bits in DEBUGCAUSE, starting from lsbit */
1175#define XCHAL_DEBUGCAUSE_BREAKN_MASK 0x00000010 /* mask of bits in BREAKN field of DEBUGCAUSE */
1176/* DEBUGINT field: */
1177#define XCHAL_DEBUGCAUSE_DEBUGINT_BITS 1 /* number of bits in DEBUGINT field */
1178#define XCHAL_DEBUGCAUSE_DEBUGINT_NUM 2 /* max number of possible causes (2^bits) */
1179#define XCHAL_DEBUGCAUSE_DEBUGINT_SHIFT 5 /* position of DEBUGINT bits in DEBUGCAUSE, starting from lsbit */
1180#define XCHAL_DEBUGCAUSE_DEBUGINT_MASK 0x00000020 /* mask of bits in DEBUGINT field of DEBUGCAUSE */
1181
1182
1183
1184/*----------------------------------------------------------------------
1185 ISA
1186 ----------------------------------------------------------------------*/
1187
1188#define XCHAL_HAVE_DENSITY 1 /* 1 if density option configured, 0 otherwise */
1189#define XCHAL_HAVE_LOOPS 1 /* 1 if zero-overhead loops option configured, 0 otherwise */
1190/* Misc instructions: */
1191#define XCHAL_HAVE_NSA 0 /* 1 if NSA/NSAU instructions option configured, 0 otherwise */
1192#define XCHAL_HAVE_MINMAX 0 /* 1 if MIN/MAX instructions option configured, 0 otherwise */
1193#define XCHAL_HAVE_SEXT 0 /* 1 if sign-extend instruction option configured, 0 otherwise */
1194#define XCHAL_HAVE_CLAMPS 0 /* 1 if CLAMPS instruction option configured, 0 otherwise */
1195#define XCHAL_HAVE_MAC16 0 /* 1 if MAC16 option configured, 0 otherwise */
1196#define XCHAL_HAVE_MUL16 0 /* 1 if 16-bit integer multiply option configured, 0 otherwise */
1197/*#define XCHAL_HAVE_POPC 0*/ /* 1 if CRC instruction option configured, 0 otherwise */
1198/*#define XCHAL_HAVE_CRC 0*/ /* 1 if POPC instruction option configured, 0 otherwise */
1199
1200#define XCHAL_HAVE_SPECULATION 0 /* 1 if speculation option configured, 0 otherwise */
1201/*#define XCHAL_HAVE_MP_SYNC 0*/ /* 1 if multiprocessor sync. option configured, 0 otherwise */
1202#define XCHAL_HAVE_PRID 0 /* 1 if processor ID register configured, 0 otherwise */
1203
1204#define XCHAL_NUM_MISC_REGS 2 /* number of miscellaneous registers (0..4) */
1205
1206/* These relate a bit more to TIE: */
1207#define XCHAL_HAVE_BOOLEANS 0 /* 1 if booleans option configured, 0 otherwise */
1208#define XCHAL_HAVE_MUL32 0 /* 1 if 32-bit integer multiply option configured, 0 otherwise */
1209#define XCHAL_HAVE_MUL32_HIGH 0 /* 1 if MUL32 option includes MULUH and MULSH, 0 otherwise */
1210#define XCHAL_HAVE_FP 0 /* 1 if floating point option configured, 0 otherwise */
1211
1212
1213/*----------------------------------------------------------------------
1214 DERIVED
1215 ----------------------------------------------------------------------*/
1216
1217#if XCHAL_HAVE_BE
1218#define XCHAL_INST_ILLN 0xD60F /* 2-byte illegal instruction, msb-first */
1219#define XCHAL_INST_ILLN_BYTE0 0xD6 /* 2-byte illegal instruction, 1st byte */
1220#define XCHAL_INST_ILLN_BYTE1 0x0F /* 2-byte illegal instruction, 2nd byte */
1221#else
1222#define XCHAL_INST_ILLN 0xF06D /* 2-byte illegal instruction, lsb-first */
1223#define XCHAL_INST_ILLN_BYTE0 0x6D /* 2-byte illegal instruction, 1st byte */
1224#define XCHAL_INST_ILLN_BYTE1 0xF0 /* 2-byte illegal instruction, 2nd byte */
1225#endif
1226/* Belongs in xtensa/hal.h: */
1227#define XTHAL_INST_ILL 0x000000 /* 3-byte illegal instruction */
1228
1229
1230/*
1231 * Because information as to exactly which hardware release is targeted
1232 * by a given software build is not always available, compile-time HAL
1233 * Hardware-Release "_AT" macros are fuzzy (return 0, 1, or XCHAL_MAYBE):
1234 */
1235#ifndef XCHAL_HW_RELEASE_MAJOR
1236# define XCHAL_HW_CONFIGID_RELIABLE 0
1237#endif
1238#if XCHAL_HW_CONFIGID_RELIABLE
1239# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor) (XTHAL_REL_LE( XCHAL_HW_RELEASE_MAJOR,XCHAL_HW_RELEASE_MINOR, major,minor ) ? 1 : 0)
1240# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor) (XTHAL_REL_GE( XCHAL_HW_RELEASE_MAJOR,XCHAL_HW_RELEASE_MINOR, major,minor ) ? 1 : 0)
1241# define XCHAL_HW_RELEASE_AT(major,minor) (XTHAL_REL_EQ( XCHAL_HW_RELEASE_MAJOR,XCHAL_HW_RELEASE_MINOR, major,minor ) ? 1 : 0)
1242# define XCHAL_HW_RELEASE_MAJOR_AT(major) ((XCHAL_HW_RELEASE_MAJOR == (major)) ? 1 : 0)
1243#else
1244# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor) ( ((major) < 1040 && XCHAL_HAVE_XEA2) ? 0 \
1245 : ((major) > 1050 && XCHAL_HAVE_XEA1) ? 1 \
1246 : XTHAL_MAYBE )
1247# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor) ( ((major) >= 2000 && XCHAL_HAVE_XEA1) ? 0 \
1248 : (XTHAL_REL_LE(major,minor, 1040,0) && XCHAL_HAVE_XEA2) ? 1 \
1249 : XTHAL_MAYBE )
1250# define XCHAL_HW_RELEASE_AT(major,minor) ( (((major) < 1040 && XCHAL_HAVE_XEA2) || \
1251 ((major) >= 2000 && XCHAL_HAVE_XEA1)) ? 0 : XTHAL_MAYBE)
1252# define XCHAL_HW_RELEASE_MAJOR_AT(major) XCHAL_HW_RELEASE_AT(major,0)
1253#endif
1254
1255/*
1256 * Specific errata:
1257 */
1258
1259/*
1260 * Erratum T1020.H13, T1030.H7, T1040.H10, T1050.H4 (fixed in T1040.3 and T1050.1;
1261 * relevant only in XEA1, kernel-vector mode, level-one interrupts and overflows enabled):
1262 */
1263#define XCHAL_MAYHAVE_ERRATUM_XEA1KWIN (XCHAL_HAVE_XEA1 && \
1264 (XCHAL_HW_RELEASE_AT_OR_BELOW(1040,2) != 0 \
1265 || XCHAL_HW_RELEASE_AT(1050,0)))
1266
1267
1268
1269#endif /*XTENSA_CONFIG_CORE_H*/
1270
diff --git a/include/asm-xtensa/xtensa/config-linux_be/defs.h b/include/asm-xtensa/xtensa/config-linux_be/defs.h
new file mode 100644
index 000000000000..f7c58b273371
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/defs.h
@@ -0,0 +1,270 @@
1/* Definitions for Xtensa instructions, types, and protos. */
2
3/*
4 * Copyright (c) 2003 Tensilica, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2.1 of the GNU Lesser General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it would be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * Further, this software is distributed without any warranty that it is
15 * free of the rightful claim of any third person regarding infringement
16 * or the like. Any license provided herein, whether implied or
17 * otherwise, applies only to this software file. Patent licenses, if
18 * any, provided herein do not apply to combinations of this program with
19 * other software, or any other product whatsoever.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
24 * USA.
25 */
26
27/* Do not modify. This is automatically generated.*/
28
29#ifndef _XTENSA_BASE_HEADER
30#define _XTENSA_BASE_HEADER
31
32#ifdef __XTENSA__
33#if defined(__GNUC__) && !defined(__XCC__)
34
35#define L8UI_ASM(arr, ars, imm) { \
36 __asm__ volatile("l8ui %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
37}
38
39#define XT_L8UI(ars, imm) \
40({ \
41 unsigned char _arr; \
42 const unsigned char *_ars = ars; \
43 L8UI_ASM(_arr, _ars, imm); \
44 _arr; \
45})
46
47#define L16UI_ASM(arr, ars, imm) { \
48 __asm__ volatile("l16ui %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
49}
50
51#define XT_L16UI(ars, imm) \
52({ \
53 unsigned short _arr; \
54 const unsigned short *_ars = ars; \
55 L16UI_ASM(_arr, _ars, imm); \
56 _arr; \
57})
58
59#define L16SI_ASM(arr, ars, imm) {\
60 __asm__ volatile("l16si %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
61}
62
63#define XT_L16SI(ars, imm) \
64({ \
65 signed short _arr; \
66 const signed short *_ars = ars; \
67 L16SI_ASM(_arr, _ars, imm); \
68 _arr; \
69})
70
71#define L32I_ASM(arr, ars, imm) { \
72 __asm__ volatile("l32i %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
73}
74
75#define XT_L32I(ars, imm) \
76({ \
77 unsigned _arr; \
78 const unsigned *_ars = ars; \
79 L32I_ASM(_arr, _ars, imm); \
80 _arr; \
81})
82
83#define S8I_ASM(arr, ars, imm) {\
84 __asm__ volatile("s8i %0, %1, %2" : : "a" (arr), "a" (ars) , "i" (imm) : "memory" ); \
85}
86
87#define XT_S8I(arr, ars, imm) \
88({ \
89 signed char _arr = arr; \
90 const signed char *_ars = ars; \
91 S8I_ASM(_arr, _ars, imm); \
92})
93
94#define S16I_ASM(arr, ars, imm) {\
95 __asm__ volatile("s16i %0, %1, %2" : : "a" (arr), "a" (ars) , "i" (imm) : "memory" ); \
96}
97
98#define XT_S16I(arr, ars, imm) \
99({ \
100 signed short _arr = arr; \
101 const signed short *_ars = ars; \
102 S16I_ASM(_arr, _ars, imm); \
103})
104
105#define S32I_ASM(arr, ars, imm) { \
106 __asm__ volatile("s32i %0, %1, %2" : : "a" (arr), "a" (ars) , "i" (imm) : "memory" ); \
107}
108
109#define XT_S32I(arr, ars, imm) \
110({ \
111 signed int _arr = arr; \
112 const signed int *_ars = ars; \
113 S32I_ASM(_arr, _ars, imm); \
114})
115
116#define ADDI_ASM(art, ars, imm) {\
117 __asm__ ("addi %0, %1, %2" : "=a" (art) : "a" (ars), "i" (imm)); \
118}
119
120#define XT_ADDI(ars, imm) \
121({ \
122 unsigned _art; \
123 unsigned _ars = ars; \
124 ADDI_ASM(_art, _ars, imm); \
125 _art; \
126})
127
128#define ABS_ASM(arr, art) {\
129 __asm__ ("abs %0, %1" : "=a" (arr) : "a" (art)); \
130}
131
132#define XT_ABS(art) \
133({ \
134 unsigned _arr; \
135 signed _art = art; \
136 ABS_ASM(_arr, _art); \
137 _arr; \
138})
139
140/* Note: In the following macros that reference SAR, the magic "state"
141 register is used to capture the dependency on SAR. This is because
142 SAR is a 5-bit register and thus there are no C types that can be
143 used to represent it. It doesn't appear that the SAR register is
144 even relevant to GCC, but it is marked as "clobbered" just in
145 case. */
146
147#define SRC_ASM(arr, ars, art) {\
148 register int _xt_sar __asm__ ("state"); \
149 __asm__ ("src %0, %1, %2" \
150 : "=a" (arr) : "a" (ars), "a" (art), "t" (_xt_sar)); \
151}
152
153#define XT_SRC(ars, art) \
154({ \
155 unsigned _arr; \
156 unsigned _ars = ars; \
157 unsigned _art = art; \
158 SRC_ASM(_arr, _ars, _art); \
159 _arr; \
160})
161
162#define SSR_ASM(ars) {\
163 register int _xt_sar __asm__ ("state"); \
164 __asm__ ("ssr %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
165}
166
167#define XT_SSR(ars) \
168({ \
169 unsigned _ars = ars; \
170 SSR_ASM(_ars); \
171})
172
173#define SSL_ASM(ars) {\
174 register int _xt_sar __asm__ ("state"); \
175 __asm__ ("ssl %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
176}
177
178#define XT_SSL(ars) \
179({ \
180 unsigned _ars = ars; \
181 SSL_ASM(_ars); \
182})
183
184#define SSA8B_ASM(ars) {\
185 register int _xt_sar __asm__ ("state"); \
186 __asm__ ("ssa8b %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
187}
188
189#define XT_SSA8B(ars) \
190({ \
191 unsigned _ars = ars; \
192 SSA8B_ASM(_ars); \
193})
194
195#define SSA8L_ASM(ars) {\
196 register int _xt_sar __asm__ ("state"); \
197 __asm__ ("ssa8l %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
198}
199
200#define XT_SSA8L(ars) \
201({ \
202 unsigned _ars = ars; \
203 SSA8L_ASM(_ars); \
204})
205
206#define SSAI_ASM(imm) {\
207 register int _xt_sar __asm__ ("state"); \
208 __asm__ ("ssai %1" : "=t" (_xt_sar) : "i" (imm) : "sar"); \
209}
210
211#define XT_SSAI(imm) \
212({ \
213 SSAI_ASM(imm); \
214})
215
216
217
218
219
220
221
222
223#endif /* __GNUC__ && !__XCC__ */
224
225#ifdef __XCC__
226
227/* Core load/store instructions */
228extern unsigned char _TIE_L8UI(const unsigned char * ars, immediate imm);
229extern unsigned short _TIE_L16UI(const unsigned short * ars, immediate imm);
230extern signed short _TIE_L16SI(const signed short * ars, immediate imm);
231extern unsigned _TIE_L32I(const unsigned * ars, immediate imm);
232extern void _TIE_S8I(unsigned char arr, unsigned char * ars, immediate imm);
233extern void _TIE_S16I(unsigned short arr, unsigned short * ars, immediate imm);
234extern void _TIE_S32I(unsigned arr, unsigned * ars, immediate imm);
235
236#define XT_L8UI _TIE_L8UI
237#define XT_L16UI _TIE_L16UI
238#define XT_L16SI _TIE_L16SI
239#define XT_L32I _TIE_L32I
240#define XT_S8I _TIE_S8I
241#define XT_S16I _TIE_S16I
242#define XT_S32I _TIE_S32I
243
244/* Add-immediate instruction */
245extern unsigned _TIE_ADDI(unsigned ars, immediate imm);
246#define XT_ADDI _TIE_ADDI
247
248/* Absolute value instruction */
249extern unsigned _TIE_ABS(int art);
250#define XT_ABS _TIE_ABS
251
252/* funnel shift instructions */
253extern unsigned _TIE_SRC(unsigned ars, unsigned art);
254#define XT_SRC _TIE_SRC
255extern void _TIE_SSR(unsigned ars);
256#define XT_SSR _TIE_SSR
257extern void _TIE_SSL(unsigned ars);
258#define XT_SSL _TIE_SSL
259extern void _TIE_SSA8B(unsigned ars);
260#define XT_SSA8B _TIE_SSA8B
261extern void _TIE_SSA8L(unsigned ars);
262#define XT_SSA8L _TIE_SSA8L
263extern void _TIE_SSAI(immediate imm);
264#define XT_SSAI _TIE_SSAI
265
266
267#endif /* __XCC__ */
268
269#endif /* __XTENSA__ */
270#endif /* !_XTENSA_BASE_HEADER */
diff --git a/include/asm-xtensa/xtensa/config-linux_be/specreg.h b/include/asm-xtensa/xtensa/config-linux_be/specreg.h
new file mode 100644
index 000000000000..fa4106aa9a02
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/specreg.h
@@ -0,0 +1,99 @@
1/*
2 * Xtensa Special Register symbolic names
3 */
4
5/* $Id: specreg.h,v 1.2 2003/03/07 19:15:18 joetaylor Exp $ */
6
7/*
8 * Copyright (c) 2003 Tensilica, Inc. All Rights Reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2.1 of the GNU Lesser General Public
12 * License as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it would be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 *
18 * Further, this software is distributed without any warranty that it is
19 * free of the rightful claim of any third person regarding infringement
20 * or the like. Any license provided herein, whether implied or
21 * otherwise, applies only to this software file. Patent licenses, if
22 * any, provided herein do not apply to combinations of this program with
23 * other software, or any other product whatsoever.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this program; if not, write the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
28 * USA.
29 */
30
31#ifndef XTENSA_SPECREG_H
32#define XTENSA_SPECREG_H
33
34/* Include these special register bitfield definitions, for historical reasons: */
35#include <xtensa/corebits.h>
36
37
38/* Special registers: */
39#define LBEG 0
40#define LEND 1
41#define LCOUNT 2
42#define SAR 3
43#define WINDOWBASE 72
44#define WINDOWSTART 73
45#define PTEVADDR 83
46#define RASID 90
47#define ITLBCFG 91
48#define DTLBCFG 92
49#define IBREAKENABLE 96
50#define DDR 104
51#define IBREAKA_0 128
52#define IBREAKA_1 129
53#define DBREAKA_0 144
54#define DBREAKA_1 145
55#define DBREAKC_0 160
56#define DBREAKC_1 161
57#define EPC_1 177
58#define EPC_2 178
59#define EPC_3 179
60#define EPC_4 180
61#define DEPC 192
62#define EPS_2 194
63#define EPS_3 195
64#define EPS_4 196
65#define EXCSAVE_1 209
66#define EXCSAVE_2 210
67#define EXCSAVE_3 211
68#define EXCSAVE_4 212
69#define INTERRUPT 226
70#define INTENABLE 228
71#define PS 230
72#define EXCCAUSE 232
73#define DEBUGCAUSE 233
74#define CCOUNT 234
75#define ICOUNT 236
76#define ICOUNTLEVEL 237
77#define EXCVADDR 238
78#define CCOMPARE_0 240
79#define CCOMPARE_1 241
80#define CCOMPARE_2 242
81#define MISC_REG_0 244
82#define MISC_REG_1 245
83
84/* Special cases (bases of special register series): */
85#define IBREAKA 128
86#define DBREAKA 144
87#define DBREAKC 160
88#define EPC 176
89#define EPS 192
90#define EXCSAVE 208
91#define CCOMPARE 240
92
93/* Special names for read-only and write-only interrupt registers: */
94#define INTREAD 226
95#define INTSET 226
96#define INTCLEAR 227
97
98#endif /* XTENSA_SPECREG_H */
99
diff --git a/include/asm-xtensa/xtensa/config-linux_be/system.h b/include/asm-xtensa/xtensa/config-linux_be/system.h
new file mode 100644
index 000000000000..cf9d4d308e3a
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/system.h
@@ -0,0 +1,198 @@
1/*
2 * xtensa/config/system.h -- HAL definitions that are dependent on SYSTEM configuration
3 *
4 * NOTE: The location and contents of this file are highly subject to change.
5 *
6 * Source for configuration-independent binaries (which link in a
7 * configuration-specific HAL library) must NEVER include this file.
8 * The HAL itself has historically included this file in some instances,
9 * but this is not appropriate either, because the HAL is meant to be
10 * core-specific but system independent.
11 */
12
13/*
14 * Copyright (c) 2003 Tensilica, Inc. All Rights Reserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of version 2.1 of the GNU Lesser General Public
18 * License as published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it would be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 *
24 * Further, this software is distributed without any warranty that it is
25 * free of the rightful claim of any third person regarding infringement
26 * or the like. Any license provided herein, whether implied or
27 * otherwise, applies only to this software file. Patent licenses, if
28 * any, provided herein do not apply to combinations of this program with
29 * other software, or any other product whatsoever.
30 *
31 * You should have received a copy of the GNU Lesser General Public
32 * License along with this program; if not, write the Free Software
33 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
34 * USA.
35 */
36
37
38#ifndef XTENSA_CONFIG_SYSTEM_H
39#define XTENSA_CONFIG_SYSTEM_H
40
41/*#include <xtensa/hal.h>*/
42
43
44
45/*----------------------------------------------------------------------
46 DEVICE ADDRESSES
47 ----------------------------------------------------------------------*/
48
49/*
50 * Strange place to find these, but the configuration GUI
51 * allows moving these around to account for various core
52 * configurations. Specific boards (and their BSP software)
53 * will have specific meanings for these components.
54 */
55
56/* I/O Block areas: */
57#define XSHAL_IOBLOCK_CACHED_VADDR 0xE0000000
58#define XSHAL_IOBLOCK_CACHED_PADDR 0xF0000000
59#define XSHAL_IOBLOCK_CACHED_SIZE 0x0E000000
60
61#define XSHAL_IOBLOCK_BYPASS_VADDR 0xF0000000
62#define XSHAL_IOBLOCK_BYPASS_PADDR 0xF0000000
63#define XSHAL_IOBLOCK_BYPASS_SIZE 0x0E000000
64
65/* System ROM: */
66#define XSHAL_ROM_VADDR 0xEE000000
67#define XSHAL_ROM_PADDR 0xFE000000
68#define XSHAL_ROM_SIZE 0x00400000
69/* Largest available area (free of vectors): */
70#define XSHAL_ROM_AVAIL_VADDR 0xEE00052C
71#define XSHAL_ROM_AVAIL_VSIZE 0x003FFAD4
72
73/* System RAM: */
74#define XSHAL_RAM_VADDR 0xD0000000
75#define XSHAL_RAM_PADDR 0x00000000
76#define XSHAL_RAM_VSIZE 0x08000000
77#define XSHAL_RAM_PSIZE 0x10000000
78#define XSHAL_RAM_SIZE XSHAL_RAM_PSIZE
79/* Largest available area (free of vectors): */
80#define XSHAL_RAM_AVAIL_VADDR 0xD0000370
81#define XSHAL_RAM_AVAIL_VSIZE 0x07FFFC90
82
83/*
84 * Shadow system RAM (same device as system RAM, at different address).
85 * (Emulation boards need this for the SONIC Ethernet driver
86 * when data caches are configured for writeback mode.)
87 * NOTE: on full MMU configs, this points to the BYPASS virtual address
88 * of system RAM, ie. is the same as XSHAL_RAM_* except that virtual
89 * addresses are viewed through the BYPASS static map rather than
90 * the CACHED static map.
91 */
92#define XSHAL_RAM_BYPASS_VADDR 0xD8000000
93#define XSHAL_RAM_BYPASS_PADDR 0x00000000
94#define XSHAL_RAM_BYPASS_PSIZE 0x08000000
95
96/* Alternate system RAM (different device than system RAM): */
97#define XSHAL_ALTRAM_VADDR 0xCEE00000
98#define XSHAL_ALTRAM_PADDR 0xC0000000
99#define XSHAL_ALTRAM_SIZE 0x00200000
100
101
102/*----------------------------------------------------------------------
103 * DEVICE-ADDRESS DEPENDENT...
104 *
105 * Values written to CACHEATTR special register (or its equivalent)
106 * to enable and disable caches in various modes.
107 *----------------------------------------------------------------------*/
108
109/*----------------------------------------------------------------------
110 BACKWARD COMPATIBILITY ...
111 ----------------------------------------------------------------------*/
112
113/*
114 * NOTE: the following two macros are DEPRECATED. Use the latter
115 * board-specific macros instead, which are specially tuned for the
116 * particular target environments' memory maps.
117 */
118#define XSHAL_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS /* disable caches in bypass mode */
119#define XSHAL_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT /* default setting to enable caches (no writeback!) */
120
121/*----------------------------------------------------------------------
122 ISS (Instruction Set Simulator) SPECIFIC ...
123 ----------------------------------------------------------------------*/
124
125#define XSHAL_ISS_CACHEATTR_WRITEBACK 0x1122222F /* enable caches in write-back mode */
126#define XSHAL_ISS_CACHEATTR_WRITEALLOC 0x1122222F /* enable caches in write-allocate mode */
127#define XSHAL_ISS_CACHEATTR_WRITETHRU 0x1122222F /* enable caches in write-through mode */
128#define XSHAL_ISS_CACHEATTR_BYPASS 0x2222222F /* disable caches in bypass mode */
129#define XSHAL_ISS_CACHEATTR_DEFAULT XSHAL_ISS_CACHEATTR_WRITEBACK /* default setting to enable caches */
130
131/* For Coware only: */
132#define XSHAL_COWARE_CACHEATTR_WRITEBACK 0x11222222 /* enable caches in write-back mode */
133#define XSHAL_COWARE_CACHEATTR_WRITEALLOC 0x11222222 /* enable caches in write-allocate mode */
134#define XSHAL_COWARE_CACHEATTR_WRITETHRU 0x11222222 /* enable caches in write-through mode */
135#define XSHAL_COWARE_CACHEATTR_BYPASS 0x22222222 /* disable caches in bypass mode */
136#define XSHAL_COWARE_CACHEATTR_DEFAULT XSHAL_COWARE_CACHEATTR_WRITEBACK /* default setting to enable caches */
137
138/* For BFM and other purposes: */
139#define XSHAL_ALLVALID_CACHEATTR_WRITEBACK 0x11222222 /* enable caches without any invalid regions */
140#define XSHAL_ALLVALID_CACHEATTR_DEFAULT XSHAL_ALLVALID_CACHEATTR_WRITEBACK /* default setting for caches without any invalid regions */
141
142#define XSHAL_ISS_PIPE_REGIONS 0
143#define XSHAL_ISS_SDRAM_REGIONS 0
144
145
146/*----------------------------------------------------------------------
147 XT2000 BOARD SPECIFIC ...
148 ----------------------------------------------------------------------*/
149
150#define XSHAL_XT2000_CACHEATTR_WRITEBACK 0x22FFFFFF /* enable caches in write-back mode */
151#define XSHAL_XT2000_CACHEATTR_WRITEALLOC 0x22FFFFFF /* enable caches in write-allocate mode */
152#define XSHAL_XT2000_CACHEATTR_WRITETHRU 0x22FFFFFF /* enable caches in write-through mode */
153#define XSHAL_XT2000_CACHEATTR_BYPASS 0x22FFFFFF /* disable caches in bypass mode */
154#define XSHAL_XT2000_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_WRITEBACK /* default setting to enable caches */
155
156#define XSHAL_XT2000_PIPE_REGIONS 0x00001000 /* BusInt pipeline regions */
157#define XSHAL_XT2000_SDRAM_REGIONS 0x00000005 /* BusInt SDRAM regions */
158
159
160/*----------------------------------------------------------------------
161 VECTOR SIZES
162 ----------------------------------------------------------------------*/
163
164/*
165 * Sizes allocated to vectors by the system (memory map) configuration.
166 * These sizes are constrained by core configuration (eg. one vector's
167 * code cannot overflow into another vector) but are dependent on the
168 * system or board (or LSP) memory map configuration.
169 *
170 * Whether or not each vector happens to be in a system ROM is also
171 * a system configuration matter, sometimes useful, included here also:
172 */
173#define XSHAL_RESET_VECTOR_SIZE 0x000004E0
174#define XSHAL_RESET_VECTOR_ISROM 1
175#define XSHAL_USER_VECTOR_SIZE 0x0000001C
176#define XSHAL_USER_VECTOR_ISROM 0
177#define XSHAL_PROGRAMEXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */
178#define XSHAL_USEREXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */
179#define XSHAL_KERNEL_VECTOR_SIZE 0x0000001C
180#define XSHAL_KERNEL_VECTOR_ISROM 0
181#define XSHAL_STACKEDEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */
182#define XSHAL_KERNELEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */
183#define XSHAL_DOUBLEEXC_VECTOR_SIZE 0x000000E0
184#define XSHAL_DOUBLEEXC_VECTOR_ISROM 0
185#define XSHAL_WINDOW_VECTORS_SIZE 0x00000180
186#define XSHAL_WINDOW_VECTORS_ISROM 0
187#define XSHAL_INTLEVEL2_VECTOR_SIZE 0x0000000C
188#define XSHAL_INTLEVEL2_VECTOR_ISROM 0
189#define XSHAL_INTLEVEL3_VECTOR_SIZE 0x0000000C
190#define XSHAL_INTLEVEL3_VECTOR_ISROM 0
191#define XSHAL_INTLEVEL4_VECTOR_SIZE 0x0000000C
192#define XSHAL_INTLEVEL4_VECTOR_ISROM 1
193#define XSHAL_DEBUG_VECTOR_SIZE XSHAL_INTLEVEL4_VECTOR_SIZE
194#define XSHAL_DEBUG_VECTOR_ISROM XSHAL_INTLEVEL4_VECTOR_ISROM
195
196
197#endif /*XTENSA_CONFIG_SYSTEM_H*/
198
diff --git a/include/asm-xtensa/xtensa/config-linux_be/tie.h b/include/asm-xtensa/xtensa/config-linux_be/tie.h
new file mode 100644
index 000000000000..3c2e514602f4
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/tie.h
@@ -0,0 +1,275 @@
1/*
2 * xtensa/config/tie.h -- HAL definitions that are dependent on CORE and TIE configuration
3 *
4 * This header file is sometimes referred to as the "compile-time HAL" or CHAL.
5 * It was generated for a specific Xtensa processor configuration,
6 * and furthermore for a specific set of TIE source files that extend
7 * basic core functionality.
8 *
9 * Source for configuration-independent binaries (which link in a
10 * configuration-specific HAL library) must NEVER include this file.
11 * It is perfectly normal, however, for the HAL source itself to include this file.
12 */
13
14/*
15 * Copyright (c) 2003 Tensilica, Inc. All Rights Reserved.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of version 2.1 of the GNU Lesser General Public
19 * License as published by the Free Software Foundation.
20 *
21 * This program is distributed in the hope that it would be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 *
25 * Further, this software is distributed without any warranty that it is
26 * free of the rightful claim of any third person regarding infringement
27 * or the like. Any license provided herein, whether implied or
28 * otherwise, applies only to this software file. Patent licenses, if
29 * any, provided herein do not apply to combinations of this program with
30 * other software, or any other product whatsoever.
31 *
32 * You should have received a copy of the GNU Lesser General Public
33 * License along with this program; if not, write the Free Software
34 * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
35 * USA.
36 */
37
38
39#ifndef XTENSA_CONFIG_TIE_H
40#define XTENSA_CONFIG_TIE_H
41
42#include <xtensa/hal.h>
43
44
45/*----------------------------------------------------------------------
46 GENERAL
47 ----------------------------------------------------------------------*/
48
49/*
50 * Separators for macros that expand into arrays.
51 * These can be predefined by files that #include this one,
52 * when different separators are required.
53 */
54/* Element separator for macros that expand into 1-dimensional arrays: */
55#ifndef XCHAL_SEP
56#define XCHAL_SEP ,
57#endif
58/* Array separator for macros that expand into 2-dimensional arrays: */
59#ifndef XCHAL_SEP2
60#define XCHAL_SEP2 },{
61#endif
62
63
64
65
66
67
68/*----------------------------------------------------------------------
69 COPROCESSORS and EXTRA STATE
70 ----------------------------------------------------------------------*/
71
72#define XCHAL_CP_NUM 0 /* number of coprocessors */
73#define XCHAL_CP_MAX 0 /* max coprocessor id plus one (0 if none) */
74#define XCHAL_CP_MASK 0x00 /* bitmask of coprocessors by id */
75
76/* Space for coprocessors' state save areas: */
77#define XCHAL_CP0_SA_SIZE 0
78#define XCHAL_CP1_SA_SIZE 0
79#define XCHAL_CP2_SA_SIZE 0
80#define XCHAL_CP3_SA_SIZE 0
81#define XCHAL_CP4_SA_SIZE 0
82#define XCHAL_CP5_SA_SIZE 0
83#define XCHAL_CP6_SA_SIZE 0
84#define XCHAL_CP7_SA_SIZE 0
85/* Minimum required alignments of CP state save areas: */
86#define XCHAL_CP0_SA_ALIGN 1
87#define XCHAL_CP1_SA_ALIGN 1
88#define XCHAL_CP2_SA_ALIGN 1
89#define XCHAL_CP3_SA_ALIGN 1
90#define XCHAL_CP4_SA_ALIGN 1
91#define XCHAL_CP5_SA_ALIGN 1
92#define XCHAL_CP6_SA_ALIGN 1
93#define XCHAL_CP7_SA_ALIGN 1
94
95/* Indexing macros: */
96#define _XCHAL_CP_SA_SIZE(n) XCHAL_CP ## n ## _SA_SIZE
97#define XCHAL_CP_SA_SIZE(n) _XCHAL_CP_SA_SIZE(n) /* n = 0 .. 7 */
98#define _XCHAL_CP_SA_ALIGN(n) XCHAL_CP ## n ## _SA_ALIGN
99#define XCHAL_CP_SA_ALIGN(n) _XCHAL_CP_SA_ALIGN(n) /* n = 0 .. 7 */
100
101
102/* Space for "extra" state (user special registers and non-cp TIE) save area: */
103#define XCHAL_EXTRA_SA_SIZE 0
104#define XCHAL_EXTRA_SA_ALIGN 1
105
106/* Total save area size (extra + all coprocessors) */
107/* (not useful until xthal_{save,restore}_all_extra() is implemented, */
108/* but included for Tor2 beta; doesn't account for alignment!): */
109#define XCHAL_CPEXTRA_SA_SIZE_TOR2 0 /* Tor2Beta temporary definition -- do not use */
110
111/* Combined required alignment for all CP and EXTRA state save areas */
112/* (does not include required alignment for any base config registers): */
113#define XCHAL_CPEXTRA_SA_ALIGN 1
114
115/* ... */
116
117
118#ifdef _ASMLANGUAGE
119/*
120 * Assembly-language specific definitions (assembly macros, etc.).
121 */
122#include <xtensa/config/specreg.h>
123
124/********************
125 * Macros to save and restore the non-coprocessor TIE portion of EXTRA state.
126 */
127
128/* (none) */
129
130
131/********************
132 * Macros to create functions that save and restore all EXTRA (non-coprocessor) state
133 * (does not include zero-overhead loop registers and non-optional registers).
134 */
135
136 /*
137 * Macro that expands to the body of a function that
138 * stores the extra (non-coprocessor) optional/custom state.
139 * Entry: a2 = ptr to save area in which to save extra state
140 * Exit: any register a2-a15 (?) may have been clobbered.
141 */
142 .macro xchal_extra_store_funcbody
143 .endm
144
145
146 /*
147 * Macro that expands to the body of a function that
148 * loads the extra (non-coprocessor) optional/custom state.
149 * Entry: a2 = ptr to save area from which to restore extra state
150 * Exit: any register a2-a15 (?) may have been clobbered.
151 */
152 .macro xchal_extra_load_funcbody
153 .endm
154
155
156/********************
157 * Macros to save and restore the state of each TIE coprocessor.
158 */
159
160
161
162/********************
163 * Macros to create functions that save and restore the state of *any* TIE coprocessor.
164 */
165
166 /*
167 * Macro that expands to the body of a function
168 * that stores the selected coprocessor's state (registers etc).
169 * Entry: a2 = ptr to save area in which to save cp state
170 * a3 = coprocessor number
171 * Exit: any register a2-a15 (?) may have been clobbered.
172 */
173 .macro xchal_cpi_store_funcbody
174 .endm
175
176
177 /*
178 * Macro that expands to the body of a function
179 * that loads the selected coprocessor's state (registers etc).
180 * Entry: a2 = ptr to save area from which to restore cp state
181 * a3 = coprocessor number
182 * Exit: any register a2-a15 (?) may have been clobbered.
183 */
184 .macro xchal_cpi_load_funcbody
185 .endm
186
187#endif /*_ASMLANGUAGE*/
188
189
190/*
191 * Contents of save areas in terms of libdb register numbers.
192 * NOTE: CONTENTS_LIBDB_{UREG,REGF} macros are not defined in this file;
193 * it is up to the user of this header file to define these macros
194 * usefully before each expansion of the CONTENTS_LIBDB macros.
195 * (Fields rsv[123] are reserved for future additions; they are currently
196 * set to zero but may be set to some useful values in the future.)
197 *
198 * CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum, bitmask, rsv2, rsv3)
199 * CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum, bitmask, rsv2, rsv3)
200 * CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, numentries, contentsize, regname_base, regfile_name, rsv2, rsv3)
201 */
202
203#define XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM 0
204#define XCHAL_EXTRA_SA_CONTENTS_LIBDB /* empty */
205
206#define XCHAL_CP0_SA_CONTENTS_LIBDB_NUM 0
207#define XCHAL_CP0_SA_CONTENTS_LIBDB /* empty */
208
209#define XCHAL_CP1_SA_CONTENTS_LIBDB_NUM 0
210#define XCHAL_CP1_SA_CONTENTS_LIBDB /* empty */
211
212#define XCHAL_CP2_SA_CONTENTS_LIBDB_NUM 0
213#define XCHAL_CP2_SA_CONTENTS_LIBDB /* empty */
214
215#define XCHAL_CP3_SA_CONTENTS_LIBDB_NUM 0
216#define XCHAL_CP3_SA_CONTENTS_LIBDB /* empty */
217
218#define XCHAL_CP4_SA_CONTENTS_LIBDB_NUM 0
219#define XCHAL_CP4_SA_CONTENTS_LIBDB /* empty */
220
221#define XCHAL_CP5_SA_CONTENTS_LIBDB_NUM 0
222#define XCHAL_CP5_SA_CONTENTS_LIBDB /* empty */
223
224#define XCHAL_CP6_SA_CONTENTS_LIBDB_NUM 0
225#define XCHAL_CP6_SA_CONTENTS_LIBDB /* empty */
226
227#define XCHAL_CP7_SA_CONTENTS_LIBDB_NUM 0
228#define XCHAL_CP7_SA_CONTENTS_LIBDB /* empty */
229
230
231
232
233
234
235/*----------------------------------------------------------------------
236 MISC
237 ----------------------------------------------------------------------*/
238
239#if 0 /* is there something equivalent for user TIE? */
240#define XCHAL_CORE_ID "linux_be" /* configuration's alphanumeric core identifier
241 (CoreID) set in the Xtensa Processor Generator */
242
243#define XCHAL_BUILD_UNIQUE_ID 0x00003256 /* software build-unique ID (22-bit) */
244
245/* These definitions describe the hardware targeted by this software: */
246#define XCHAL_HW_CONFIGID0 0xC103D1FF /* config ID reg 0 value (upper 32 of 64 bits) */
247#define XCHAL_HW_CONFIGID1 0x00803256 /* config ID reg 1 value (lower 32 of 64 bits) */
248#define XCHAL_CONFIGID0 XCHAL_HW_CONFIGID0 /* for backward compatibility only -- don't use! */
249#define XCHAL_CONFIGID1 XCHAL_HW_CONFIGID1 /* for backward compatibility only -- don't use! */
250#define XCHAL_HW_RELEASE_MAJOR 1050 /* major release of targeted hardware */
251#define XCHAL_HW_RELEASE_MINOR 1 /* minor release of targeted hardware */
252#define XCHAL_HW_RELEASE_NAME "T1050.1" /* full release name of targeted hardware */
253#define XTHAL_HW_REL_T1050 1
254#define XTHAL_HW_REL_T1050_1 1
255#define XCHAL_HW_CONFIGID_RELIABLE 1
256#endif /*0*/
257
258
259
260/*----------------------------------------------------------------------
261 ISA
262 ----------------------------------------------------------------------*/
263
264#if 0 /* these probably don't belong here, but are related to or implemented using TIE */
265#define XCHAL_HAVE_BOOLEANS 0 /* 1 if booleans option configured, 0 otherwise */
266/* Misc instructions: */
267#define XCHAL_HAVE_MUL32 0 /* 1 if 32-bit integer multiply option configured, 0 otherwise */
268#define XCHAL_HAVE_MUL32_HIGH 0 /* 1 if MUL32 option includes MULUH and MULSH, 0 otherwise */
269
270#define XCHAL_HAVE_FP 0 /* 1 if floating point option configured, 0 otherwise */
271#endif /*0*/
272
273
274#endif /*XTENSA_CONFIG_TIE_H*/
275
diff --git a/include/asm-xtensa/xtensa/coreasm.h b/include/asm-xtensa/xtensa/coreasm.h
new file mode 100644
index 000000000000..a8cfb54c20a1
--- /dev/null
+++ b/include/asm-xtensa/xtensa/coreasm.h
@@ -0,0 +1,526 @@
1#ifndef XTENSA_COREASM_H
2#define XTENSA_COREASM_H
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * include/asm-xtensa/xtensa/coreasm.h -- assembler-specific
8 * definitions that depend on CORE configuration.
9 *
10 * Source for configuration-independent binaries (which link in a
11 * configuration-specific HAL library) must NEVER include this file.
12 * It is perfectly normal, however, for the HAL itself to include this
13 * file.
14 *
15 * This file must NOT include xtensa/config/system.h. Any assembler
16 * header file that depends on system information should likely go in
17 * a new systemasm.h (or sysasm.h) header file.
18 *
19 * NOTE: macro beqi32 is NOT configuration-dependent, and is placed
20 * here til we will have configuration-independent header file.
21 *
22 * This file is subject to the terms and conditions of the GNU General
23 * Public License. See the file "COPYING" in the main directory of
24 * this archive for more details.
25 *
26 * Copyright (C) 2002 Tensilica Inc.
27 */
28
29
30#include <xtensa/config/core.h>
31#include <xtensa/config/specreg.h>
32
33/*
34 * Assembly-language specific definitions (assembly macros, etc.).
35 */
36
37/*----------------------------------------------------------------------
38 * find_ms_setbit
39 *
40 * This macro finds the most significant bit that is set in <as>
41 * and return its index + <base> in <ad>, or <base> - 1 if <as> is zero.
42 * The index counts starting at zero for the lsbit, so the return
43 * value ranges from <base>-1 (no bit set) to <base>+31 (msbit set).
44 *
45 * Parameters:
46 * <ad> destination address register (any register)
47 * <as> source address register
48 * <at> temporary address register (must be different than <as>)
49 * <base> constant value added to result (usually 0 or 1)
50 * On entry:
51 * <ad> = undefined if different than <as>
52 * <as> = value whose most significant set bit is to be found
53 * <at> = undefined
54 * no other registers are used by this macro.
55 * On exit:
56 * <ad> = <base> + index of msbit set in original <as>,
57 * = <base> - 1 if original <as> was zero.
58 * <as> clobbered (if not <ad>)
59 * <at> clobbered (if not <ad>)
60 * Example:
61 * find_ms_setbit a0, a4, a0, 0 -- return in a0 index of msbit set in a4
62 */
63
64 .macro find_ms_setbit ad, as, at, base
65#if XCHAL_HAVE_NSA
66 movi \at, 31+\base
67 nsau \as, \as // get index of \as, numbered from msbit (32 if absent)
68 sub \ad, \at, \as // get numbering from lsbit (0..31, -1 if absent)
69#else /* XCHAL_HAVE_NSA */
70 movi \at, \base // start with result of 0 (point to lsbit of 32)
71
72 beqz \as, 2f // special case for zero argument: return -1
73 bltui \as, 0x10000, 1f // is it one of the 16 lsbits? (if so, check lower 16 bits)
74 addi \at, \at, 16 // no, increment result to upper 16 bits (of 32)
75 //srli \as, \as, 16 // check upper half (shift right 16 bits)
76 extui \as, \as, 16, 16 // check upper half (shift right 16 bits)
771: bltui \as, 0x100, 1f // is it one of the 8 lsbits? (if so, check lower 8 bits)
78 addi \at, \at, 8 // no, increment result to upper 8 bits (of 16)
79 srli \as, \as, 8 // shift right to check upper 8 bits
801: bltui \as, 0x10, 1f // is it one of the 4 lsbits? (if so, check lower 4 bits)
81 addi \at, \at, 4 // no, increment result to upper 4 bits (of 8)
82 srli \as, \as, 4 // shift right 4 bits to check upper half
831: bltui \as, 0x4, 1f // is it one of the 2 lsbits? (if so, check lower 2 bits)
84 addi \at, \at, 2 // no, increment result to upper 2 bits (of 4)
85 srli \as, \as, 2 // shift right 2 bits to check upper half
861: bltui \as, 0x2, 1f // is it the lsbit?
87 addi \at, \at, 2 // no, increment result to upper bit (of 2)
882: addi \at, \at, -1 // (from just above: add 1; from beqz: return -1)
89 //srli \as, \as, 1
901: // done! \at contains index of msbit set (or -1 if none set)
91 .if 0x\ad - 0x\at // destination different than \at ? (works because regs are a0-a15)
92 mov \ad, \at // then move result to \ad
93 .endif
94#endif /* XCHAL_HAVE_NSA */
95 .endm // find_ms_setbit
96
97/*----------------------------------------------------------------------
98 * find_ls_setbit
99 *
100 * This macro finds the least significant bit that is set in <as>,
101 * and return its index in <ad>.
102 * Usage is the same as for the find_ms_setbit macro.
103 * Example:
104 * find_ls_setbit a0, a4, a0, 0 -- return in a0 index of lsbit set in a4
105 */
106
107 .macro find_ls_setbit ad, as, at, base
108 neg \at, \as // keep only the least-significant bit that is set...
109 and \as, \at, \as // ... in \as
110 find_ms_setbit \ad, \as, \at, \base
111 .endm // find_ls_setbit
112
113/*----------------------------------------------------------------------
114 * find_ls_one
115 *
116 * Same as find_ls_setbit with base zero.
117 * Source (as) and destination (ad) registers must be different.
118 * Provided for backward compatibility.
119 */
120
121 .macro find_ls_one ad, as
122 find_ls_setbit \ad, \as, \ad, 0
123 .endm // find_ls_one
124
125/*----------------------------------------------------------------------
126 * floop, floopnez, floopgtz, floopend
127 *
128 * These macros are used for fast inner loops that
129 * work whether or not the Loops options is configured.
130 * If the Loops option is configured, they simply use
131 * the zero-overhead LOOP instructions; otherwise
132 * they use explicit decrement and branch instructions.
133 *
134 * They are used in pairs, with floop, floopnez or floopgtz
135 * at the beginning of the loop, and floopend at the end.
136 *
137 * Each pair of loop macro calls must be given the loop count
138 * address register and a unique label for that loop.
139 *
140 * Example:
141 *
142 * movi a3, 16 // loop 16 times
143 * floop a3, myloop1
144 * :
145 * bnez a7, end1 // exit loop if a7 != 0
146 * :
147 * floopend a3, myloop1
148 * end1:
149 *
150 * Like the LOOP instructions, these macros cannot be
151 * nested, must include at least one instruction,
152 * cannot call functions inside the loop, etc.
153 * The loop can be exited by jumping to the instruction
154 * following floopend (or elsewhere outside the loop),
155 * or continued by jumping to a NOP instruction placed
156 * immediately before floopend.
157 *
158 * Unlike LOOP instructions, the register passed to floop*
159 * cannot be used inside the loop, because it is used as
160 * the loop counter if the Loops option is not configured.
161 * And its value is undefined after exiting the loop.
162 * And because the loop counter register is active inside
163 * the loop, you can't easily use this construct to loop
164 * across a register file using ROTW as you might with LOOP
165 * instructions, unless you copy the loop register along.
166 */
167
168 /* Named label version of the macros: */
169
170 .macro floop ar, endlabel
171 floop_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
172 .endm
173
174 .macro floopnez ar, endlabel
175 floopnez_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
176 .endm
177
178 .macro floopgtz ar, endlabel
179 floopgtz_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
180 .endm
181
182 .macro floopend ar, endlabel
183 floopend_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
184 .endm
185
186 /* Numbered local label version of the macros: */
187#if 0 /*UNTESTED*/
188 .macro floop89 ar
189 floop_ \ar, 8, 9f
190 .endm
191
192 .macro floopnez89 ar
193 floopnez_ \ar, 8, 9f
194 .endm
195
196 .macro floopgtz89 ar
197 floopgtz_ \ar, 8, 9f
198 .endm
199
200 .macro floopend89 ar
201 floopend_ \ar, 8b, 9
202 .endm
203#endif /*0*/
204
205 /* Underlying version of the macros: */
206
207 .macro floop_ ar, startlabel, endlabelref
208 .ifdef _infloop_
209 .if _infloop_
210 .err // Error: floop cannot be nested
211 .endif
212 .endif
213 .set _infloop_, 1
214#if XCHAL_HAVE_LOOPS
215 loop \ar, \endlabelref
216#else /* XCHAL_HAVE_LOOPS */
217\startlabel:
218 addi \ar, \ar, -1
219#endif /* XCHAL_HAVE_LOOPS */
220 .endm // floop_
221
222 .macro floopnez_ ar, startlabel, endlabelref
223 .ifdef _infloop_
224 .if _infloop_
225 .err // Error: floopnez cannot be nested
226 .endif
227 .endif
228 .set _infloop_, 1
229#if XCHAL_HAVE_LOOPS
230 loopnez \ar, \endlabelref
231#else /* XCHAL_HAVE_LOOPS */
232 beqz \ar, \endlabelref
233\startlabel:
234 addi \ar, \ar, -1
235#endif /* XCHAL_HAVE_LOOPS */
236 .endm // floopnez_
237
238 .macro floopgtz_ ar, startlabel, endlabelref
239 .ifdef _infloop_
240 .if _infloop_
241 .err // Error: floopgtz cannot be nested
242 .endif
243 .endif
244 .set _infloop_, 1
245#if XCHAL_HAVE_LOOPS
246 loopgtz \ar, \endlabelref
247#else /* XCHAL_HAVE_LOOPS */
248 bltz \ar, \endlabelref
249 beqz \ar, \endlabelref
250\startlabel:
251 addi \ar, \ar, -1
252#endif /* XCHAL_HAVE_LOOPS */
253 .endm // floopgtz_
254
255
256 .macro floopend_ ar, startlabelref, endlabel
257 .ifndef _infloop_
258 .err // Error: floopend without matching floopXXX
259 .endif
260 .ifeq _infloop_
261 .err // Error: floopend without matching floopXXX
262 .endif
263 .set _infloop_, 0
264#if ! XCHAL_HAVE_LOOPS
265 bnez \ar, \startlabelref
266#endif /* XCHAL_HAVE_LOOPS */
267\endlabel:
268 .endm // floopend_
269
270/*----------------------------------------------------------------------
271 * crsil -- conditional RSIL (read/set interrupt level)
272 *
273 * Executes the RSIL instruction if it exists, else just reads PS.
274 * The RSIL instruction does not exist in the new exception architecture
275 * if the interrupt option is not selected.
276 */
277
278 .macro crsil ar, newlevel
279#if XCHAL_HAVE_OLD_EXC_ARCH || XCHAL_HAVE_INTERRUPTS
280 rsil \ar, \newlevel
281#else
282 rsr \ar, PS
283#endif
284 .endm // crsil
285
286/*----------------------------------------------------------------------
287 * window_spill{4,8,12}
288 *
289 * These macros spill callers' register windows to the stack.
290 * They work for both privileged and non-privileged tasks.
291 * Must be called from a windowed ABI context, eg. within
292 * a windowed ABI function (ie. valid stack frame, window
293 * exceptions enabled, not in exception mode, etc).
294 *
295 * This macro requires a single invocation of the window_spill_common
296 * macro in the same assembly unit and section.
297 *
298 * Note that using window_spill{4,8,12} macros is more efficient
299 * than calling a function implemented using window_spill_function,
300 * because the latter needs extra code to figure out the size of
301 * the call to the spilling function.
302 *
303 * Example usage:
304 *
305 * .text
306 * .align 4
307 * .global some_function
308 * .type some_function,@function
309 * some_function:
310 * entry a1, 16
311 * :
312 * :
313 *
314 * window_spill4 // spill windows of some_function's callers; preserves a0..a3 only;
315 * // to use window_spill{8,12} in this example function we'd have
316 * // to increase space allocated by the entry instruction, because
317 * // 16 bytes only allows call4; 32 or 48 bytes (+locals) are needed
318 * // for call8/window_spill8 or call12/window_spill12 respectively.
319 * :
320 *
321 * retw
322 *
323 * window_spill_common // instantiates code used by window_spill4
324 *
325 *
326 * On entry:
327 * none (if window_spill4)
328 * stack frame has enough space allocated for call8 (if window_spill8)
329 * stack frame has enough space allocated for call12 (if window_spill12)
330 * On exit:
331 * a4..a15 clobbered (if window_spill4)
332 * a8..a15 clobbered (if window_spill8)
333 * a12..a15 clobbered (if window_spill12)
334 * no caller windows are in live registers
335 */
336
337 .macro window_spill4
338#if XCHAL_HAVE_WINDOWED
339# if XCHAL_NUM_AREGS == 16
340 movi a15, 0 // for 16-register files, no need to call to reach the end
341# elif XCHAL_NUM_AREGS == 32
342 call4 .L__wdwspill_assist28 // call deep enough to clear out any live callers
343# elif XCHAL_NUM_AREGS == 64
344 call4 .L__wdwspill_assist60 // call deep enough to clear out any live callers
345# endif
346#endif
347 .endm // window_spill4
348
349 .macro window_spill8
350#if XCHAL_HAVE_WINDOWED
351# if XCHAL_NUM_AREGS == 16
352 movi a15, 0 // for 16-register files, no need to call to reach the end
353# elif XCHAL_NUM_AREGS == 32
354 call8 .L__wdwspill_assist24 // call deep enough to clear out any live callers
355# elif XCHAL_NUM_AREGS == 64
356 call8 .L__wdwspill_assist56 // call deep enough to clear out any live callers
357# endif
358#endif
359 .endm // window_spill8
360
361 .macro window_spill12
362#if XCHAL_HAVE_WINDOWED
363# if XCHAL_NUM_AREGS == 16
364 movi a15, 0 // for 16-register files, no need to call to reach the end
365# elif XCHAL_NUM_AREGS == 32
366 call12 .L__wdwspill_assist20 // call deep enough to clear out any live callers
367# elif XCHAL_NUM_AREGS == 64
368 call12 .L__wdwspill_assist52 // call deep enough to clear out any live callers
369# endif
370#endif
371 .endm // window_spill12
372
373/*----------------------------------------------------------------------
374 * window_spill_function
375 *
376 * This macro outputs a function that will spill its caller's callers'
377 * register windows to the stack. Eg. it could be used to implement
378 * a version of xthal_window_spill() that works in non-privileged tasks.
379 * This works for both privileged and non-privileged tasks.
380 *
381 * Typical usage:
382 *
383 * .text
384 * .align 4
385 * .global my_spill_function
386 * .type my_spill_function,@function
387 * my_spill_function:
388 * window_spill_function
389 *
390 * On entry to resulting function:
391 * none
392 * On exit from resulting function:
393 * none (no caller windows are in live registers)
394 */
395
396 .macro window_spill_function
397#if XCHAL_HAVE_WINDOWED
398# if XCHAL_NUM_AREGS == 32
399 entry sp, 48
400 bbci.l a0, 31, 1f // branch if called with call4
401 bbsi.l a0, 30, 2f // branch if called with call12
402 call8 .L__wdwspill_assist16 // called with call8, only need another 8
403 retw
4041: call12 .L__wdwspill_assist16 // called with call4, only need another 12
405 retw
4062: call4 .L__wdwspill_assist16 // called with call12, only need another 4
407 retw
408# elif XCHAL_NUM_AREGS == 64
409 entry sp, 48
410 bbci.l a0, 31, 1f // branch if called with call4
411 bbsi.l a0, 30, 2f // branch if called with call12
412 call4 .L__wdwspill_assist52 // called with call8, only need a call4
413 retw
4141: call8 .L__wdwspill_assist52 // called with call4, only need a call8
415 retw
4162: call12 .L__wdwspill_assist40 // called with call12, can skip a call12
417 retw
418# elif XCHAL_NUM_AREGS == 16
419 entry sp, 16
420 bbci.l a0, 31, 1f // branch if called with call4
421 bbsi.l a0, 30, 2f // branch if called with call12
422 movi a7, 0 // called with call8
423 retw
4241: movi a11, 0 // called with call4
4252: retw // if called with call12, everything already spilled
426
427// movi a15, 0 // trick to spill all but the direct caller
428// j 1f
429// // The entry instruction is magical in the assembler (gets auto-aligned)
430// // so we have to jump to it to avoid falling through the padding.
431// // We need entry/retw to know where to return.
432//1: entry sp, 16
433// retw
434# else
435# error "unrecognized address register file size"
436# endif
437#endif /* XCHAL_HAVE_WINDOWED */
438 window_spill_common
439 .endm // window_spill_function
440
441/*----------------------------------------------------------------------
442 * window_spill_common
443 *
444 * Common code used by any number of invocations of the window_spill##
445 * and window_spill_function macros.
446 *
447 * Must be instantiated exactly once within a given assembly unit,
448 * within call/j range of and same section as window_spill##
449 * macro invocations for that assembly unit.
450 * (Is automatically instantiated by the window_spill_function macro.)
451 */
452
453 .macro window_spill_common
454#if XCHAL_HAVE_WINDOWED && (XCHAL_NUM_AREGS == 32 || XCHAL_NUM_AREGS == 64)
455 .ifndef .L__wdwspill_defined
456# if XCHAL_NUM_AREGS >= 64
457.L__wdwspill_assist60:
458 entry sp, 32
459 call8 .L__wdwspill_assist52
460 retw
461.L__wdwspill_assist56:
462 entry sp, 16
463 call4 .L__wdwspill_assist52
464 retw
465.L__wdwspill_assist52:
466 entry sp, 48
467 call12 .L__wdwspill_assist40
468 retw
469.L__wdwspill_assist40:
470 entry sp, 48
471 call12 .L__wdwspill_assist28
472 retw
473# endif
474.L__wdwspill_assist28:
475 entry sp, 48
476 call12 .L__wdwspill_assist16
477 retw
478.L__wdwspill_assist24:
479 entry sp, 32
480 call8 .L__wdwspill_assist16
481 retw
482.L__wdwspill_assist20:
483 entry sp, 16
484 call4 .L__wdwspill_assist16
485 retw
486.L__wdwspill_assist16:
487 entry sp, 16
488 movi a15, 0
489 retw
490 .set .L__wdwspill_defined, 1
491 .endif
492#endif /* XCHAL_HAVE_WINDOWED with 32 or 64 aregs */
493 .endm // window_spill_common
494
495/*----------------------------------------------------------------------
496 * beqi32
497 *
498 * macro implements version of beqi for arbitrary 32-bit immidiate value
499 *
500 * beqi32 ax, ay, imm32, label
501 *
502 * Compares value in register ax with imm32 value and jumps to label if
503 * equal. Clobberes register ay if needed
504 *
505 */
506 .macro beqi32 ax, ay, imm, label
507 .ifeq ((\imm-1) & ~7) // 1..8 ?
508 beqi \ax, \imm, \label
509 .else
510 .ifeq (\imm+1) // -1 ?
511 beqi \ax, \imm, \label
512 .else
513 .ifeq (\imm) // 0 ?
514 beqz \ax, \label
515 .else
516 // We could also handle immediates 10,12,16,32,64,128,256
517 // but it would be a long macro...
518 movi \ay, \imm
519 beq \ax, \ay, \label
520 .endif
521 .endif
522 .endif
523 .endm // beqi32
524
525#endif /*XTENSA_COREASM_H*/
526
diff --git a/include/asm-xtensa/xtensa/corebits.h b/include/asm-xtensa/xtensa/corebits.h
new file mode 100644
index 000000000000..e578ade41632
--- /dev/null
+++ b/include/asm-xtensa/xtensa/corebits.h
@@ -0,0 +1,77 @@
1#ifndef XTENSA_COREBITS_H
2#define XTENSA_COREBITS_H
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * xtensa/corebits.h - Xtensa Special Register field positions and masks.
8 *
9 * (In previous releases, these were defined in specreg.h, a generated file.
10 * This file is not generated, i.e. it is processor configuration independent.)
11 */
12
13
14/* EXCCAUSE register fields: */
15#define EXCCAUSE_EXCCAUSE_SHIFT 0
16#define EXCCAUSE_EXCCAUSE_MASK 0x3F
17/* Exception causes (mostly incomplete!): */
18#define EXCCAUSE_ILLEGAL 0
19#define EXCCAUSE_SYSCALL 1
20#define EXCCAUSE_IFETCHERROR 2
21#define EXCCAUSE_LOADSTOREERROR 3
22#define EXCCAUSE_LEVEL1INTERRUPT 4
23#define EXCCAUSE_ALLOCA 5
24
25/* PS register fields: */
26#define PS_WOE_SHIFT 18
27#define PS_WOE_MASK 0x00040000
28#define PS_WOE PS_WOE_MASK
29#define PS_CALLINC_SHIFT 16
30#define PS_CALLINC_MASK 0x00030000
31#define PS_CALLINC(n) (((n)&3)<<PS_CALLINC_SHIFT) /* n = 0..3 */
32#define PS_OWB_SHIFT 8
33#define PS_OWB_MASK 0x00000F00
34#define PS_OWB(n) (((n)&15)<<PS_OWB_SHIFT) /* n = 0..15 (or 0..7) */
35#define PS_RING_SHIFT 6
36#define PS_RING_MASK 0x000000C0
37#define PS_RING(n) (((n)&3)<<PS_RING_SHIFT) /* n = 0..3 */
38#define PS_UM_SHIFT 5
39#define PS_UM_MASK 0x00000020
40#define PS_UM PS_UM_MASK
41#define PS_EXCM_SHIFT 4
42#define PS_EXCM_MASK 0x00000010
43#define PS_EXCM PS_EXCM_MASK
44#define PS_INTLEVEL_SHIFT 0
45#define PS_INTLEVEL_MASK 0x0000000F
46#define PS_INTLEVEL(n) ((n)&PS_INTLEVEL_MASK) /* n = 0..15 */
47/* Backward compatibility (deprecated): */
48#define PS_PROGSTACK_SHIFT PS_UM_SHIFT
49#define PS_PROGSTACK_MASK PS_UM_MASK
50#define PS_PROG_SHIFT PS_UM_SHIFT
51#define PS_PROG_MASK PS_UM_MASK
52#define PS_PROG PS_UM
53
54/* DBREAKCn register fields: */
55#define DBREAKC_MASK_SHIFT 0
56#define DBREAKC_MASK_MASK 0x0000003F
57#define DBREAKC_LOADBREAK_SHIFT 30
58#define DBREAKC_LOADBREAK_MASK 0x40000000
59#define DBREAKC_STOREBREAK_SHIFT 31
60#define DBREAKC_STOREBREAK_MASK 0x80000000
61
62/* DEBUGCAUSE register fields: */
63#define DEBUGCAUSE_DEBUGINT_SHIFT 5
64#define DEBUGCAUSE_DEBUGINT_MASK 0x20 /* debug interrupt */
65#define DEBUGCAUSE_BREAKN_SHIFT 4
66#define DEBUGCAUSE_BREAKN_MASK 0x10 /* BREAK.N instruction */
67#define DEBUGCAUSE_BREAK_SHIFT 3
68#define DEBUGCAUSE_BREAK_MASK 0x08 /* BREAK instruction */
69#define DEBUGCAUSE_DBREAK_SHIFT 2
70#define DEBUGCAUSE_DBREAK_MASK 0x04 /* DBREAK match */
71#define DEBUGCAUSE_IBREAK_SHIFT 1
72#define DEBUGCAUSE_IBREAK_MASK 0x02 /* IBREAK match */
73#define DEBUGCAUSE_ICOUNT_SHIFT 0
74#define DEBUGCAUSE_ICOUNT_MASK 0x01 /* ICOUNT would increment to zero */
75
76#endif /*XTENSA_COREBITS_H*/
77
diff --git a/include/asm-xtensa/xtensa/hal.h b/include/asm-xtensa/xtensa/hal.h
new file mode 100644
index 000000000000..d10472505454
--- /dev/null
+++ b/include/asm-xtensa/xtensa/hal.h
@@ -0,0 +1,822 @@
1#ifndef XTENSA_HAL_H
2#define XTENSA_HAL_H
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * include/asm-xtensa/xtensa/hal.h -- contains a definition of the
8 * Core HAL interface.
9 *
10 * All definitions in this header file are independent of any specific
11 * Xtensa processor configuration. Thus an OS or other software can
12 * include this header file and be compiled into configuration-
13 * independent objects that can be distributed and eventually linked
14 * to the HAL library (libhal.a) to create a configuration-specific
15 * final executable.
16 *
17 * Certain definitions, however, are release-specific -- such as the
18 * XTHAL_RELEASE_xxx macros (or additions made in later releases).
19 *
20 * This file is subject to the terms and conditions of the GNU General Public
21 * License. See the file "COPYING" in the main directory of this archive
22 * for more details.
23 *
24 * Copyright (C) 2002 Tensilica Inc.
25 */
26
27
28/*----------------------------------------------------------------------
29 Constant Definitions
30 (shared with assembly)
31 ----------------------------------------------------------------------*/
32
33/* Software release information (not configuration-specific!): */
34#define XTHAL_RELEASE_MAJOR 1050
35#define XTHAL_RELEASE_MINOR 0
36#define XTHAL_RELEASE_NAME "T1050.0-2002-08-06-eng0"
37#define XTHAL_RELEASE_INTERNAL "2002-08-06-eng0"
38#define XTHAL_REL_T1050 1
39#define XTHAL_REL_T1050_0 1
40#define XTHAL_REL_T1050_0_2002 1
41#define XTHAL_REL_T1050_0_2002_08 1
42#define XTHAL_REL_T1050_0_2002_08_06 1
43#define XTHAL_REL_T1050_0_2002_08_06_ENG0 1
44
45/* HAL version numbers (these names are for backward compatibility): */
46#define XTHAL_MAJOR_REV XTHAL_RELEASE_MAJOR
47#define XTHAL_MINOR_REV XTHAL_RELEASE_MINOR
48/*
49 * A bit of software release history on values of XTHAL_{MAJOR,MINOR}_REV:
50 *
51 * Release MAJOR MINOR Comment
52 * ======= ===== ===== =======
53 * T1015.n n/a n/a (HAL not yet available)
54 * T1020.{0,1,2} 0 1 (HAL beta)
55 * T1020.{3,4} 0 2 First release.
56 * T1020.n (n>4) 0 2 or >3 (TBD)
57 * T1030.0 0 1 (HAL beta)
58 * T1030.{1,2} 0 3 Equivalent to first release.
59 * T1030.n (n>=3) 0 >= 3 (TBD)
60 * T1040.n 1040 n Full CHAL available from T1040.2
61 * T1050.n 1050 n Current release.
62 *
63 *
64 * Note: there is a distinction between the software release with
65 * which something is compiled (accessible using XTHAL_RELEASE_* macros)
66 * and the software release with which the HAL library was compiled
67 * (accessible using Xthal_release_* global variables). This
68 * distinction is particularly relevant for vendors that distribute
69 * configuration-independent binaries (eg. an OS), where their customer
70 * might link it with a HAL of a different Xtensa software release.
71 * In this case, it may be appropriate for the OS to verify at run-time
72 * whether XTHAL_RELEASE_* and Xthal_release_* are compatible.
73 * [Guidelines as to which release is compatible with which are not
74 * currently provided explicitly, but might be inferred from reading
75 * OSKit documentation for all releases -- compatibility is also highly
76 * dependent on which HAL features are used. Each release is usually
77 * backward compatible, with very few exceptions if any.]
78 *
79 * Notes:
80 * Tornado 2.0 supported in T1020.3+, T1030.1+, and T1040.{0,1} only.
81 * Tornado 2.0.2 supported in T1040.2+, and T1050.
82 * Compile-time HAL port of NucleusPlus supported by T1040.2+ and T1050.
83 */
84
85
86/*
87 * Architectural limits, independent of configuration.
88 * Note that these are ISA-defined limits, not micro-architecture implementation
89 * limits enforced by the Xtensa Processor Generator (which may be stricter than
90 * these below).
91 */
92#define XTHAL_MAX_CPS 8 /* max number of coprocessors (0..7) */
93#define XTHAL_MAX_INTERRUPTS 32 /* max number of interrupts (0..31) */
94#define XTHAL_MAX_INTLEVELS 16 /* max number of interrupt levels (0..15) */
95 /* (as of T1040, implementation limit is 7: 0..6) */
96#define XTHAL_MAX_TIMERS 4 /* max number of timers (CCOMPARE0..CCOMPARE3) */
97 /* (as of T1040, implementation limit is 3: 0..2) */
98
99/* Misc: */
100#define XTHAL_LITTLEENDIAN 0
101#define XTHAL_BIGENDIAN 1
102
103
104/* Interrupt types: */
105#define XTHAL_INTTYPE_UNCONFIGURED 0
106#define XTHAL_INTTYPE_SOFTWARE 1
107#define XTHAL_INTTYPE_EXTERN_EDGE 2
108#define XTHAL_INTTYPE_EXTERN_LEVEL 3
109#define XTHAL_INTTYPE_TIMER 4
110#define XTHAL_INTTYPE_NMI 5
111#define XTHAL_MAX_INTTYPES 6 /* number of interrupt types */
112
113/* Timer related: */
114#define XTHAL_TIMER_UNCONFIGURED -1 /* Xthal_timer_interrupt[] value for non-existent timers */
115#define XTHAL_TIMER_UNASSIGNED XTHAL_TIMER_UNCONFIGURED /* (for backwards compatibility only) */
116
117
118/* Access Mode bits (tentative): */ /* bit abbr unit short_name PPC equ - Description */
119#define XTHAL_AMB_EXCEPTION 0 /* 001 E EX fls: EXception none - generate exception on any access (aka "illegal") */
120#define XTHAL_AMB_HITCACHE 1 /* 002 C CH fls: use Cache on Hit ~(I CI) - use cache on hit -- way from tag match [or H HC, or U UC] (ISA: same, except for Isolate case) */
121#define XTHAL_AMB_ALLOCATE 2 /* 004 A AL fl?: ALlocate none - refill cache on miss -- way from LRU [or F FI fill] (ISA: Read/Write Miss Refill) */
122#define XTHAL_AMB_WRITETHRU 3 /* 008 W WT --s: WriteThrough W WT - store immediately to memory (ISA: same) */
123#define XTHAL_AMB_ISOLATE 4 /* 010 I IS fls: ISolate none - use cache regardless of hit-vs-miss -- way from vaddr (ISA: use-cache-on-miss+hit) */
124#define XTHAL_AMB_GUARD 5 /* 020 G GU ?l?: GUard G * - non-speculative; spec/replay refs not permitted */
125#if 0
126#define XTHAL_AMB_ORDERED x /* 000 O OR fls: ORdered G * - mem accesses cannot be out of order */
127#define XTHAL_AMB_FUSEWRITES x /* 000 F FW --s: FuseWrites none - allow combining/merging multiple writes (to same datapath data unit) into one (implied by writeback) */
128#define XTHAL_AMB_COHERENT x /* 000 M MC fl?: Mem/MP Coherent M - on reads, other CPUs/bus-masters may need to supply data */
129#define XTHAL_AMB_TRUSTED x /* 000 T TR ?l?: TRusted none - memory will not bus error (if it does, handle as fatal imprecise interrupt) */
130#define XTHAL_AMB_PREFETCH x /* 000 P PR fl?: PRefetch none - on refill, read line+1 into prefetch buffers */
131#define XTHAL_AMB_STREAM x /* 000 S ST ???: STreaming none - access one of N stream buffers */
132#endif /*0*/
133
134#define XTHAL_AM_EXCEPTION (1<<XTHAL_AMB_EXCEPTION)
135#define XTHAL_AM_HITCACHE (1<<XTHAL_AMB_HITCACHE)
136#define XTHAL_AM_ALLOCATE (1<<XTHAL_AMB_ALLOCATE)
137#define XTHAL_AM_WRITETHRU (1<<XTHAL_AMB_WRITETHRU)
138#define XTHAL_AM_ISOLATE (1<<XTHAL_AMB_ISOLATE)
139#define XTHAL_AM_GUARD (1<<XTHAL_AMB_GUARD)
140#if 0
141#define XTHAL_AM_ORDERED (1<<XTHAL_AMB_ORDERED)
142#define XTHAL_AM_FUSEWRITES (1<<XTHAL_AMB_FUSEWRITES)
143#define XTHAL_AM_COHERENT (1<<XTHAL_AMB_COHERENT)
144#define XTHAL_AM_TRUSTED (1<<XTHAL_AMB_TRUSTED)
145#define XTHAL_AM_PREFETCH (1<<XTHAL_AMB_PREFETCH)
146#define XTHAL_AM_STREAM (1<<XTHAL_AMB_STREAM)
147#endif /*0*/
148
149/*
150 * Allowed Access Modes (bit combinations).
151 *
152 * Columns are:
153 * "FOGIWACE"
154 * Access mode bits (see XTHAL_AMB_xxx above).
155 * <letter> = bit is set
156 * '-' = bit is clear
157 * '.' = bit is irrelevant / don't care, as follows:
158 * E=1 makes all others irrelevant
159 * W,F relevant only for stores
160 * "2345"
161 * Indicates which Xtensa releases support the corresponding
162 * access mode. Releases for each character column are:
163 * 2 = prior to T1020.2: T1015 (V1.5), T1020.0, T1020.1
164 * 3 = T1020.2 and later: T1020.2+, T1030
165 * 4 = T1040
166 * 5 = T1050 (maybe)
167 * And the character column contents are:
168 * <number> = support by release(s)
169 * "." = unsupported by release(s)
170 * "?" = support unknown
171 */
172 /* FOGIWACE 2345 */
173/* For instruction fetch: */
174#define XTHAL_FAM_EXCEPTION 0x001 /* .......E 2345 exception */
175#define XTHAL_FAM_ISOLATE 0x012 /* .--I.-C- .... isolate */
176#define XTHAL_FAM_BYPASS 0x000 /* .---.--- 2345 bypass */
177#define XTHAL_FAM_NACACHED 0x002 /* .---.-C- .... cached no-allocate (frozen) */
178#define XTHAL_FAM_CACHED 0x006 /* .---.AC- 2345 cached */
179/* For data load: */
180#define XTHAL_LAM_EXCEPTION 0x001 /* .......E 2345 exception */
181#define XTHAL_LAM_ISOLATE 0x012 /* .--I.-C- 2345 isolate */
182#define XTHAL_LAM_BYPASS 0x000 /* .O--.--- 2... bypass speculative */
183#define XTHAL_LAM_BYPASSG 0x020 /* .OG-.--- .345 bypass guarded */
184#define XTHAL_LAM_NACACHED 0x002 /* .O--.-C- 2... cached no-allocate speculative */
185#define XTHAL_LAM_NACACHEDG 0x022 /* .OG-.-C- .345 cached no-allocate guarded */
186#define XTHAL_LAM_CACHED 0x006 /* .---.AC- 2345 cached speculative */
187#define XTHAL_LAM_CACHEDG 0x026 /* .?G-.AC- .... cached guarded */
188/* For data store: */
189#define XTHAL_SAM_EXCEPTION 0x001 /* .......E 2345 exception */
190#define XTHAL_SAM_ISOLATE 0x032 /* .-GI--C- 2345 isolate */
191#define XTHAL_SAM_BYPASS 0x028 /* -OG-W--- 2345 bypass */
192/*efine XTHAL_SAM_BYPASSF 0x028*/ /* F-G-W--- ...? bypass write-combined */
193#define XTHAL_SAM_WRITETHRU 0x02A /* -OG-W-C- 234? writethrough */
194/*efine XTHAL_SAM_WRITETHRUF 0x02A*/ /* F-G-W-C- ...5 writethrough write-combined */
195#define XTHAL_SAM_WRITEALLOC 0x02E /* -OG-WAC- ...? writethrough-allocate */
196/*efine XTHAL_SAM_WRITEALLOCF 0x02E*/ /* F-G-WAC- ...? writethrough-allocate write-combined */
197#define XTHAL_SAM_WRITEBACK 0x026 /* F-G--AC- ...5 writeback */
198
199#if 0
200/*
201 Cache attribute encoding for CACHEATTR (per ISA):
202 (Note: if this differs from ISA Ref Manual, ISA has precedence)
203
204 Inst-fetches Loads Stores
205 ------------- ------------ -------------
2060x0 FCA_EXCEPTION ?LCA_NACACHED_G* SCA_WRITETHRU "uncached"
2070x1 FCA_CACHED LCA_CACHED SCA_WRITETHRU cached
2080x2 FCA_BYPASS LCA_BYPASS_G* SCA_BYPASS bypass
2090x3 FCA_CACHED LCA_CACHED SCA_WRITEALLOCF write-allocate
210 or LCA_EXCEPTION SCA_EXCEPTION (if unimplemented)
2110x4 FCA_CACHED LCA_CACHED SCA_WRITEBACK write-back
212 or LCA_EXCEPTION SCA_EXCEPTION (if unimplemented)
2130x5..D FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION (reserved)
2140xE FCA_EXCEPTION LCA_ISOLATE SCA_ISOLATE isolate
2150xF FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION illegal
216 * Prior to T1020.2?, guard feature not supported, this defaulted to speculative (no _G)
217*/
218#endif /*0*/
219
220
221#if !defined(__ASSEMBLY__) && !defined(_NOCLANGUAGE)
222#ifdef __cplusplus
223extern "C" {
224#endif
225
226/*----------------------------------------------------------------------
227 HAL
228 ----------------------------------------------------------------------*/
229
230/* Constant to be checked in build = (XTHAL_MAJOR_REV<<16)|XTHAL_MINOR_REV */
231extern const unsigned int Xthal_rev_no;
232
233
234/*----------------------------------------------------------------------
235 Processor State
236 ----------------------------------------------------------------------*/
237/* save & restore the extra processor state */
238extern void xthal_save_extra(void *base);
239extern void xthal_restore_extra(void *base);
240
241extern void xthal_save_cpregs(void *base, int);
242extern void xthal_restore_cpregs(void *base, int);
243
244/*extern void xthal_save_all_extra(void *base);*/
245/*extern void xthal_restore_all_extra(void *base);*/
246
247/* space for processor state */
248extern const unsigned int Xthal_extra_size;
249extern const unsigned int Xthal_extra_align;
250/* space for TIE register files */
251extern const unsigned int Xthal_cpregs_size[XTHAL_MAX_CPS];
252extern const unsigned int Xthal_cpregs_align[XTHAL_MAX_CPS];
253
254/* total of space for the processor state (for Tor2) */
255extern const unsigned int Xthal_all_extra_size;
256extern const unsigned int Xthal_all_extra_align;
257
258/* initialize the extra processor */
259/*extern void xthal_init_extra(void);*/
260/* initialize the TIE coprocessor */
261/*extern void xthal_init_cp(int);*/
262
263/* initialize the extra processor */
264extern void xthal_init_mem_extra(void *);
265/* initialize the TIE coprocessor */
266extern void xthal_init_mem_cp(void *, int);
267
268/* validate & invalidate the TIE register file */
269extern void xthal_validate_cp(int);
270extern void xthal_invalidate_cp(int);
271
272/* the number of TIE coprocessors contiguous from zero (for Tor2) */
273extern const unsigned int Xthal_num_coprocessors;
274
275/* actual number of coprocessors */
276extern const unsigned char Xthal_cp_num;
277/* index of highest numbered coprocessor, plus one */
278extern const unsigned char Xthal_cp_max;
279/* index of highest allowed coprocessor number, per cfg, plus one */
280/*extern const unsigned char Xthal_cp_maxcfg;*/
281/* bitmask of which coprocessors are present */
282extern const unsigned int Xthal_cp_mask;
283
284/* read and write cpenable register */
285extern void xthal_set_cpenable(unsigned);
286extern unsigned xthal_get_cpenable(void);
287
288/* read & write extra state register */
289/*extern int xthal_read_extra(void *base, unsigned reg, unsigned *value);*/
290/*extern int xthal_write_extra(void *base, unsigned reg, unsigned value);*/
291
292/* read & write a TIE coprocessor register */
293/*extern int xthal_read_cpreg(void *base, int cp, unsigned reg, unsigned *value);*/
294/*extern int xthal_write_cpreg(void *base, int cp, unsigned reg, unsigned value);*/
295
296/* return coprocessor number based on register */
297/*extern int xthal_which_cp(unsigned reg);*/
298
299/*----------------------------------------------------------------------
300 Interrupts
301 ----------------------------------------------------------------------*/
302
303/* the number of interrupt levels */
304extern const unsigned char Xthal_num_intlevels;
305/* the number of interrupts */
306extern const unsigned char Xthal_num_interrupts;
307
308/* mask for level of interrupts */
309extern const unsigned int Xthal_intlevel_mask[XTHAL_MAX_INTLEVELS];
310/* mask for level 0 to N interrupts */
311extern const unsigned int Xthal_intlevel_andbelow_mask[XTHAL_MAX_INTLEVELS];
312
313/* level of each interrupt */
314extern const unsigned char Xthal_intlevel[XTHAL_MAX_INTERRUPTS];
315
316/* type per interrupt */
317extern const unsigned char Xthal_inttype[XTHAL_MAX_INTERRUPTS];
318
319/* masks of each type of interrupt */
320extern const unsigned int Xthal_inttype_mask[XTHAL_MAX_INTTYPES];
321
322/* interrupt numbers assigned to each timer interrupt */
323extern const int Xthal_timer_interrupt[XTHAL_MAX_TIMERS];
324
325/*** Virtual interrupt prioritization: ***/
326
327/* Convert between interrupt levels (as per PS.INTLEVEL) and virtual interrupt priorities: */
328extern unsigned xthal_vpri_to_intlevel(unsigned vpri);
329extern unsigned xthal_intlevel_to_vpri(unsigned intlevel);
330
331/* Enables/disables given set (mask) of interrupts; returns previous enabled-mask of all ints: */
332extern unsigned xthal_int_enable(unsigned);
333extern unsigned xthal_int_disable(unsigned);
334
335/* Set/get virtual priority of an interrupt: */
336extern int xthal_set_int_vpri(int intnum, int vpri);
337extern int xthal_get_int_vpri(int intnum);
338
339/* Set/get interrupt lockout level for exclusive access to virtual priority data structures: */
340extern void xthal_set_vpri_locklevel(unsigned intlevel);
341extern unsigned xthal_get_vpri_locklevel(void);
342
343/* Set/get current virtual interrupt priority: */
344extern unsigned xthal_set_vpri(unsigned vpri);
345extern unsigned xthal_get_vpri(unsigned vpri);
346extern unsigned xthal_set_vpri_intlevel(unsigned intlevel);
347extern unsigned xthal_set_vpri_lock(void);
348
349
350
351/*----------------------------------------------------------------------
352 Generic Interrupt Trampolining Support
353 ----------------------------------------------------------------------*/
354
355typedef void (XtHalVoidFunc)(void);
356
357/*
358 * Bitmask of interrupts currently trampolining down:
359 */
360extern unsigned Xthal_tram_pending;
361
362/*
363 * Bitmask of which interrupts currently trampolining down
364 * synchronously are actually enabled; this bitmask is necessary
365 * because INTENABLE cannot hold that state (sync-trampolining
366 * interrupts must be kept disabled while trampolining);
367 * in the current implementation, any bit set here is not set
368 * in INTENABLE, and vice-versa; once a sync-trampoline is
369 * handled (at level one), its enable bit must be moved from
370 * here to INTENABLE:
371 */
372extern unsigned Xthal_tram_enabled;
373
374/*
375 * Bitmask of interrupts configured for sync trampolining:
376 */
377extern unsigned Xthal_tram_sync;
378
379
380/* Trampoline support functions: */
381extern unsigned xthal_tram_pending_to_service( void );
382extern void xthal_tram_done( unsigned serviced_mask );
383extern int xthal_tram_set_sync( int intnum, int sync );
384extern XtHalVoidFunc* xthal_set_tram_trigger_func( XtHalVoidFunc *trigger_fn );
385
386/* INTENABLE,INTREAD,INTSET,INTCLEAR register access functions: */
387extern unsigned xthal_get_intenable( void );
388extern void xthal_set_intenable( unsigned );
389extern unsigned xthal_get_intread( void );
390extern void xthal_set_intset( unsigned );
391extern void xthal_set_intclear( unsigned );
392
393
394/*----------------------------------------------------------------------
395 Register Windows
396 ----------------------------------------------------------------------*/
397
398/* number of registers in register window */
399extern const unsigned int Xthal_num_aregs;
400extern const unsigned char Xthal_num_aregs_log2;
401
402/* This spill any live register windows (other than the caller's): */
403extern void xthal_window_spill( void );
404
405
406/*----------------------------------------------------------------------
407 Cache
408 ----------------------------------------------------------------------*/
409
410/* size of the cache lines in log2(bytes) */
411extern const unsigned char Xthal_icache_linewidth;
412extern const unsigned char Xthal_dcache_linewidth;
413/* size of the cache lines in bytes */
414extern const unsigned short Xthal_icache_linesize;
415extern const unsigned short Xthal_dcache_linesize;
416/* number of cache sets in log2(lines per way) */
417extern const unsigned char Xthal_icache_setwidth;
418extern const unsigned char Xthal_dcache_setwidth;
419/* cache set associativity (number of ways) */
420extern const unsigned int Xthal_icache_ways;
421extern const unsigned int Xthal_dcache_ways;
422/* size of the caches in bytes (ways * 2^(linewidth + setwidth)) */
423extern const unsigned int Xthal_icache_size;
424extern const unsigned int Xthal_dcache_size;
425/* cache features */
426extern const unsigned char Xthal_dcache_is_writeback;
427extern const unsigned char Xthal_icache_line_lockable;
428extern const unsigned char Xthal_dcache_line_lockable;
429
430/* cache attribute register control (used by other HAL routines) */
431extern unsigned xthal_get_cacheattr( void );
432extern unsigned xthal_get_icacheattr( void );
433extern unsigned xthal_get_dcacheattr( void );
434extern void xthal_set_cacheattr( unsigned );
435extern void xthal_set_icacheattr( unsigned );
436extern void xthal_set_dcacheattr( unsigned );
437
438/* initialize cache support (must be called once at startup, before all other cache calls) */
439/*extern void xthal_cache_startinit( void );*/
440/* reset caches */
441/*extern void xthal_icache_reset( void );*/
442/*extern void xthal_dcache_reset( void );*/
443/* enable caches */
444extern void xthal_icache_enable( void ); /* DEPRECATED */
445extern void xthal_dcache_enable( void ); /* DEPRECATED */
446/* disable caches */
447extern void xthal_icache_disable( void ); /* DEPRECATED */
448extern void xthal_dcache_disable( void ); /* DEPRECATED */
449
450/* invalidate the caches */
451extern void xthal_icache_all_invalidate( void );
452extern void xthal_dcache_all_invalidate( void );
453extern void xthal_icache_region_invalidate( void *addr, unsigned size );
454extern void xthal_dcache_region_invalidate( void *addr, unsigned size );
455extern void xthal_icache_line_invalidate(void *addr);
456extern void xthal_dcache_line_invalidate(void *addr);
457/* write dirty data back */
458extern void xthal_dcache_all_writeback( void );
459extern void xthal_dcache_region_writeback( void *addr, unsigned size );
460extern void xthal_dcache_line_writeback(void *addr);
461/* write dirty data back and invalidate */
462extern void xthal_dcache_all_writeback_inv( void );
463extern void xthal_dcache_region_writeback_inv( void *addr, unsigned size );
464extern void xthal_dcache_line_writeback_inv(void *addr);
465/* prefetch and lock specified memory range into cache */
466extern void xthal_icache_region_lock( void *addr, unsigned size );
467extern void xthal_dcache_region_lock( void *addr, unsigned size );
468extern void xthal_icache_line_lock(void *addr);
469extern void xthal_dcache_line_lock(void *addr);
470/* unlock from cache */
471extern void xthal_icache_all_unlock( void );
472extern void xthal_dcache_all_unlock( void );
473extern void xthal_icache_region_unlock( void *addr, unsigned size );
474extern void xthal_dcache_region_unlock( void *addr, unsigned size );
475extern void xthal_icache_line_unlock(void *addr);
476extern void xthal_dcache_line_unlock(void *addr);
477
478
479/* sync icache and memory */
480extern void xthal_icache_sync( void );
481/* sync dcache and memory */
482extern void xthal_dcache_sync( void );
483
484/*----------------------------------------------------------------------
485 Debug
486 ----------------------------------------------------------------------*/
487
488/* 1 if debug option configured, 0 if not: */
489extern const int Xthal_debug_configured;
490
491/* Number of instruction and data break registers: */
492extern const int Xthal_num_ibreak;
493extern const int Xthal_num_dbreak;
494
495/* Set (plant) and remove software breakpoint, both synchronizing cache: */
496extern unsigned int xthal_set_soft_break(void *addr);
497extern void xthal_remove_soft_break(void *addr, unsigned int);
498
499
500/*----------------------------------------------------------------------
501 Disassembler
502 ----------------------------------------------------------------------*/
503
504/* Max expected size of the return buffer for a disassembled instruction (hint only): */
505#define XTHAL_DISASM_BUFSIZE 80
506
507/* Disassembly option bits for selecting what to return: */
508#define XTHAL_DISASM_OPT_ADDR 0x0001 /* display address */
509#define XTHAL_DISASM_OPT_OPHEX 0x0002 /* display opcode bytes in hex */
510#define XTHAL_DISASM_OPT_OPCODE 0x0004 /* display opcode name (mnemonic) */
511#define XTHAL_DISASM_OPT_PARMS 0x0008 /* display parameters */
512#define XTHAL_DISASM_OPT_ALL 0x0FFF /* display everything */
513
514/* routine to get a string for the disassembled instruction */
515extern int xthal_disassemble( unsigned char *instr_buf, void *tgt_addr,
516 char *buffer, unsigned buflen, unsigned options );
517
518/* routine to get the size of the next instruction. Returns 0 for
519 illegal instruction */
520extern int xthal_disassemble_size( unsigned char *instr_buf );
521
522
523/*----------------------------------------------------------------------
524 Core Counter
525 ----------------------------------------------------------------------*/
526
527/* counter info */
528extern const unsigned char Xthal_have_ccount; /* set if CCOUNT register present */
529extern const unsigned char Xthal_num_ccompare; /* number of CCOMPAREn registers */
530
531/* get CCOUNT register (if not present return 0) */
532extern unsigned xthal_get_ccount(void);
533
534/* set and get CCOMPAREn registers (if not present, get returns 0) */
535extern void xthal_set_ccompare(int, unsigned);
536extern unsigned xthal_get_ccompare(int);
537
538
539/*----------------------------------------------------------------------
540 Instruction/Data RAM/ROM Access
541 ----------------------------------------------------------------------*/
542
543extern void* xthal_memcpy(void *dst, const void *src, unsigned len);
544extern void* xthal_bcopy(const void *src, void *dst, unsigned len);
545
546/*----------------------------------------------------------------------
547 MP Synchronization
548 ----------------------------------------------------------------------*/
549extern int xthal_compare_and_set( int *addr, int test_val, int compare_val );
550extern unsigned xthal_get_prid( void );
551
552/*extern const char Xthal_have_s32c1i;*/
553extern const unsigned char Xthal_have_prid;
554
555
556/*----------------------------------------------------------------------
557 Miscellaneous
558 ----------------------------------------------------------------------*/
559
560extern const unsigned int Xthal_release_major;
561extern const unsigned int Xthal_release_minor;
562extern const char * const Xthal_release_name;
563extern const char * const Xthal_release_internal;
564
565extern const unsigned char Xthal_memory_order;
566extern const unsigned char Xthal_have_windowed;
567extern const unsigned char Xthal_have_density;
568extern const unsigned char Xthal_have_booleans;
569extern const unsigned char Xthal_have_loops;
570extern const unsigned char Xthal_have_nsa;
571extern const unsigned char Xthal_have_minmax;
572extern const unsigned char Xthal_have_sext;
573extern const unsigned char Xthal_have_clamps;
574extern const unsigned char Xthal_have_mac16;
575extern const unsigned char Xthal_have_mul16;
576extern const unsigned char Xthal_have_fp;
577extern const unsigned char Xthal_have_speculation;
578extern const unsigned char Xthal_have_exceptions;
579extern const unsigned char Xthal_xea_version;
580extern const unsigned char Xthal_have_interrupts;
581extern const unsigned char Xthal_have_highlevel_interrupts;
582extern const unsigned char Xthal_have_nmi;
583
584extern const unsigned short Xthal_num_writebuffer_entries;
585
586extern const unsigned int Xthal_build_unique_id;
587/* Release info for hardware targeted by software upgrades: */
588extern const unsigned int Xthal_hw_configid0;
589extern const unsigned int Xthal_hw_configid1;
590extern const unsigned int Xthal_hw_release_major;
591extern const unsigned int Xthal_hw_release_minor;
592extern const char * const Xthal_hw_release_name;
593extern const char * const Xthal_hw_release_internal;
594
595
596/* Internal memories... */
597
598extern const unsigned char Xthal_num_instrom;
599extern const unsigned char Xthal_num_instram;
600extern const unsigned char Xthal_num_datarom;
601extern const unsigned char Xthal_num_dataram;
602extern const unsigned char Xthal_num_xlmi;
603extern const unsigned int Xthal_instrom_vaddr[1];
604extern const unsigned int Xthal_instrom_paddr[1];
605extern const unsigned int Xthal_instrom_size [1];
606extern const unsigned int Xthal_instram_vaddr[1];
607extern const unsigned int Xthal_instram_paddr[1];
608extern const unsigned int Xthal_instram_size [1];
609extern const unsigned int Xthal_datarom_vaddr[1];
610extern const unsigned int Xthal_datarom_paddr[1];
611extern const unsigned int Xthal_datarom_size [1];
612extern const unsigned int Xthal_dataram_vaddr[1];
613extern const unsigned int Xthal_dataram_paddr[1];
614extern const unsigned int Xthal_dataram_size [1];
615extern const unsigned int Xthal_xlmi_vaddr[1];
616extern const unsigned int Xthal_xlmi_paddr[1];
617extern const unsigned int Xthal_xlmi_size [1];
618
619
620
621/*----------------------------------------------------------------------
622 Memory Management Unit
623 ----------------------------------------------------------------------*/
624
625extern const unsigned char Xthal_have_spanning_way;
626extern const unsigned char Xthal_have_identity_map;
627extern const unsigned char Xthal_have_mimic_cacheattr;
628extern const unsigned char Xthal_have_xlt_cacheattr;
629extern const unsigned char Xthal_have_cacheattr;
630extern const unsigned char Xthal_have_tlbs;
631
632extern const unsigned char Xthal_mmu_asid_bits; /* 0 .. 8 */
633extern const unsigned char Xthal_mmu_asid_kernel;
634extern const unsigned char Xthal_mmu_rings; /* 1 .. 4 (perhaps 0 if no MMU and/or no protection?) */
635extern const unsigned char Xthal_mmu_ring_bits;
636extern const unsigned char Xthal_mmu_sr_bits;
637extern const unsigned char Xthal_mmu_ca_bits;
638extern const unsigned int Xthal_mmu_max_pte_page_size;
639extern const unsigned int Xthal_mmu_min_pte_page_size;
640
641extern const unsigned char Xthal_itlb_way_bits;
642extern const unsigned char Xthal_itlb_ways;
643extern const unsigned char Xthal_itlb_arf_ways;
644extern const unsigned char Xthal_dtlb_way_bits;
645extern const unsigned char Xthal_dtlb_ways;
646extern const unsigned char Xthal_dtlb_arf_ways;
647
648/* Convert between virtual and physical addresses (through static maps only): */
649/*** WARNING: these two functions may go away in a future release; don't depend on them! ***/
650extern int xthal_static_v2p( unsigned vaddr, unsigned *paddrp );
651extern int xthal_static_p2v( unsigned paddr, unsigned *vaddrp, unsigned cached );
652
653#if 0
654/******************* EXPERIMENTAL AND TENTATIVE ONLY ********************/
655
656#define XTHAL_MMU_PAGESZ_COUNT_MAX 8 /* maximum number of different page sizes */
657extern const char Xthal_mmu_pagesz_count; /* 0 .. 8 number of different page sizes configured */
658
659/* Note: the following table doesn't necessarily have page sizes in increasing order: */
660extern const char Xthal_mmu_pagesz_log2[XTHAL_MMU_PAGESZ_COUNT_MAX]; /* 10 .. 28 (0 past count) */
661
662/* Sorted (increasing) table of page sizes, that indexes into the above table: */
663extern const char Xthal_mmu_pagesz_sorted[XTHAL_MMU_PAGESZ_COUNT_MAX]; /* 0 .. 7 (0 past count) */
664
665/*u32 Xthal_virtual_exceptions;*/ /* bitmask of which exceptions execute in virtual mode... */
666
667extern const char Xthal_mmu_pte_pagesz_log2_min; /* ?? minimum page size in PTEs */
668extern const char Xthal_mmu_pte_pagesz_log2_max; /* ?? maximum page size in PTEs */
669
670/* Cache Attribute Bits Implemented by the Cache (part of the cache abstraction) */
671extern const char Xthal_icache_fca_bits_implemented; /* ITLB/UTLB only! */
672extern const char Xthal_dcache_lca_bits_implemented; /* DTLB/UTLB only! */
673extern const char Xthal_dcache_sca_bits_implemented; /* DTLB/UTLB only! */
674
675/* Per TLB Parameters (Instruction, Data, Unified) */
676struct XtHalMmuTlb Xthal_itlb; /* description of MMU I-TLB generic features */
677struct XtHalMmuTlb Xthal_dtlb; /* description of MMU D-TLB generic features */
678struct XtHalMmuTlb Xthal_utlb; /* description of MMU U-TLB generic features */
679
680#define XTHAL_MMU_WAYS_MAX 8 /* maximum number of ways (associativities) for each TLB */
681
682/* Structure for common information described for each possible TLB (instruction, data and unified): */
683typedef struct XtHalMmuTlb {
684 u8 va_bits; /* 32 (number of virtual address bits) */
685 u8 pa_bits; /* 32 (number of physical address bits) */
686 bool tlb_va_indexed; /* 1 (set if TLB is indexed by virtual address) */
687 bool tlb_va_tagged; /* 0 (set if TLB is tagged by virtual address) */
688 bool cache_va_indexed; /* 1 (set if cache is indexed by virtual address) */
689 bool cache_va_tagged; /* 0 (set if cache is tagged by virtual address) */
690 /*bool (whether page tables are traversed in vaddr sorted order, paddr sorted order, ...) */
691 /*u8 (set of available page attribute bits, other than cache attribute bits defined above) */
692 /*u32 (various masks for pages, MMU table/TLB entries, etc.) */
693 u8 way_count; /* 0 .. 8 (number of ways, a.k.a. associativities, for this TLB) */
694 XtHalMmuTlbWay * ways[XTHAL_MMU_WAYS_MAX]; /* pointers to per-way parms for each way */
695} XtHalMmuTlb;
696
697/* Per TLB Way (Per Associativity) Parameters */
698typedef struct XtHalMmuTlbWay {
699 u32 index_count_log2; /* 0 .. 4 */
700 u32 pagesz_mask; /* 0 .. 2^pagesz_count - 1 (each bit corresponds to a size */
701 /* defined in the Xthal_mmu_pagesz_log2[] table) */
702 u32 vpn_const_mask;
703 u32 vpn_const_value;
704 u64 ppn_const_mask; /* future may support pa_bits > 32 */
705 u64 ppn_const_value;
706 u32 ppn_id_mask; /* paddr bits taken directly from vaddr */
707 bool backgnd_match; /* 0 or 1 */
708 /* These are defined in terms of the XTHAL_CACHE_xxx bits: */
709 u8 fca_const_mask; /* ITLB/UTLB only! */
710 u8 fca_const_value; /* ITLB/UTLB only! */
711 u8 lca_const_mask; /* DTLB/UTLB only! */
712 u8 lca_const_value; /* DTLB/UTLB only! */
713 u8 sca_const_mask; /* DTLB/UTLB only! */
714 u8 sca_const_value; /* DTLB/UTLB only! */
715 /* These define an encoding that map 5 bits in TLB and PTE entries to */
716 /* 8 bits (FCA, ITLB), 16 bits (LCA+SCA, DTLB) or 24 bits (FCA+LCA+SCA, UTLB): */
717 /* (they may be moved to struct XtHalMmuTlb) */
718 u8 ca_bits; /* number of bits in TLB/PTE entries for cache attributes */
719 u32 * ca_map; /* pointer to array of 2^ca_bits entries of FCA+LCA+SCA bits */
720} XtHalMmuTlbWay;
721
722/*
723 * The way to determine whether protection support is present in core
724 * is to [look at Xthal_mmu_rings ???].
725 * Give info on memory requirements for MMU tables and other in-memory
726 * data structures (globally, per task, base and per page, etc.) - whatever bounds can be calculated.
727 */
728
729
730/* Default vectors: */
731xthal_immu_fetch_miss_vector
732xthal_dmmu_load_miss_vector
733xthal_dmmu_store_miss_vector
734
735/* Functions called when a fault is detected: */
736typedef void (XtHalMmuFaultFunc)( unsigned vaddr, ...context... );
737/* Or, */
738/* a? = vaddr */
739/* a? = context... */
740/* PS.xxx = xxx */
741XtHalMMuFaultFunc *Xthal_immu_fetch_fault_func;
742XtHalMMuFaultFunc *Xthal_dmmu_load_fault_func;
743XtHalMMuFaultFunc *Xthal_dmmu_store_fault_func;
744
745/* Default Handlers: */
746/* The user and/or kernel exception handlers may jump to these handlers to handle the relevant exceptions,
747 * according to the value of EXCCAUSE. The exact register state on entry to these handlers is TBD. */
748/* When multiple TLB entries match (hit) on the same access: */
749xthal_immu_fetch_multihit_handler
750xthal_dmmu_load_multihit_handler
751xthal_dmmu_store_multihit_handler
752/* Protection violations according to cache attributes, and other cache attribute mismatches: */
753xthal_immu_fetch_attr_handler
754xthal_dmmu_load_attr_handler
755xthal_dmmu_store_attr_handler
756/* Protection violations due to insufficient ring level: */
757xthal_immu_fetch_priv_handler
758xthal_dmmu_load_priv_handler
759xthal_dmmu_store_priv_handler
760/* Alignment exception handlers (if supported by the particular Xtensa MMU configuration): */
761xthal_dmmu_load_align_handler
762xthal_dmmu_store_align_handler
763
764/* Or, alternatively, the OS user and/or kernel exception handlers may simply jump to the
765 * following entry points which will handle any values of EXCCAUSE not handled by the OS: */
766xthal_user_exc_default_handler
767xthal_kernel_exc_default_handler
768
769#endif /*0*/
770
771#ifdef INCLUDE_DEPRECATED_HAL_CODE
772extern const unsigned char Xthal_have_old_exc_arch;
773extern const unsigned char Xthal_have_mmu;
774extern const unsigned int Xthal_num_regs;
775extern const unsigned char Xthal_num_iroms;
776extern const unsigned char Xthal_num_irams;
777extern const unsigned char Xthal_num_droms;
778extern const unsigned char Xthal_num_drams;
779extern const unsigned int Xthal_configid0;
780extern const unsigned int Xthal_configid1;
781#endif
782
783#ifdef INCLUDE_DEPRECATED_HAL_DEBUG_CODE
784#define XTHAL_24_BIT_BREAK 0x80000000
785#define XTHAL_16_BIT_BREAK 0x40000000
786extern const unsigned short Xthal_ill_inst_16[16];
787#define XTHAL_DEST_REG 0xf0000000 /* Mask for destination register */
788#define XTHAL_DEST_REG_INST 0x08000000 /* Branch address is in register */
789#define XTHAL_DEST_REL_INST 0x04000000 /* Branch address is relative */
790#define XTHAL_RFW_INST 0x00000800
791#define XTHAL_RFUE_INST 0x00000400
792#define XTHAL_RFI_INST 0x00000200
793#define XTHAL_RFE_INST 0x00000100
794#define XTHAL_RET_INST 0x00000080
795#define XTHAL_BREAK_INST 0x00000040
796#define XTHAL_SYSCALL_INST 0x00000020
797#define XTHAL_LOOP_END 0x00000010 /* Not set by xthal_inst_type */
798#define XTHAL_JUMP_INST 0x00000008 /* Call or jump instruction */
799#define XTHAL_BRANCH_INST 0x00000004 /* Branch instruction */
800#define XTHAL_24_BIT_INST 0x00000002
801#define XTHAL_16_BIT_INST 0x00000001
802typedef struct xthal_state {
803 unsigned pc;
804 unsigned ar[16];
805 unsigned lbeg;
806 unsigned lend;
807 unsigned lcount;
808 unsigned extra_ptr;
809 unsigned cpregs_ptr[XTHAL_MAX_CPS];
810} XTHAL_STATE;
811extern unsigned int xthal_inst_type(void *addr);
812extern unsigned int xthal_branch_addr(void *addr);
813extern unsigned int xthal_get_npc(XTHAL_STATE *user_state);
814#endif /* INCLUDE_DEPRECATED_HAL_DEBUG_CODE */
815
816#ifdef __cplusplus
817}
818#endif
819#endif /*!__ASSEMBLY__ */
820
821#endif /*XTENSA_HAL_H*/
822
diff --git a/include/asm-xtensa/xtensa/simcall.h b/include/asm-xtensa/xtensa/simcall.h
new file mode 100644
index 000000000000..a2b868929a49
--- /dev/null
+++ b/include/asm-xtensa/xtensa/simcall.h
@@ -0,0 +1,130 @@
1#ifndef SIMCALL_INCLUDED
2#define SIMCALL_INCLUDED
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * include/asm-xtensa/xtensa/simcall.h - Simulator call numbers
8 *
9 * This file is subject to the terms and conditions of the GNU General
10 * Public License. See the file "COPYING" in the main directory of
11 * this archive for more details.
12 *
13 * Copyright (C) 2002 Tensilica Inc.
14 */
15
16
17/*
18 * System call like services offered by the simulator host.
19 * These are modeled after the Linux 2.4 kernel system calls
20 * for Xtensa processors. However not all system calls and
21 * not all functionality of a given system call are implemented,
22 * or necessarily have well defined or equivalent semantics in
23 * the context of a simulation (as opposed to a Unix kernel).
24 *
25 * These services behave largely as if they had been invoked
26 * as a task in the simulator host's operating system
27 * (eg. files accessed are those of the simulator host).
28 * However, these SIMCALLs model a virtual operating system
29 * so that various definitions, bit assignments etc
30 * (eg. open mode bits, errno values, etc) are independent
31 * of the host operating system used to run the simulation.
32 * Rather these definitions are specific to the Xtensa ISS.
33 * This way Xtensa ISA code written to use these SIMCALLs
34 * can (in principle) be simulated on any host.
35 *
36 * Up to 6 parameters are passed in registers a3 to a8
37 * (note the 6th parameter isn't passed on the stack,
38 * unlike windowed function calling conventions).
39 * The return value is in a2. A negative value in the
40 * range -4096 to -1 indicates a negated error code to be
41 * reported in errno with a return value of -1, otherwise
42 * the value in a2 is returned as is.
43 */
44
45/* These #defines need to match what's in Xtensa/OS/vxworks/xtiss/simcalls.c */
46
47#define SYS_nop 0 /* n/a - setup; used to flush register windows */
48#define SYS_exit 1 /*x*/
49#define SYS_fork 2
50#define SYS_read 3 /*x*/
51#define SYS_write 4 /*x*/
52#define SYS_open 5 /*x*/
53#define SYS_close 6 /*x*/
54#define SYS_rename 7 /*x 38 - waitpid */
55#define SYS_creat 8 /*x*/
56#define SYS_link 9 /*x (not implemented on WIN32) */
57#define SYS_unlink 10 /*x*/
58#define SYS_execv 11 /* n/a - execve */
59#define SYS_execve 12 /* 11 - chdir */
60#define SYS_pipe 13 /* 42 - time */
61#define SYS_stat 14 /* 106 - mknod */
62#define SYS_chmod 15
63#define SYS_chown 16 /* 202 - lchown */
64#define SYS_utime 17 /* 30 - break */
65#define SYS_wait 18 /* n/a - oldstat */
66#define SYS_lseek 19 /*x*/
67#define SYS_getpid 20
68#define SYS_isatty 21 /* n/a - mount */
69#define SYS_fstat 22 /* 108 - oldumount */
70#define SYS_time 23 /* 13 - setuid */
71#define SYS_gettimeofday 24 /*x 78 - getuid (not implemented on WIN32) */
72#define SYS_times 25 /*X 43 - stime (Xtensa-specific implementation) */
73#define SYS_socket 26
74#define SYS_sendto 27
75#define SYS_recvfrom 28
76#define SYS_select_one 29 /* not compitible select, one file descriptor at the time */
77#define SYS_bind 30
78#define SYS_ioctl 31
79
80/*
81 * Other...
82 */
83#define SYS_iss_argc 1000 /* returns value of argc */
84#define SYS_iss_argv_size 1001 /* bytes needed for argv & arg strings */
85#define SYS_iss_set_argv 1002 /* saves argv & arg strings at given addr */
86
87/*
88 * SIMCALLs for the ferret memory debugger. All are invoked by
89 * libferret.a ... ( Xtensa/Target-Libs/ferret )
90 */
91#define SYS_ferret 1010
92#define SYS_malloc 1011
93#define SYS_free 1012
94#define SYS_more_heap 1013
95#define SYS_no_heap 1014
96
97
98/*
99 * Extra SIMCALLs for GDB:
100 */
101#define SYS_gdb_break -1 /* invoked by XTOS on user exceptions if EPC points
102 to a break.n/break, regardless of cause! */
103#define SYS_xmon_out -2 /* invoked by XMON: ... */
104#define SYS_xmon_in -3 /* invoked by XMON: ... */
105#define SYS_xmon_flush -4 /* invoked by XMON: ... */
106#define SYS_gdb_abort -5 /* invoked by XTOS in _xtos_panic() */
107#define SYS_gdb_illegal_inst -6 /* invoked by XTOS for illegal instructions (too deeply) */
108#define SYS_xmon_init -7 /* invoked by XMON: ... */
109#define SYS_gdb_enter_sktloop -8 /* invoked by XTOS on debug exceptions */
110
111/*
112 * SIMCALLs for vxWorks xtiss BSP:
113 */
114#define SYS_setup_ppp_pipes -83
115#define SYS_log_msg -84
116
117/*
118 * Test SIMCALLs:
119 */
120#define SYS_test_write_state -100
121#define SYS_test_read_state -101
122
123/*
124 * SYS_select_one specifiers
125 */
126#define XTISS_SELECT_ONE_READ 1
127#define XTISS_SELECT_ONE_WRITE 2
128#define XTISS_SELECT_ONE_EXCEPT 3
129
130#endif /* !SIMCALL_INCLUDED */
diff --git a/include/asm-xtensa/xtensa/xt2000-uart.h b/include/asm-xtensa/xtensa/xt2000-uart.h
new file mode 100644
index 000000000000..0154460f0ed8
--- /dev/null
+++ b/include/asm-xtensa/xtensa/xt2000-uart.h
@@ -0,0 +1,155 @@
1#ifndef _uart_h_included_
2#define _uart_h_included_
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * include/asm-xtensa/xtensa/xt2000-uart.h -- NatSemi PC16552D DUART
8 * definitions
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 *
14 * Copyright (C) 2002 Tensilica Inc.
15 */
16
17
18#include <xtensa/xt2000.h>
19
20
21/* 16550 UART DEVICE REGISTERS
22 The XT2000 board aligns each register to a 32-bit word but the UART device only uses
23 one byte of the word, which is the least-significant byte regardless of the
24 endianness of the core (ie. byte offset 0 for little-endian and 3 for big-endian).
25 So if using word accesses then endianness doesn't matter.
26 The macros provided here do that.
27*/
28struct uart_dev_s {
29 union {
30 unsigned int rxb; /* DLAB=0: receive buffer, read-only */
31 unsigned int txb; /* DLAB=0: transmit buffer, write-only */
32 unsigned int dll; /* DLAB=1: divisor, least-significant byte latch (was write-only?) */
33 } w0;
34 union {
35 unsigned int ier; /* DLAB=0: interrupt-enable register (was write-only?) */
36 unsigned int dlm; /* DLAB=1: divisor, most-significant byte latch (was write-only?) */
37 } w1;
38
39 union {
40 unsigned int isr; /* DLAB=0: interrupt status register, read-only */
41 unsigned int fcr; /* DLAB=0: FIFO control register, write-only */
42 unsigned int afr; /* DLAB=1: alternate function register */
43 } w2;
44
45 unsigned int lcr; /* line control-register, write-only */
46 unsigned int mcr; /* modem control-regsiter, write-only */
47 unsigned int lsr; /* line status register, read-only */
48 unsigned int msr; /* modem status register, read-only */
49 unsigned int scr; /* scratch regsiter, read/write */
50};
51
52#define _RXB(u) ((u)->w0.rxb)
53#define _TXB(u) ((u)->w0.txb)
54#define _DLL(u) ((u)->w0.dll)
55#define _IER(u) ((u)->w1.ier)
56#define _DLM(u) ((u)->w1.dlm)
57#define _ISR(u) ((u)->w2.isr)
58#define _FCR(u) ((u)->w2.fcr)
59#define _AFR(u) ((u)->w2.afr)
60#define _LCR(u) ((u)->lcr)
61#define _MCR(u) ((u)->mcr)
62#define _LSR(u) ((u)->lsr)
63#define _MSR(u) ((u)->msr)
64#define _SCR(u) ((u)->scr)
65
66typedef volatile struct uart_dev_s uart_dev_t;
67
68/* IER bits */
69#define RCVR_DATA_REG_INTENABLE 0x01
70#define XMIT_HOLD_REG_INTENABLE 0x02
71#define RCVR_STATUS_INTENABLE 0x04
72#define MODEM_STATUS_INTENABLE 0x08
73
74/* FCR bits */
75#define _FIFO_ENABLE 0x01
76#define RCVR_FIFO_RESET 0x02
77#define XMIT_FIFO_RESET 0x04
78#define DMA_MODE_SELECT 0x08
79#define RCVR_TRIGGER_LSB 0x40
80#define RCVR_TRIGGER_MSB 0x80
81
82/* AFR bits */
83#define AFR_CONC_WRITE 0x01
84#define AFR_BAUDOUT_SEL 0x02
85#define AFR_RXRDY_SEL 0x04
86
87/* ISR bits */
88#define INT_STATUS(r) ((r)&1)
89#define INT_PRIORITY(r) (((r)>>1)&0x7)
90
91/* LCR bits */
92#define WORD_LENGTH(n) (((n)-5)&0x3)
93#define STOP_BIT_ENABLE 0x04
94#define PARITY_ENABLE 0x08
95#define EVEN_PARITY 0x10
96#define FORCE_PARITY 0x20
97#define XMIT_BREAK 0x40
98#define DLAB_ENABLE 0x80
99
100/* MCR bits */
101#define _DTR 0x01
102#define _RTS 0x02
103#define _OP1 0x04
104#define _OP2 0x08
105#define LOOP_BACK 0x10
106
107/* LSR Bits */
108#define RCVR_DATA_READY 0x01
109#define OVERRUN_ERROR 0x02
110#define PARITY_ERROR 0x04
111#define FRAMING_ERROR 0x08
112#define BREAK_INTERRUPT 0x10
113#define XMIT_HOLD_EMPTY 0x20
114#define XMIT_EMPTY 0x40
115#define FIFO_ERROR 0x80
116#define RCVR_READY(u) (_LSR(u)&RCVR_DATA_READY)
117#define XMIT_READY(u) (_LSR(u)&XMIT_HOLD_EMPTY)
118
119/* MSR bits */
120#define _RDR 0x01
121#define DELTA_DSR 0x02
122#define DELTA_RI 0x04
123#define DELTA_CD 0x08
124#define _CTS 0x10
125#define _DSR 0x20
126#define _RI 0x40
127#define _CD 0x80
128
129/* prototypes */
130void uart_init( uart_dev_t *u, int bitrate );
131void uart_out( uart_dev_t *u, char c );
132void uart_puts( uart_dev_t *u, char *s );
133char uart_in( uart_dev_t *u );
134void uart_enable_rcvr_int( uart_dev_t *u );
135void uart_disable_rcvr_int( uart_dev_t *u );
136
137#ifdef DUART16552_1_VADDR
138/* DUART present. */
139#define DUART_1_BASE (*(uart_dev_t*)DUART16552_1_VADDR)
140#define DUART_2_BASE (*(uart_dev_t*)DUART16552_2_VADDR)
141#define UART1_PUTS(s) uart_puts( &DUART_1_BASE, s )
142#define UART2_PUTS(s) uart_puts( &DUART_2_BASE, s )
143#else
144/* DUART not configured, use dummy placeholders to allow compiles to work. */
145#define DUART_1_BASE (*(uart_dev_t*)0)
146#define DUART_2_BASE (*(uart_dev_t*)0)
147#define UART1_PUTS(s)
148#define UART2_PUTS(s)
149#endif
150
151/* Compute 16-bit divisor for baudrate generator, with rounding: */
152#define DUART_DIVISOR(crystal,speed) (((crystal)/16 + (speed)/2)/(speed))
153
154#endif /*_uart_h_included_*/
155
diff --git a/include/asm-xtensa/xtensa/xt2000.h b/include/asm-xtensa/xtensa/xt2000.h
new file mode 100644
index 000000000000..703a45002f8f
--- /dev/null
+++ b/include/asm-xtensa/xtensa/xt2000.h
@@ -0,0 +1,408 @@
1#ifndef _INC_XT2000_H_
2#define _INC_XT2000_H_
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * include/asm-xtensa/xtensa/xt2000.h - Definitions specific to the
8 * Tensilica XT2000 Emulation Board
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 *
14 * Copyright (C) 2002 Tensilica Inc.
15 */
16
17
18#include <xtensa/config/core.h>
19#include <xtensa/config/system.h>
20
21
22/*
23 * Default assignment of XT2000 devices to external interrupts.
24 */
25
26/* Ethernet interrupt: */
27#ifdef XCHAL_EXTINT3_NUM
28#define SONIC83934_INTNUM XCHAL_EXTINT3_NUM
29#define SONIC83934_INTLEVEL XCHAL_EXTINT3_LEVEL
30#define SONIC83934_INTMASK XCHAL_EXTINT3_MASK
31#else
32#define SONIC83934_INTMASK 0
33#endif
34
35/* DUART channel 1 interrupt (P1 - console): */
36#ifdef XCHAL_EXTINT4_NUM
37#define DUART16552_1_INTNUM XCHAL_EXTINT4_NUM
38#define DUART16552_1_INTLEVEL XCHAL_EXTINT4_LEVEL
39#define DUART16552_1_INTMASK XCHAL_EXTINT4_MASK
40#else
41#define DUART16552_1_INTMASK 0
42#endif
43
44/* DUART channel 2 interrupt (P2 - 2nd serial port): */
45#ifdef XCHAL_EXTINT5_NUM
46#define DUART16552_2_INTNUM XCHAL_EXTINT5_NUM
47#define DUART16552_2_INTLEVEL XCHAL_EXTINT5_LEVEL
48#define DUART16552_2_INTMASK XCHAL_EXTINT5_MASK
49#else
50#define DUART16552_2_INTMASK 0
51#endif
52
53/* FPGA-combined PCI/etc interrupts: */
54#ifdef XCHAL_EXTINT6_NUM
55#define XT2000_FPGAPCI_INTNUM XCHAL_EXTINT6_NUM
56#define XT2000_FPGAPCI_INTLEVEL XCHAL_EXTINT6_LEVEL
57#define XT2000_FPGAPCI_INTMASK XCHAL_EXTINT6_MASK
58#else
59#define XT2000_FPGAPCI_INTMASK 0
60#endif
61
62
63
64/*
65 * Device addresses.
66 *
67 * Note: for endianness-independence, use 32-bit loads and stores for all
68 * register accesses to Ethernet, DUART and LED devices. Undefined bits
69 * may need to be masked out if needed when reading if the actual register
70 * size is smaller than 32 bits.
71 *
72 * Note: XT2000 bus byte lanes are defined in terms of msbyte and lsbyte
73 * relative to the processor. So 32-bit registers are accessed consistently
74 * from both big and little endian processors. However, this means byte
75 * sequences are not consistent between big and little endian processors.
76 * This is fine for RAM, and for ROM if ROM is created for a specific
77 * processor (and thus has correct byte sequences). However this may be
78 * unexpected for Flash, which might contain a file-system that one wants
79 * to use for multiple processor configurations (eg. the Flash might contain
80 * the Ethernet card's address, endianness-independent application data, etc).
81 * That is, byte sequences written in Flash by a core of a given endianness
82 * will be byte-swapped when seen by a core of the other endianness.
83 * Someone implementing an endianness-independent Flash file system will
84 * likely handle this byte-swapping issue in the Flash driver software.
85 */
86
87#define DUART16552_XTAL_FREQ 18432000 /* crystal frequency in Hz */
88#define XTBOARD_FLASH_MAXSIZE 0x4000000 /* 64 MB (max; depends on what is socketed!) */
89#define XTBOARD_EPROM_MAXSIZE 0x0400000 /* 4 MB (max; depends on what is socketed!) */
90#define XTBOARD_EEPROM_MAXSIZE 0x0080000 /* 512 kB (max; depends on what is socketed!) */
91#define XTBOARD_ASRAM_SIZE 0x0100000 /* 1 MB */
92#define XTBOARD_PCI_MEM_SIZE 0x8000000 /* 128 MB (allocated) */
93#define XTBOARD_PCI_IO_SIZE 0x1000000 /* 16 MB (allocated) */
94
95#ifdef XSHAL_IOBLOCK_BYPASS_PADDR
96/* PCI memory space: */
97# define XTBOARD_PCI_MEM_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x0000000)
98/* Socketed Flash (eg. 2 x 16-bit devices): */
99# define XTBOARD_FLASH_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0x8000000)
100/* PCI I/O space: */
101# define XTBOARD_PCI_IO_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xC000000)
102/* V3 PCI interface chip register/config space: */
103# define XTBOARD_V3PCI_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD000000)
104/* Bus Interface registers: */
105# define XTBOARD_BUSINT_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD010000)
106/* FPGA registers: */
107# define XT2000_FPGAREGS_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD020000)
108/* SONIC SN83934 Ethernet controller/transceiver: */
109# define SONIC83934_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD030000)
110/* 8-character bitmapped LED display: */
111# define XTBOARD_LED_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD040000)
112/* National-Semi PC16552D DUART: */
113# define DUART16552_1_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD050020) /* channel 1 (P1 - console) */
114# define DUART16552_2_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD050000) /* channel 2 (P2) */
115/* Asynchronous Static RAM: */
116# define XTBOARD_ASRAM_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD400000)
117/* 8-bit EEPROM: */
118# define XTBOARD_EEPROM_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD600000)
119/* 2 x 16-bit EPROMs: */
120# define XTBOARD_EPROM_PADDR (XSHAL_IOBLOCK_BYPASS_PADDR+0xD800000)
121#endif /* XSHAL_IOBLOCK_BYPASS_PADDR */
122
123/* These devices might be accessed cached: */
124#ifdef XSHAL_IOBLOCK_CACHED_PADDR
125# define XTBOARD_PCI_MEM_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x0000000)
126# define XTBOARD_FLASH_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0x8000000)
127# define XTBOARD_ASRAM_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0xD400000)
128# define XTBOARD_EEPROM_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0xD600000)
129# define XTBOARD_EPROM_CACHED_PADDR (XSHAL_IOBLOCK_CACHED_PADDR+0xD800000)
130#endif /* XSHAL_IOBLOCK_CACHED_PADDR */
131
132
133/*** Same thing over again, this time with virtual addresses: ***/
134
135#ifdef XSHAL_IOBLOCK_BYPASS_VADDR
136/* PCI memory space: */
137# define XTBOARD_PCI_MEM_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x0000000)
138/* Socketed Flash (eg. 2 x 16-bit devices): */
139# define XTBOARD_FLASH_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0x8000000)
140/* PCI I/O space: */
141# define XTBOARD_PCI_IO_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xC000000)
142/* V3 PCI interface chip register/config space: */
143# define XTBOARD_V3PCI_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD000000)
144/* Bus Interface registers: */
145# define XTBOARD_BUSINT_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD010000)
146/* FPGA registers: */
147# define XT2000_FPGAREGS_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD020000)
148/* SONIC SN83934 Ethernet controller/transceiver: */
149# define SONIC83934_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD030000)
150/* 8-character bitmapped LED display: */
151# define XTBOARD_LED_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD040000)
152/* National-Semi PC16552D DUART: */
153# define DUART16552_1_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD050020) /* channel 1 (P1 - console) */
154# define DUART16552_2_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD050000) /* channel 2 (P2) */
155/* Asynchronous Static RAM: */
156# define XTBOARD_ASRAM_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD400000)
157/* 8-bit EEPROM: */
158# define XTBOARD_EEPROM_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD600000)
159/* 2 x 16-bit EPROMs: */
160# define XTBOARD_EPROM_VADDR (XSHAL_IOBLOCK_BYPASS_VADDR+0xD800000)
161#endif /* XSHAL_IOBLOCK_BYPASS_VADDR */
162
163/* These devices might be accessed cached: */
164#ifdef XSHAL_IOBLOCK_CACHED_VADDR
165# define XTBOARD_PCI_MEM_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x0000000)
166# define XTBOARD_FLASH_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0x8000000)
167# define XTBOARD_ASRAM_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0xD400000)
168# define XTBOARD_EEPROM_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0xD600000)
169# define XTBOARD_EPROM_CACHED_VADDR (XSHAL_IOBLOCK_CACHED_VADDR+0xD800000)
170#endif /* XSHAL_IOBLOCK_CACHED_VADDR */
171
172
173/* System ROM: */
174#define XTBOARD_ROM_SIZE XSHAL_ROM_SIZE
175#ifdef XSHAL_ROM_VADDR
176#define XTBOARD_ROM_VADDR XSHAL_ROM_VADDR
177#endif
178#ifdef XSHAL_ROM_PADDR
179#define XTBOARD_ROM_PADDR XSHAL_ROM_PADDR
180#endif
181
182/* System RAM: */
183#define XTBOARD_RAM_SIZE XSHAL_RAM_SIZE
184#ifdef XSHAL_RAM_VADDR
185#define XTBOARD_RAM_VADDR XSHAL_RAM_VADDR
186#endif
187#ifdef XSHAL_RAM_PADDR
188#define XTBOARD_RAM_PADDR XSHAL_RAM_PADDR
189#endif
190#define XTBOARD_RAM_BYPASS_VADDR XSHAL_RAM_BYPASS_VADDR
191#define XTBOARD_RAM_BYPASS_PADDR XSHAL_RAM_BYPASS_PADDR
192
193
194
195/*
196 * Things that depend on device addresses.
197 */
198
199
200#define XTBOARD_CACHEATTR_WRITEBACK XSHAL_XT2000_CACHEATTR_WRITEBACK
201#define XTBOARD_CACHEATTR_WRITEALLOC XSHAL_XT2000_CACHEATTR_WRITEALLOC
202#define XTBOARD_CACHEATTR_WRITETHRU XSHAL_XT2000_CACHEATTR_WRITETHRU
203#define XTBOARD_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS
204#define XTBOARD_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT
205
206#define XTBOARD_BUSINT_PIPE_REGIONS XSHAL_XT2000_PIPE_REGIONS
207#define XTBOARD_BUSINT_SDRAM_REGIONS XSHAL_XT2000_SDRAM_REGIONS
208
209
210
211/*
212 * BusLogic (FPGA) registers.
213 * All these registers are normally accessed using 32-bit loads/stores.
214 */
215
216/* Register offsets: */
217#define XT2000_DATECD_OFS 0x00 /* date code (read-only) */
218#define XT2000_STSREG_OFS 0x04 /* status (read-only) */
219#define XT2000_SYSLED_OFS 0x08 /* system LED */
220#define XT2000_WRPROT_OFS 0x0C /* write protect */
221#define XT2000_SWRST_OFS 0x10 /* software reset */
222#define XT2000_SYSRST_OFS 0x14 /* system (peripherals) reset */
223#define XT2000_IMASK_OFS 0x18 /* interrupt mask */
224#define XT2000_ISTAT_OFS 0x1C /* interrupt status */
225#define XT2000_V3CFG_OFS 0x20 /* V3 config (V320 PCI) */
226
227/* Physical register addresses: */
228#ifdef XT2000_FPGAREGS_PADDR
229#define XT2000_DATECD_PADDR (XT2000_FPGAREGS_PADDR+XT2000_DATECD_OFS)
230#define XT2000_STSREG_PADDR (XT2000_FPGAREGS_PADDR+XT2000_STSREG_OFS)
231#define XT2000_SYSLED_PADDR (XT2000_FPGAREGS_PADDR+XT2000_SYSLED_OFS)
232#define XT2000_WRPROT_PADDR (XT2000_FPGAREGS_PADDR+XT2000_WRPROT_OFS)
233#define XT2000_SWRST_PADDR (XT2000_FPGAREGS_PADDR+XT2000_SWRST_OFS)
234#define XT2000_SYSRST_PADDR (XT2000_FPGAREGS_PADDR+XT2000_SYSRST_OFS)
235#define XT2000_IMASK_PADDR (XT2000_FPGAREGS_PADDR+XT2000_IMASK_OFS)
236#define XT2000_ISTAT_PADDR (XT2000_FPGAREGS_PADDR+XT2000_ISTAT_OFS)
237#define XT2000_V3CFG_PADDR (XT2000_FPGAREGS_PADDR+XT2000_V3CFG_OFS)
238#endif
239
240/* Virtual register addresses: */
241#ifdef XT2000_FPGAREGS_VADDR
242#define XT2000_DATECD_VADDR (XT2000_FPGAREGS_VADDR+XT2000_DATECD_OFS)
243#define XT2000_STSREG_VADDR (XT2000_FPGAREGS_VADDR+XT2000_STSREG_OFS)
244#define XT2000_SYSLED_VADDR (XT2000_FPGAREGS_VADDR+XT2000_SYSLED_OFS)
245#define XT2000_WRPROT_VADDR (XT2000_FPGAREGS_VADDR+XT2000_WRPROT_OFS)
246#define XT2000_SWRST_VADDR (XT2000_FPGAREGS_VADDR+XT2000_SWRST_OFS)
247#define XT2000_SYSRST_VADDR (XT2000_FPGAREGS_VADDR+XT2000_SYSRST_OFS)
248#define XT2000_IMASK_VADDR (XT2000_FPGAREGS_VADDR+XT2000_IMASK_OFS)
249#define XT2000_ISTAT_VADDR (XT2000_FPGAREGS_VADDR+XT2000_ISTAT_OFS)
250#define XT2000_V3CFG_VADDR (XT2000_FPGAREGS_VADDR+XT2000_V3CFG_OFS)
251/* Register access (for C code): */
252#define XT2000_DATECD_REG (*(volatile unsigned*) XT2000_DATECD_VADDR)
253#define XT2000_STSREG_REG (*(volatile unsigned*) XT2000_STSREG_VADDR)
254#define XT2000_SYSLED_REG (*(volatile unsigned*) XT2000_SYSLED_VADDR)
255#define XT2000_WRPROT_REG (*(volatile unsigned*) XT2000_WRPROT_VADDR)
256#define XT2000_SWRST_REG (*(volatile unsigned*) XT2000_SWRST_VADDR)
257#define XT2000_SYSRST_REG (*(volatile unsigned*) XT2000_SYSRST_VADDR)
258#define XT2000_IMASK_REG (*(volatile unsigned*) XT2000_IMASK_VADDR)
259#define XT2000_ISTAT_REG (*(volatile unsigned*) XT2000_ISTAT_VADDR)
260#define XT2000_V3CFG_REG (*(volatile unsigned*) XT2000_V3CFG_VADDR)
261#endif
262
263/* DATECD (date code) bit fields: */
264
265/* BCD-coded month (01..12): */
266#define XT2000_DATECD_MONTH_SHIFT 24
267#define XT2000_DATECD_MONTH_BITS 8
268#define XT2000_DATECD_MONTH_MASK 0xFF000000
269/* BCD-coded day (01..31): */
270#define XT2000_DATECD_DAY_SHIFT 16
271#define XT2000_DATECD_DAY_BITS 8
272#define XT2000_DATECD_DAY_MASK 0x00FF0000
273/* BCD-coded year (2001..9999): */
274#define XT2000_DATECD_YEAR_SHIFT 0
275#define XT2000_DATECD_YEAR_BITS 16
276#define XT2000_DATECD_YEAR_MASK 0x0000FFFF
277
278/* STSREG (status) bit fields: */
279
280/* Switch SW3 setting bit fields (0=off/up, 1=on/down): */
281#define XT2000_STSREG_SW3_SHIFT 0
282#define XT2000_STSREG_SW3_BITS 4
283#define XT2000_STSREG_SW3_MASK 0x0000000F
284/* Boot-select bits of switch SW3: */
285#define XT2000_STSREG_BOOTSEL_SHIFT 0
286#define XT2000_STSREG_BOOTSEL_BITS 2
287#define XT2000_STSREG_BOOTSEL_MASK 0x00000003
288/* Boot-select values: */
289#define XT2000_STSREG_BOOTSEL_FLASH 0
290#define XT2000_STSREG_BOOTSEL_EPROM16 1
291#define XT2000_STSREG_BOOTSEL_PROM8 2
292#define XT2000_STSREG_BOOTSEL_ASRAM 3
293/* User-defined bits of switch SW3: */
294#define XT2000_STSREG_SW3_2_SHIFT 2
295#define XT2000_STSREG_SW3_2_MASK 0x00000004
296#define XT2000_STSREG_SW3_3_SHIFT 3
297#define XT2000_STSREG_SW3_3_MASK 0x00000008
298
299/* SYSLED (system LED) bit fields: */
300
301/* LED control bit (0=off, 1=on): */
302#define XT2000_SYSLED_LEDON_SHIFT 0
303#define XT2000_SYSLED_LEDON_MASK 0x00000001
304
305/* WRPROT (write protect) bit fields (0=writable, 1=write-protected [default]): */
306
307/* Flash write protect: */
308#define XT2000_WRPROT_FLWP_SHIFT 0
309#define XT2000_WRPROT_FLWP_MASK 0x00000001
310/* Reserved but present write protect bits: */
311#define XT2000_WRPROT_WRP_SHIFT 1
312#define XT2000_WRPROT_WRP_BITS 7
313#define XT2000_WRPROT_WRP_MASK 0x000000FE
314
315/* SWRST (software reset; allows s/w to generate power-on equivalent reset): */
316
317/* Software reset bits: */
318#define XT2000_SWRST_SWR_SHIFT 0
319#define XT2000_SWRST_SWR_BITS 16
320#define XT2000_SWRST_SWR_MASK 0x0000FFFF
321/* Software reset value -- writing this value resets the board: */
322#define XT2000_SWRST_RESETVALUE 0x0000DEAD
323
324/* SYSRST (system reset; controls reset of individual peripherals): */
325
326/* All-device reset: */
327#define XT2000_SYSRST_ALL_SHIFT 0
328#define XT2000_SYSRST_ALL_BITS 4
329#define XT2000_SYSRST_ALL_MASK 0x0000000F
330/* HDSP-2534 LED display reset (1=reset, 0=nothing): */
331#define XT2000_SYSRST_LED_SHIFT 0
332#define XT2000_SYSRST_LED_MASK 0x00000001
333/* Sonic DP83934 Ethernet controller reset (1=reset, 0=nothing): */
334#define XT2000_SYSRST_SONIC_SHIFT 1
335#define XT2000_SYSRST_SONIC_MASK 0x00000002
336/* DP16552 DUART reset (1=reset, 0=nothing): */
337#define XT2000_SYSRST_DUART_SHIFT 2
338#define XT2000_SYSRST_DUART_MASK 0x00000004
339/* V3 V320 PCI bridge controller reset (1=reset, 0=nothing): */
340#define XT2000_SYSRST_V3_SHIFT 3
341#define XT2000_SYSRST_V3_MASK 0x00000008
342
343/* IMASK (interrupt mask; 0=disable, 1=enable): */
344/* ISTAT (interrupt status; 0=inactive, 1=pending): */
345
346/* PCI INTP interrupt: */
347#define XT2000_INTMUX_PCI_INTP_SHIFT 2
348#define XT2000_INTMUX_PCI_INTP_MASK 0x00000004
349/* PCI INTS interrupt: */
350#define XT2000_INTMUX_PCI_INTS_SHIFT 3
351#define XT2000_INTMUX_PCI_INTS_MASK 0x00000008
352/* PCI INTD interrupt: */
353#define XT2000_INTMUX_PCI_INTD_SHIFT 4
354#define XT2000_INTMUX_PCI_INTD_MASK 0x00000010
355/* V320 PCI controller interrupt: */
356#define XT2000_INTMUX_V3_SHIFT 5
357#define XT2000_INTMUX_V3_MASK 0x00000020
358/* PCI ENUM interrupt: */
359#define XT2000_INTMUX_PCI_ENUM_SHIFT 6
360#define XT2000_INTMUX_PCI_ENUM_MASK 0x00000040
361/* PCI DEG interrupt: */
362#define XT2000_INTMUX_PCI_DEG_SHIFT 7
363#define XT2000_INTMUX_PCI_DEG_MASK 0x00000080
364
365/* V3CFG (V3 config, V320 PCI controller): */
366
367/* V3 address control (0=pass-thru, 1=V3 address bits 31:28 set to 4'b0001 [default]): */
368#define XT2000_V3CFG_V3ADC_SHIFT 0
369#define XT2000_V3CFG_V3ADC_MASK 0x00000001
370
371/* I2C Devices */
372
373#define XT2000_I2C_RTC_ID 0x68
374#define XT2000_I2C_NVRAM0_ID 0x56 /* 1st 256 byte block */
375#define XT2000_I2C_NVRAM1_ID 0x57 /* 2nd 256 byte block */
376
377/* NVRAM Board Info structure: */
378
379#define XT2000_NVRAM_SIZE 512
380
381#define XT2000_NVRAM_BINFO_START 0x100
382#define XT2000_NVRAM_BINFO_SIZE 0x20
383#define XT2000_NVRAM_BINFO_VERSION 0x10 /* version 1.0 */
384#if 0
385#define XT2000_NVRAM_BINFO_VERSION_OFFSET 0x00
386#define XT2000_NVRAM_BINFO_VERSION_SIZE 0x1
387#define XT2000_NVRAM_BINFO_ETH_ADDR_OFFSET 0x02
388#define XT2000_NVRAM_BINFO_ETH_ADDR_SIZE 0x6
389#define XT2000_NVRAM_BINFO_SN_OFFSET 0x10
390#define XT2000_NVRAM_BINFO_SN_SIZE 0xE
391#define XT2000_NVRAM_BINFO_CRC_OFFSET 0x1E
392#define XT2000_NVRAM_BINFO_CRC_SIZE 0x2
393#endif /*0*/
394
395#if !defined(__ASSEMBLY__) && !defined(_NOCLANGUAGE)
396typedef struct xt2000_nvram_binfo {
397 unsigned char version;
398 unsigned char reserved1;
399 unsigned char eth_addr[6];
400 unsigned char reserved8[8];
401 unsigned char serialno[14];
402 unsigned char crc[2]; /* 16-bit CRC */
403} xt2000_nvram_binfo;
404#endif /*!__ASSEMBLY__ && !_NOCLANGUAGE*/
405
406
407#endif /*_INC_XT2000_H_*/
408
diff --git a/include/asm-xtensa/xtensa/xtboard.h b/include/asm-xtensa/xtensa/xtboard.h
new file mode 100644
index 000000000000..22469c175307
--- /dev/null
+++ b/include/asm-xtensa/xtensa/xtboard.h
@@ -0,0 +1,120 @@
1#ifndef _xtboard_h_included_
2#define _xtboard_h_included_
3
4/*
5 * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
6 *
7 * xtboard.h -- Routines for getting useful information from the board.
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 * Copyright (C) 2002 Tensilica Inc.
14 */
15
16
17#include <xtensa/xt2000.h>
18
19#define XTBOARD_RTC_ERROR -1
20#define XTBOARD_RTC_STOPPED -2
21
22
23/* xt2000-i2cdev.c: */
24typedef void XtboardDelayFunc( unsigned );
25extern XtboardDelayFunc* xtboard_set_nsdelay_func( XtboardDelayFunc *delay_fn );
26extern int xtboard_i2c_read (unsigned id, unsigned char *buf, unsigned addr, unsigned size);
27extern int xtboard_i2c_write(unsigned id, unsigned char *buf, unsigned addr, unsigned size);
28extern int xtboard_i2c_wait_nvram_ack(unsigned id, unsigned swtimer);
29
30/* xtboard.c: */
31extern int xtboard_nvram_read (unsigned addr, unsigned len, unsigned char *buf);
32extern int xtboard_nvram_write(unsigned addr, unsigned len, unsigned char *buf);
33extern int xtboard_nvram_binfo_read (xt2000_nvram_binfo *buf);
34extern int xtboard_nvram_binfo_write(xt2000_nvram_binfo *buf);
35extern int xtboard_nvram_binfo_valid(xt2000_nvram_binfo *buf);
36extern int xtboard_ethermac_get(unsigned char *buf);
37extern int xtboard_ethermac_set(unsigned char *buf);
38
39/*+*----------------------------------------------------------------------------
40/ Function: xtboard_get_rtc_time
41/
42/ Description: Get time stored in real-time clock.
43/
44/ Returns: time in seconds stored in real-time clock.
45/-**----------------------------------------------------------------------------*/
46
47extern unsigned xtboard_get_rtc_time(void);
48
49/*+*----------------------------------------------------------------------------
50/ Function: xtboard_set_rtc_time
51/
52/ Description: Set time stored in real-time clock.
53/
54/ Parameters: time -- time in seconds to store to real-time clock
55/
56/ Returns: 0 on success, xtboard_i2c_write() error code otherwise.
57/-**----------------------------------------------------------------------------*/
58
59extern int xtboard_set_rtc_time(unsigned time);
60
61
62/* xtfreq.c: */
63/*+*----------------------------------------------------------------------------
64/ Function: xtboard_measure_sys_clk
65/
66/ Description: Get frequency of system clock.
67/
68/ Parameters: none
69/
70/ Returns: frequency of system clock.
71/-**----------------------------------------------------------------------------*/
72
73extern unsigned xtboard_measure_sys_clk(void);
74
75
76#if 0 /* old stuff from xtboard.c: */
77
78/*+*----------------------------------------------------------------------------
79/ Function: xtboard_nvram valid
80/
81/ Description: Determines if data in NVRAM is valid.
82/
83/ Parameters: delay -- 10us delay function
84/
85/ Returns: 1 if NVRAM is valid, 0 otherwise
86/-**----------------------------------------------------------------------------*/
87
88extern unsigned xtboard_nvram_valid(void (*delay)( void ));
89
90/*+*----------------------------------------------------------------------------
91/ Function: xtboard_get_nvram_contents
92/
93/ Description: Returns contents of NVRAM.
94/
95/ Parameters: buf -- buffer to NVRAM contents.
96/ delay -- 10us delay function
97/
98/ Returns: 1 if NVRAM is valid, 0 otherwise
99/-**----------------------------------------------------------------------------*/
100
101extern unsigned xtboard_get_nvram_contents(unsigned char *buf, void (*delay)( void ));
102
103/*+*----------------------------------------------------------------------------
104/ Function: xtboard_get_ether_addr
105/
106/ Description: Returns ethernet address of board.
107/
108/ Parameters: buf -- buffer to store ethernet address
109/ delay -- 10us delay function
110/
111/ Returns: nothing.
112/-**----------------------------------------------------------------------------*/
113
114extern void xtboard_get_ether_addr(unsigned char *buf, void (*delay)( void ));
115
116#endif /*0*/
117
118
119#endif /*_xtboard_h_included_*/
120
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 7e736e201c46..c1e82c514443 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -69,6 +69,11 @@ extern void remove_arg_zero(struct linux_binprm *);
69extern int search_binary_handler(struct linux_binprm *,struct pt_regs *); 69extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
70extern int flush_old_exec(struct linux_binprm * bprm); 70extern int flush_old_exec(struct linux_binprm * bprm);
71 71
72extern int suid_dumpable;
73#define SUID_DUMP_DISABLE 0 /* No setuid dumping */
74#define SUID_DUMP_USER 1 /* Dump as user of process */
75#define SUID_DUMP_ROOT 2 /* Dump as root */
76
72/* Stack area protections */ 77/* Stack area protections */
73#define EXSTACK_DEFAULT 0 /* Whatever the arch defaults to */ 78#define EXSTACK_DEFAULT 0 /* Whatever the arch defaults to */
74#define EXSTACK_DISABLE_X 1 /* Disable executable stacks */ 79#define EXSTACK_DISABLE_X 1 /* Disable executable stacks */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4a99b76c5a33..60272141ff19 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -285,16 +285,12 @@ enum blk_queue_state {
285 Queue_up, 285 Queue_up,
286}; 286};
287 287
288#define BLK_TAGS_PER_LONG (sizeof(unsigned long) * 8)
289#define BLK_TAGS_MASK (BLK_TAGS_PER_LONG - 1)
290
291struct blk_queue_tag { 288struct blk_queue_tag {
292 struct request **tag_index; /* map of busy tags */ 289 struct request **tag_index; /* map of busy tags */
293 unsigned long *tag_map; /* bit map of free/busy tags */ 290 unsigned long *tag_map; /* bit map of free/busy tags */
294 struct list_head busy_list; /* fifo list of busy tags */ 291 struct list_head busy_list; /* fifo list of busy tags */
295 int busy; /* current depth */ 292 int busy; /* current depth */
296 int max_depth; /* what we will send to device */ 293 int max_depth; /* what we will send to device */
297 int real_max_depth; /* what the array can hold */
298 atomic_t refcnt; /* map can be shared */ 294 atomic_t refcnt; /* map can be shared */
299}; 295};
300 296
@@ -396,6 +392,7 @@ struct request_queue
396 */ 392 */
397 unsigned int sg_timeout; 393 unsigned int sg_timeout;
398 unsigned int sg_reserved_size; 394 unsigned int sg_reserved_size;
395 int node;
399 396
400 struct list_head drain_list; 397 struct list_head drain_list;
401 398
@@ -615,6 +612,8 @@ static inline void blkdev_dequeue_request(struct request *req)
615/* 612/*
616 * Access functions for manipulating queue properties 613 * Access functions for manipulating queue properties
617 */ 614 */
615extern request_queue_t *blk_init_queue_node(request_fn_proc *rfn,
616 spinlock_t *lock, int node_id);
618extern request_queue_t *blk_init_queue(request_fn_proc *, spinlock_t *); 617extern request_queue_t *blk_init_queue(request_fn_proc *, spinlock_t *);
619extern void blk_cleanup_queue(request_queue_t *); 618extern void blk_cleanup_queue(request_queue_t *);
620extern void blk_queue_make_request(request_queue_t *, make_request_fn *); 619extern void blk_queue_make_request(request_queue_t *, make_request_fn *);
@@ -646,7 +645,8 @@ extern void blk_wait_queue_drained(request_queue_t *, int);
646extern void blk_finish_queue_drain(request_queue_t *); 645extern void blk_finish_queue_drain(request_queue_t *);
647 646
648int blk_get_queue(request_queue_t *); 647int blk_get_queue(request_queue_t *);
649request_queue_t *blk_alloc_queue(int); 648request_queue_t *blk_alloc_queue(int gfp_mask);
649request_queue_t *blk_alloc_queue_node(int,int);
650#define blk_put_queue(q) blk_cleanup_queue((q)) 650#define blk_put_queue(q) blk_cleanup_queue((q))
651 651
652/* 652/*
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 0dd8ca1a3d5a..500f451ce0c0 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -67,6 +67,15 @@ extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size,
67 __alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0) 67 __alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0)
68#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ 68#endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
69 69
70#ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
71extern void *alloc_remap(int nid, unsigned long size);
72#else
73static inline void *alloc_remap(int nid, unsigned long size)
74{
75 return NULL;
76}
77#endif
78
70extern unsigned long __initdata nr_kernel_pages; 79extern unsigned long __initdata nr_kernel_pages;
71extern unsigned long __initdata nr_all_pages; 80extern unsigned long __initdata nr_all_pages;
72 81
diff --git a/include/linux/dqblk_v1.h b/include/linux/dqblk_v1.h
index 42fbf4797156..57f1250d5a52 100644
--- a/include/linux/dqblk_v1.h
+++ b/include/linux/dqblk_v1.h
@@ -11,6 +11,12 @@
11/* Root squash turned on */ 11/* Root squash turned on */
12#define V1_DQF_RSQUASH 1 12#define V1_DQF_RSQUASH 1
13 13
14/* Numbers of blocks needed for updates */
15#define V1_INIT_ALLOC 1
16#define V1_INIT_REWRITE 1
17#define V1_DEL_ALLOC 0
18#define V1_DEL_REWRITE 2
19
14/* Special information about quotafile */ 20/* Special information about quotafile */
15struct v1_mem_dqinfo { 21struct v1_mem_dqinfo {
16}; 22};
diff --git a/include/linux/dqblk_v2.h b/include/linux/dqblk_v2.h
index 4a6c5f6867bb..4f853322cb7f 100644
--- a/include/linux/dqblk_v2.h
+++ b/include/linux/dqblk_v2.h
@@ -10,6 +10,12 @@
10/* id numbers of quota format */ 10/* id numbers of quota format */
11#define QFMT_VFS_V0 2 11#define QFMT_VFS_V0 2
12 12
13/* Numbers of blocks needed for updates */
14#define V2_INIT_ALLOC 4
15#define V2_INIT_REWRITE 2
16#define V2_DEL_ALLOC 0
17#define V2_DEL_REWRITE 6
18
13/* Inmemory copy of version specific information */ 19/* Inmemory copy of version specific information */
14struct v2_mem_dqinfo { 20struct v2_mem_dqinfo {
15 unsigned int dqi_blocks; 21 unsigned int dqi_blocks;
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index fab43527e597..a657130ba03a 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -300,18 +300,19 @@ struct ext2_inode {
300/* 300/*
301 * Mount flags 301 * Mount flags
302 */ 302 */
303#define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */ 303#define EXT2_MOUNT_CHECK 0x000001 /* Do mount-time checks */
304#define EXT2_MOUNT_OLDALLOC 0x0002 /* Don't use the new Orlov allocator */ 304#define EXT2_MOUNT_OLDALLOC 0x000002 /* Don't use the new Orlov allocator */
305#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */ 305#define EXT2_MOUNT_GRPID 0x000004 /* Create files with directory's group */
306#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */ 306#define EXT2_MOUNT_DEBUG 0x000008 /* Some debugging messages */
307#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */ 307#define EXT2_MOUNT_ERRORS_CONT 0x000010 /* Continue on errors */
308#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */ 308#define EXT2_MOUNT_ERRORS_RO 0x000020 /* Remount fs ro on errors */
309#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ 309#define EXT2_MOUNT_ERRORS_PANIC 0x000040 /* Panic on errors */
310#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */ 310#define EXT2_MOUNT_MINIX_DF 0x000080 /* Mimics the Minix statfs */
311#define EXT2_MOUNT_NOBH 0x0100 /* No buffer_heads */ 311#define EXT2_MOUNT_NOBH 0x000100 /* No buffer_heads */
312#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ 312#define EXT2_MOUNT_NO_UID32 0x000200 /* Disable 32-bit UIDs */
313#define EXT2_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ 313#define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */
314#define EXT2_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */ 314#define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */
315#define EXT2_MOUNT_XIP 0x010000 /* Execute in place */
315 316
316#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt 317#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
317#define set_opt(o, opt) o |= EXT2_MOUNT_##opt 318#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 74ad31781e3e..4b6e1ab216a5 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -358,6 +358,7 @@ struct ext3_inode {
358#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ 358#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */
359#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ 359#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */
360#define EXT3_MOUNT_NOBH 0x40000 /* No bufferheads */ 360#define EXT3_MOUNT_NOBH 0x40000 /* No bufferheads */
361#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
361 362
362/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ 363/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
363#ifndef _LINUX_EXT2_FS_H 364#ifndef _LINUX_EXT2_FS_H
diff --git a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
index e8292af9033b..c8307c02dd07 100644
--- a/include/linux/ext3_jbd.h
+++ b/include/linux/ext3_jbd.h
@@ -42,15 +42,15 @@
42 * superblock only gets updated once, of course, so don't bother 42 * superblock only gets updated once, of course, so don't bother
43 * counting that again for the quota updates. */ 43 * counting that again for the quota updates. */
44 44
45#define EXT3_DATA_TRANS_BLOCKS (EXT3_SINGLEDATA_TRANS_BLOCKS + \ 45#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \
46 EXT3_XATTR_TRANS_BLOCKS - 2 + \ 46 EXT3_XATTR_TRANS_BLOCKS - 2 + \
47 2*EXT3_QUOTA_TRANS_BLOCKS) 47 2*EXT3_QUOTA_TRANS_BLOCKS(sb))
48 48
49/* Delete operations potentially hit one directory's namespace plus an 49/* Delete operations potentially hit one directory's namespace plus an
50 * entire inode, plus arbitrary amounts of bitmap/indirection data. Be 50 * entire inode, plus arbitrary amounts of bitmap/indirection data. Be
51 * generous. We can grow the delete transaction later if necessary. */ 51 * generous. We can grow the delete transaction later if necessary. */
52 52
53#define EXT3_DELETE_TRANS_BLOCKS (2 * EXT3_DATA_TRANS_BLOCKS + 64) 53#define EXT3_DELETE_TRANS_BLOCKS(sb) (2 * EXT3_DATA_TRANS_BLOCKS(sb) + 64)
54 54
55/* Define an arbitrary limit for the amount of data we will anticipate 55/* Define an arbitrary limit for the amount of data we will anticipate
56 * writing to any given transaction. For unbounded transactions such as 56 * writing to any given transaction. For unbounded transactions such as
@@ -74,14 +74,17 @@
74#ifdef CONFIG_QUOTA 74#ifdef CONFIG_QUOTA
75/* Amount of blocks needed for quota update - we know that the structure was 75/* Amount of blocks needed for quota update - we know that the structure was
76 * allocated so we need to update only inode+data */ 76 * allocated so we need to update only inode+data */
77#define EXT3_QUOTA_TRANS_BLOCKS 2 77#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
78/* Amount of blocks needed for quota insert/delete - we do some block writes 78/* Amount of blocks needed for quota insert/delete - we do some block writes
79 * but inode, sb and group updates are done only once */ 79 * but inode, sb and group updates are done only once */
80#define EXT3_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*\ 80#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
81 (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3) 81 (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
82#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
83 (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
82#else 84#else
83#define EXT3_QUOTA_TRANS_BLOCKS 0 85#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0
84#define EXT3_QUOTA_INIT_BLOCKS 0 86#define EXT3_QUOTA_INIT_BLOCKS(sb) 0
87#define EXT3_QUOTA_DEL_BLOCKS(sb) 0
85#endif 88#endif
86 89
87int 90int
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 704fb76b6334..8a7c82151de9 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -25,6 +25,10 @@
25 25
26#ifdef __KERNEL__ 26#ifdef __KERNEL__
27 27
28#ifndef force_o_largefile
29#define force_o_largefile() (BITS_PER_LONG != 32)
30#endif
31
28#if BITS_PER_LONG == 32 32#if BITS_PER_LONG == 32
29#define IS_GETLK32(cmd) ((cmd) == F_GETLK) 33#define IS_GETLK32(cmd) ((cmd) == F_GETLK)
30#define IS_SETLK32(cmd) ((cmd) == F_SETLK) 34#define IS_SETLK32(cmd) ((cmd) == F_SETLK)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index e5a8db00df29..3ae8e37bdfc8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -220,6 +220,7 @@ extern int dir_notify_enable;
220 220
221struct iovec; 221struct iovec;
222struct nameidata; 222struct nameidata;
223struct kiocb;
223struct pipe_inode_info; 224struct pipe_inode_info;
224struct poll_table_struct; 225struct poll_table_struct;
225struct kstatfs; 226struct kstatfs;
@@ -240,7 +241,7 @@ typedef int (get_block_t)(struct inode *inode, sector_t iblock,
240typedef int (get_blocks_t)(struct inode *inode, sector_t iblock, 241typedef int (get_blocks_t)(struct inode *inode, sector_t iblock,
241 unsigned long max_blocks, 242 unsigned long max_blocks,
242 struct buffer_head *bh_result, int create); 243 struct buffer_head *bh_result, int create);
243typedef void (dio_iodone_t)(struct inode *inode, loff_t offset, 244typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
244 ssize_t bytes, void *private); 245 ssize_t bytes, void *private);
245 246
246/* 247/*
@@ -302,7 +303,6 @@ struct iattr {
302struct page; 303struct page;
303struct address_space; 304struct address_space;
304struct writeback_control; 305struct writeback_control;
305struct kiocb;
306 306
307struct address_space_operations { 307struct address_space_operations {
308 int (*writepage)(struct page *page, struct writeback_control *wbc); 308 int (*writepage)(struct page *page, struct writeback_control *wbc);
@@ -330,6 +330,8 @@ struct address_space_operations {
330 int (*releasepage) (struct page *, int); 330 int (*releasepage) (struct page *, int);
331 ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, 331 ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
332 loff_t offset, unsigned long nr_segs); 332 loff_t offset, unsigned long nr_segs);
333 struct page* (*get_xip_page)(struct address_space *, sector_t,
334 int);
333}; 335};
334 336
335struct backing_dev_info; 337struct backing_dev_info;
@@ -581,7 +583,6 @@ struct file {
581 atomic_t f_count; 583 atomic_t f_count;
582 unsigned int f_flags; 584 unsigned int f_flags;
583 mode_t f_mode; 585 mode_t f_mode;
584 int f_error;
585 loff_t f_pos; 586 loff_t f_pos;
586 struct fown_struct f_owner; 587 struct fown_struct f_owner;
587 unsigned int f_uid, f_gid; 588 unsigned int f_uid, f_gid;
@@ -884,7 +885,9 @@ struct block_device_operations {
884 int (*open) (struct inode *, struct file *); 885 int (*open) (struct inode *, struct file *);
885 int (*release) (struct inode *, struct file *); 886 int (*release) (struct inode *, struct file *);
886 int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); 887 int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
888 long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
887 long (*compat_ioctl) (struct file *, unsigned, unsigned long); 889 long (*compat_ioctl) (struct file *, unsigned, unsigned long);
890 int (*direct_access) (struct block_device *, sector_t, unsigned long *);
888 int (*media_changed) (struct gendisk *); 891 int (*media_changed) (struct gendisk *);
889 int (*revalidate_disk) (struct gendisk *); 892 int (*revalidate_disk) (struct gendisk *);
890 struct module *owner; 893 struct module *owner;
@@ -1025,6 +1028,7 @@ struct super_operations {
1025#define I_FREEING 16 1028#define I_FREEING 16
1026#define I_CLEAR 32 1029#define I_CLEAR 32
1027#define I_NEW 64 1030#define I_NEW 64
1031#define I_WILL_FREE 128
1028 1032
1029#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) 1033#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
1030 1034
@@ -1495,6 +1499,23 @@ extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
1495extern int generic_file_open(struct inode * inode, struct file * filp); 1499extern int generic_file_open(struct inode * inode, struct file * filp);
1496extern int nonseekable_open(struct inode * inode, struct file * filp); 1500extern int nonseekable_open(struct inode * inode, struct file * filp);
1497 1501
1502#ifdef CONFIG_FS_XIP
1503extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len,
1504 loff_t *ppos);
1505extern ssize_t xip_file_sendfile(struct file *in_file, loff_t *ppos,
1506 size_t count, read_actor_t actor,
1507 void *target);
1508extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);
1509extern ssize_t xip_file_write(struct file *filp, const char __user *buf,
1510 size_t len, loff_t *ppos);
1511extern int xip_truncate_page(struct address_space *mapping, loff_t from);
1512#else
1513static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
1514{
1515 return 0;
1516}
1517#endif
1518
1498static inline void do_generic_file_read(struct file * filp, loff_t *ppos, 1519static inline void do_generic_file_read(struct file * filp, loff_t *ppos,
1499 read_descriptor_t * desc, 1520 read_descriptor_t * desc,
1500 read_actor_t actor) 1521 read_actor_t actor)
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 47dedaf971d6..01796c41c951 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -224,7 +224,7 @@ static inline void free_disk_stats(struct gendisk *disk)
224extern void disk_round_stats(struct gendisk *disk); 224extern void disk_round_stats(struct gendisk *disk);
225 225
226/* drivers/block/genhd.c */ 226/* drivers/block/genhd.c */
227extern int get_blkdev_list(char *); 227extern int get_blkdev_list(char *, int);
228extern void add_disk(struct gendisk *disk); 228extern void add_disk(struct gendisk *disk);
229extern void del_gendisk(struct gendisk *gp); 229extern void del_gendisk(struct gendisk *gp);
230extern void unlink_gendisk(struct gendisk *gp); 230extern void unlink_gendisk(struct gendisk *gp);
@@ -403,6 +403,7 @@ extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
403extern void add_partition(struct gendisk *, int, sector_t, sector_t); 403extern void add_partition(struct gendisk *, int, sector_t, sector_t);
404extern void delete_partition(struct gendisk *, int); 404extern void delete_partition(struct gendisk *, int);
405 405
406extern struct gendisk *alloc_disk_node(int minors, int node_id);
406extern struct gendisk *alloc_disk(int minors); 407extern struct gendisk *alloc_disk(int minors);
407extern struct kobject *get_disk(struct gendisk *disk); 408extern struct kobject *get_disk(struct gendisk *disk);
408extern void put_disk(struct gendisk *disk); 409extern void put_disk(struct gendisk *disk);
diff --git a/include/linux/i2o-dev.h b/include/linux/i2o-dev.h
index ef7f644dd873..36fd18cdad28 100644
--- a/include/linux/i2o-dev.h
+++ b/include/linux/i2o-dev.h
@@ -24,6 +24,13 @@
24#define MAX_I2O_CONTROLLERS 32 24#define MAX_I2O_CONTROLLERS 32
25 25
26//#include <linux/ioctl.h> 26//#include <linux/ioctl.h>
27#ifndef __KERNEL__
28
29typedef unsigned char u8;
30typedef unsigned short u16;
31typedef unsigned int u32;
32
33#endif /* __KERNEL__ */
27 34
28/* 35/*
29 * I2O Control IOCTLs and structures 36 * I2O Control IOCTLs and structures
@@ -113,6 +120,10 @@ struct i2o_evt_get {
113 int lost; 120 int lost;
114}; 121};
115 122
123typedef struct i2o_sg_io_hdr {
124 unsigned int flags; /* see I2O_DPT_SG_IO_FLAGS */
125} i2o_sg_io_hdr_t;
126
116/************************************************************************** 127/**************************************************************************
117 * HRT related constants and structures 128 * HRT related constants and structures
118 **************************************************************************/ 129 **************************************************************************/
@@ -126,14 +137,6 @@ struct i2o_evt_get {
126#define I2O_BUS_CARDBUS 7 137#define I2O_BUS_CARDBUS 7
127#define I2O_BUS_UNKNOWN 0x80 138#define I2O_BUS_UNKNOWN 0x80
128 139
129#ifndef __KERNEL__
130
131typedef unsigned char u8;
132typedef unsigned short u16;
133typedef unsigned int u32;
134
135#endif /* __KERNEL__ */
136
137typedef struct _i2o_pci_bus { 140typedef struct _i2o_pci_bus {
138 u8 PciFunctionNumber; 141 u8 PciFunctionNumber;
139 u8 PciDeviceNumber; 142 u8 PciDeviceNumber;
@@ -333,7 +336,7 @@ typedef struct _i2o_status_block {
333#define I2O_CLASS_ATE_PERIPHERAL 0x061 336#define I2O_CLASS_ATE_PERIPHERAL 0x061
334#define I2O_CLASS_FLOPPY_CONTROLLER 0x070 337#define I2O_CLASS_FLOPPY_CONTROLLER 0x070
335#define I2O_CLASS_FLOPPY_DEVICE 0x071 338#define I2O_CLASS_FLOPPY_DEVICE 0x071
336#define I2O_CLASS_BUS_ADAPTER_PORT 0x080 339#define I2O_CLASS_BUS_ADAPTER 0x080
337#define I2O_CLASS_PEER_TRANSPORT_AGENT 0x090 340#define I2O_CLASS_PEER_TRANSPORT_AGENT 0x090
338#define I2O_CLASS_PEER_TRANSPORT 0x091 341#define I2O_CLASS_PEER_TRANSPORT 0x091
339#define I2O_CLASS_END 0xfff 342#define I2O_CLASS_END 0xfff
@@ -399,4 +402,26 @@ typedef struct _i2o_status_block {
399#define ADAPTER_STATE_FAILED 0x10 402#define ADAPTER_STATE_FAILED 0x10
400#define ADAPTER_STATE_FAULTED 0x11 403#define ADAPTER_STATE_FAULTED 0x11
401 404
405/*
406 * Software module types
407 */
408#define I2O_SOFTWARE_MODULE_IRTOS 0x11
409#define I2O_SOFTWARE_MODULE_IOP_PRIVATE 0x22
410#define I2O_SOFTWARE_MODULE_IOP_CONFIG 0x23
411
412/*
413 * Vendors
414 */
415#define I2O_VENDOR_DPT 0x001b
416
417/*
418 * DPT / Adaptec specific values for i2o_sg_io_hdr flags.
419 */
420#define I2O_DPT_SG_FLAG_INTERPRET 0x00010000
421#define I2O_DPT_SG_FLAG_PHYSICAL 0x00020000
422
423#define I2O_DPT_FLASH_FRAG_SIZE 0x10000
424#define I2O_DPT_FLASH_READ 0x0101
425#define I2O_DPT_FLASH_WRITE 0x0102
426
402#endif /* _I2O_DEV_H */ 427#endif /* _I2O_DEV_H */
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index ea9a3ad4b67f..bdc286ec947c 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -119,12 +119,21 @@ struct i2o_driver {
119}; 119};
120 120
121/* 121/*
122 * Contains all information which are necessary for DMA operations 122 * Contains DMA mapped address information
123 */ 123 */
124struct i2o_dma { 124struct i2o_dma {
125 void *virt; 125 void *virt;
126 dma_addr_t phys; 126 dma_addr_t phys;
127 u32 len; 127 size_t len;
128};
129
130/*
131 * Contains IO mapped address information
132 */
133struct i2o_io {
134 void __iomem *virt;
135 unsigned long phys;
136 unsigned long len;
128}; 137};
129 138
130/* 139/*
@@ -147,28 +156,25 @@ struct i2o_controller {
147 156
148 struct pci_dev *pdev; /* PCI device */ 157 struct pci_dev *pdev; /* PCI device */
149 158
150 unsigned int short_req:1; /* use small block sizes */ 159 unsigned int promise:1; /* Promise controller */
160 unsigned int adaptec:1; /* DPT / Adaptec controller */
161 unsigned int raptor:1; /* split bar */
151 unsigned int no_quiesce:1; /* dont quiesce before reset */ 162 unsigned int no_quiesce:1; /* dont quiesce before reset */
152 unsigned int raptor:1; /* split bar */ 163 unsigned int short_req:1; /* use small block sizes */
153 unsigned int promise:1; /* Promise controller */ 164 unsigned int limit_sectors:1; /* limit number of sectors / request */
154 165 unsigned int pae_support:1; /* controller has 64-bit SGL support */
155#ifdef CONFIG_MTRR
156 int mtrr_reg0;
157 int mtrr_reg1;
158#endif
159 166
160 struct list_head devices; /* list of I2O devices */ 167 struct list_head devices; /* list of I2O devices */
161
162 struct notifier_block *event_notifer; /* Events */
163 atomic_t users;
164 struct list_head list; /* Controller list */ 168 struct list_head list; /* Controller list */
165 void __iomem *post_port; /* Inbout port address */ 169
166 void __iomem *reply_port; /* Outbound port address */ 170 void __iomem *in_port; /* Inbout port address */
167 void __iomem *irq_mask; /* Interrupt register address */ 171 void __iomem *out_port; /* Outbound port address */
172 void __iomem *irq_status; /* Interrupt status register address */
173 void __iomem *irq_mask; /* Interrupt mask register address */
168 174
169 /* Dynamic LCT related data */ 175 /* Dynamic LCT related data */
170 176
171 struct i2o_dma status; /* status of IOP */ 177 struct i2o_dma status; /* IOP status block */
172 178
173 struct i2o_dma hrt; /* HW Resource Table */ 179 struct i2o_dma hrt; /* HW Resource Table */
174 i2o_lct *lct; /* Logical Config Table */ 180 i2o_lct *lct; /* Logical Config Table */
@@ -176,21 +182,19 @@ struct i2o_controller {
176 struct semaphore lct_lock; /* Lock for LCT updates */ 182 struct semaphore lct_lock; /* Lock for LCT updates */
177 struct i2o_dma status_block; /* IOP status block */ 183 struct i2o_dma status_block; /* IOP status block */
178 184
179 struct i2o_dma base; /* controller messaging unit */ 185 struct i2o_io base; /* controller messaging unit */
180 struct i2o_dma in_queue; /* inbound message queue Host->IOP */ 186 struct i2o_io in_queue; /* inbound message queue Host->IOP */
181 struct i2o_dma out_queue; /* outbound message queue IOP->Host */ 187 struct i2o_dma out_queue; /* outbound message queue IOP->Host */
182 188
183 unsigned int battery:1; /* Has a battery backup */ 189 unsigned int battery:1; /* Has a battery backup */
184 unsigned int io_alloc:1; /* An I/O resource was allocated */ 190 unsigned int io_alloc:1; /* An I/O resource was allocated */
185 unsigned int mem_alloc:1; /* A memory resource was allocated */ 191 unsigned int mem_alloc:1; /* A memory resource was allocated */
186 192
187 struct resource io_resource; /* I/O resource allocated to the IOP */ 193 struct resource io_resource; /* I/O resource allocated to the IOP */
188 struct resource mem_resource; /* Mem resource allocated to the IOP */ 194 struct resource mem_resource; /* Mem resource allocated to the IOP */
189 195
190 struct proc_dir_entry *proc_entry; /* /proc dir */
191
192 struct list_head bus_list; /* list of busses on IOP */
193 struct device device; 196 struct device device;
197 struct class_device classdev; /* I2O controller class */
194 struct i2o_device *exec; /* Executive */ 198 struct i2o_device *exec; /* Executive */
195#if BITS_PER_LONG == 64 199#if BITS_PER_LONG == 64
196 spinlock_t context_list_lock; /* lock for context_list */ 200 spinlock_t context_list_lock; /* lock for context_list */
@@ -241,9 +245,10 @@ struct i2o_sys_tbl {
241extern struct list_head i2o_controllers; 245extern struct list_head i2o_controllers;
242 246
243/* Message functions */ 247/* Message functions */
244static inline u32 i2o_msg_get(struct i2o_controller *, struct i2o_message __iomem **); 248static inline u32 i2o_msg_get(struct i2o_controller *,
245extern u32 i2o_msg_get_wait(struct i2o_controller *, struct i2o_message __iomem **, 249 struct i2o_message __iomem **);
246 int); 250extern u32 i2o_msg_get_wait(struct i2o_controller *,
251 struct i2o_message __iomem **, int);
247static inline void i2o_msg_post(struct i2o_controller *, u32); 252static inline void i2o_msg_post(struct i2o_controller *, u32);
248static inline int i2o_msg_post_wait(struct i2o_controller *, u32, 253static inline int i2o_msg_post_wait(struct i2o_controller *, u32,
249 unsigned long); 254 unsigned long);
@@ -252,15 +257,6 @@ extern int i2o_msg_post_wait_mem(struct i2o_controller *, u32, unsigned long,
252extern void i2o_msg_nop(struct i2o_controller *, u32); 257extern void i2o_msg_nop(struct i2o_controller *, u32);
253static inline void i2o_flush_reply(struct i2o_controller *, u32); 258static inline void i2o_flush_reply(struct i2o_controller *, u32);
254 259
255/* DMA handling functions */
256static inline int i2o_dma_alloc(struct device *, struct i2o_dma *, size_t,
257 unsigned int);
258static inline void i2o_dma_free(struct device *, struct i2o_dma *);
259int i2o_dma_realloc(struct device *, struct i2o_dma *, size_t, unsigned int);
260
261static inline int i2o_dma_map(struct device *, struct i2o_dma *);
262static inline void i2o_dma_unmap(struct device *, struct i2o_dma *);
263
264/* IOP functions */ 260/* IOP functions */
265extern int i2o_status_get(struct i2o_controller *); 261extern int i2o_status_get(struct i2o_controller *);
266 262
@@ -285,6 +281,16 @@ static inline u32 i2o_ptr_high(void *ptr)
285{ 281{
286 return (u32) ((u64) ptr >> 32); 282 return (u32) ((u64) ptr >> 32);
287}; 283};
284
285static inline u32 i2o_dma_low(dma_addr_t dma_addr)
286{
287 return (u32) (u64) dma_addr;
288};
289
290static inline u32 i2o_dma_high(dma_addr_t dma_addr)
291{
292 return (u32) ((u64) dma_addr >> 32);
293};
288#else 294#else
289static inline u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr) 295static inline u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr)
290{ 296{
@@ -315,8 +321,246 @@ static inline u32 i2o_ptr_high(void *ptr)
315{ 321{
316 return 0; 322 return 0;
317}; 323};
324
325static inline u32 i2o_dma_low(dma_addr_t dma_addr)
326{
327 return (u32) dma_addr;
328};
329
330static inline u32 i2o_dma_high(dma_addr_t dma_addr)
331{
332 return 0;
333};
318#endif 334#endif
319 335
336/**
337 * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
338 * @c: I2O controller for which the calculation should be done
339 * @body_size: maximum body size used for message in 32-bit words.
340 *
341 * Return the maximum number of SG elements in a SG list.
342 */
343static inline u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
344{
345 i2o_status_block *sb = c->status_block.virt;
346 u16 sg_count =
347 (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
348 body_size;
349
350 if (c->pae_support) {
351 /*
352 * for 64-bit a SG attribute element must be added and each
353 * SG element needs 12 bytes instead of 8.
354 */
355 sg_count -= 2;
356 sg_count /= 3;
357 } else
358 sg_count /= 2;
359
360 if (c->short_req && (sg_count > 8))
361 sg_count = 8;
362
363 return sg_count;
364};
365
366/**
367 * i2o_dma_map_single - Map pointer to controller and fill in I2O message.
368 * @c: I2O controller
369 * @ptr: pointer to the data which should be mapped
370 * @size: size of data in bytes
371 * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
372 * @sg_ptr: pointer to the SG list inside the I2O message
373 *
374 * This function does all necessary DMA handling and also writes the I2O
375 * SGL elements into the I2O message. For details on DMA handling see also
376 * dma_map_single(). The pointer sg_ptr will only be set to the end of the
377 * SG list if the allocation was successful.
378 *
379 * Returns DMA address which must be checked for failures using
380 * dma_mapping_error().
381 */
382static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
383 size_t size,
384 enum dma_data_direction direction,
385 u32 __iomem ** sg_ptr)
386{
387 u32 sg_flags;
388 u32 __iomem *mptr = *sg_ptr;
389 dma_addr_t dma_addr;
390
391 switch (direction) {
392 case DMA_TO_DEVICE:
393 sg_flags = 0xd4000000;
394 break;
395 case DMA_FROM_DEVICE:
396 sg_flags = 0xd0000000;
397 break;
398 default:
399 return 0;
400 }
401
402 dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
403 if (!dma_mapping_error(dma_addr)) {
404#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
405 if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
406 writel(0x7C020002, mptr++);
407 writel(PAGE_SIZE, mptr++);
408 }
409#endif
410
411 writel(sg_flags | size, mptr++);
412 writel(i2o_dma_low(dma_addr), mptr++);
413#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
414 if ((sizeof(dma_addr_t) > 4) && c->pae_support)
415 writel(i2o_dma_high(dma_addr), mptr++);
416#endif
417 *sg_ptr = mptr;
418 }
419 return dma_addr;
420};
421
422/**
423 * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
424 * @c: I2O controller
425 * @sg: SG list to be mapped
426 * @sg_count: number of elements in the SG list
427 * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
428 * @sg_ptr: pointer to the SG list inside the I2O message
429 *
430 * This function does all necessary DMA handling and also writes the I2O
431 * SGL elements into the I2O message. For details on DMA handling see also
432 * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
433 * list if the allocation was successful.
434 *
435 * Returns 0 on failure or 1 on success.
436 */
437static inline int i2o_dma_map_sg(struct i2o_controller *c,
438 struct scatterlist *sg, int sg_count,
439 enum dma_data_direction direction,
440 u32 __iomem ** sg_ptr)
441{
442 u32 sg_flags;
443 u32 __iomem *mptr = *sg_ptr;
444
445 switch (direction) {
446 case DMA_TO_DEVICE:
447 sg_flags = 0x14000000;
448 break;
449 case DMA_FROM_DEVICE:
450 sg_flags = 0x10000000;
451 break;
452 default:
453 return 0;
454 }
455
456 sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
457 if (!sg_count)
458 return 0;
459
460#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
461 if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
462 writel(0x7C020002, mptr++);
463 writel(PAGE_SIZE, mptr++);
464 }
465#endif
466
467 while (sg_count-- > 0) {
468 if (!sg_count)
469 sg_flags |= 0xC0000000;
470 writel(sg_flags | sg_dma_len(sg), mptr++);
471 writel(i2o_dma_low(sg_dma_address(sg)), mptr++);
472#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
473 if ((sizeof(dma_addr_t) > 4) && c->pae_support)
474 writel(i2o_dma_high(sg_dma_address(sg)), mptr++);
475#endif
476 sg++;
477 }
478 *sg_ptr = mptr;
479
480 return 1;
481};
482
483/**
484 * i2o_dma_alloc - Allocate DMA memory
485 * @dev: struct device pointer to the PCI device of the I2O controller
486 * @addr: i2o_dma struct which should get the DMA buffer
487 * @len: length of the new DMA memory
488 * @gfp_mask: GFP mask
489 *
490 * Allocate a coherent DMA memory and write the pointers into addr.
491 *
492 * Returns 0 on success or -ENOMEM on failure.
493 */
494static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
495 size_t len, unsigned int gfp_mask)
496{
497 struct pci_dev *pdev = to_pci_dev(dev);
498 int dma_64 = 0;
499
500 if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
501 dma_64 = 1;
502 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
503 return -ENOMEM;
504 }
505
506 addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
507
508 if ((sizeof(dma_addr_t) > 4) && dma_64)
509 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
510 printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
511
512 if (!addr->virt)
513 return -ENOMEM;
514
515 memset(addr->virt, 0, len);
516 addr->len = len;
517
518 return 0;
519};
520
521/**
522 * i2o_dma_free - Free DMA memory
523 * @dev: struct device pointer to the PCI device of the I2O controller
524 * @addr: i2o_dma struct which contains the DMA buffer
525 *
526 * Free a coherent DMA memory and set virtual address of addr to NULL.
527 */
528static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
529{
530 if (addr->virt) {
531 if (addr->phys)
532 dma_free_coherent(dev, addr->len, addr->virt,
533 addr->phys);
534 else
535 kfree(addr->virt);
536 addr->virt = NULL;
537 }
538};
539
540/**
541 * i2o_dma_realloc - Realloc DMA memory
542 * @dev: struct device pointer to the PCI device of the I2O controller
543 * @addr: pointer to a i2o_dma struct DMA buffer
544 * @len: new length of memory
545 * @gfp_mask: GFP mask
546 *
547 * If there was something allocated in the addr, free it first. If len > 0
548 * than try to allocate it and write the addresses back to the addr
549 * structure. If len == 0 set the virtual address to NULL.
550 *
551 * Returns the 0 on success or negative error code on failure.
552 */
553static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
554 size_t len, unsigned int gfp_mask)
555{
556 i2o_dma_free(dev, addr);
557
558 if (len)
559 return i2o_dma_alloc(dev, addr, len, gfp_mask);
560
561 return 0;
562};
563
320/* I2O driver (OSM) functions */ 564/* I2O driver (OSM) functions */
321extern int i2o_driver_register(struct i2o_driver *); 565extern int i2o_driver_register(struct i2o_driver *);
322extern void i2o_driver_unregister(struct i2o_driver *); 566extern void i2o_driver_unregister(struct i2o_driver *);
@@ -385,49 +629,11 @@ extern int i2o_device_claim_release(struct i2o_device *);
385/* Exec OSM functions */ 629/* Exec OSM functions */
386extern int i2o_exec_lct_get(struct i2o_controller *); 630extern int i2o_exec_lct_get(struct i2o_controller *);
387 631
388/* device to i2o_device and driver to i2o_driver convertion functions */ 632/* device / driver / kobject conversion functions */
389#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver) 633#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
390#define to_i2o_device(dev) container_of(dev, struct i2o_device, device) 634#define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
391 635#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
392/* 636#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))
393 * Messenger inlines
394 */
395static inline u32 I2O_POST_READ32(struct i2o_controller *c)
396{
397 rmb();
398 return readl(c->post_port);
399};
400
401static inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 val)
402{
403 wmb();
404 writel(val, c->post_port);
405};
406
407static inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
408{
409 rmb();
410 return readl(c->reply_port);
411};
412
413static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 val)
414{
415 wmb();
416 writel(val, c->reply_port);
417};
418
419static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
420{
421 rmb();
422 return readl(c->irq_mask);
423};
424
425static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val)
426{
427 wmb();
428 writel(val, c->irq_mask);
429 wmb();
430};
431 637
432/** 638/**
433 * i2o_msg_get - obtain an I2O message from the IOP 639 * i2o_msg_get - obtain an I2O message from the IOP
@@ -443,11 +649,11 @@ static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val)
443 * available returns I2O_QUEUE_EMPTY and msg is leaved untouched. 649 * available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
444 */ 650 */
445static inline u32 i2o_msg_get(struct i2o_controller *c, 651static inline u32 i2o_msg_get(struct i2o_controller *c,
446 struct i2o_message __iomem **msg) 652 struct i2o_message __iomem ** msg)
447{ 653{
448 u32 m; 654 u32 m = readl(c->in_port);
449 655
450 if ((m = I2O_POST_READ32(c)) != I2O_QUEUE_EMPTY) 656 if (m != I2O_QUEUE_EMPTY)
451 *msg = c->in_queue.virt + m; 657 *msg = c->in_queue.virt + m;
452 658
453 return m; 659 return m;
@@ -462,7 +668,7 @@ static inline u32 i2o_msg_get(struct i2o_controller *c,
462 */ 668 */
463static inline void i2o_msg_post(struct i2o_controller *c, u32 m) 669static inline void i2o_msg_post(struct i2o_controller *c, u32 m)
464{ 670{
465 I2O_POST_WRITE32(c, m); 671 writel(m, c->in_port);
466}; 672};
467 673
468/** 674/**
@@ -491,12 +697,10 @@ static inline int i2o_msg_post_wait(struct i2o_controller *c, u32 m,
491 * The I2O controller must be informed that the reply message is not needed 697 * The I2O controller must be informed that the reply message is not needed
492 * anymore. If you forget to flush the reply, the message frame can't be 698 * anymore. If you forget to flush the reply, the message frame can't be
493 * used by the controller anymore and is therefore lost. 699 * used by the controller anymore and is therefore lost.
494 *
495 * FIXME: is there a timeout after which the controller reuse the message?
496 */ 700 */
497static inline void i2o_flush_reply(struct i2o_controller *c, u32 m) 701static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
498{ 702{
499 I2O_REPLY_WRITE32(c, m); 703 writel(m, c->out_port);
500}; 704};
501 705
502/** 706/**
@@ -530,97 +734,13 @@ static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c,
530 * work for receive side messages as they are kmalloc objects 734 * work for receive side messages as they are kmalloc objects
531 * in a different pool. 735 * in a different pool.
532 */ 736 */
533static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct i2o_controller *c, 737static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct
534 u32 m) 738 i2o_controller *c,
739 u32 m)
535{ 740{
536 return c->in_queue.virt + m; 741 return c->in_queue.virt + m;
537}; 742};
538 743
539/**
540 * i2o_dma_alloc - Allocate DMA memory
541 * @dev: struct device pointer to the PCI device of the I2O controller
542 * @addr: i2o_dma struct which should get the DMA buffer
543 * @len: length of the new DMA memory
544 * @gfp_mask: GFP mask
545 *
546 * Allocate a coherent DMA memory and write the pointers into addr.
547 *
548 * Returns 0 on success or -ENOMEM on failure.
549 */
550static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
551 size_t len, unsigned int gfp_mask)
552{
553 addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
554 if (!addr->virt)
555 return -ENOMEM;
556
557 memset(addr->virt, 0, len);
558 addr->len = len;
559
560 return 0;
561};
562
563/**
564 * i2o_dma_free - Free DMA memory
565 * @dev: struct device pointer to the PCI device of the I2O controller
566 * @addr: i2o_dma struct which contains the DMA buffer
567 *
568 * Free a coherent DMA memory and set virtual address of addr to NULL.
569 */
570static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
571{
572 if (addr->virt) {
573 if (addr->phys)
574 dma_free_coherent(dev, addr->len, addr->virt,
575 addr->phys);
576 else
577 kfree(addr->virt);
578 addr->virt = NULL;
579 }
580};
581
582/**
583 * i2o_dma_map - Map the memory to DMA
584 * @dev: struct device pointer to the PCI device of the I2O controller
585 * @addr: i2o_dma struct which should be mapped
586 *
587 * Map the memory in addr->virt to coherent DMA memory and write the
588 * physical address into addr->phys.
589 *
590 * Returns 0 on success or -ENOMEM on failure.
591 */
592static inline int i2o_dma_map(struct device *dev, struct i2o_dma *addr)
593{
594 if (!addr->virt)
595 return -EFAULT;
596
597 if (!addr->phys)
598 addr->phys = dma_map_single(dev, addr->virt, addr->len,
599 DMA_BIDIRECTIONAL);
600 if (!addr->phys)
601 return -ENOMEM;
602
603 return 0;
604};
605
606/**
607 * i2o_dma_unmap - Unmap the DMA memory
608 * @dev: struct device pointer to the PCI device of the I2O controller
609 * @addr: i2o_dma struct which should be unmapped
610 *
611 * Unmap the memory in addr->virt from DMA memory.
612 */
613static inline void i2o_dma_unmap(struct device *dev, struct i2o_dma *addr)
614{
615 if (!addr->virt)
616 return;
617
618 if (addr->phys) {
619 dma_unmap_single(dev, addr->phys, addr->len, DMA_BIDIRECTIONAL);
620 addr->phys = 0;
621 }
622};
623
624/* 744/*
625 * Endian handling wrapped into the macro - keeps the core code 745 * Endian handling wrapped into the macro - keeps the core code
626 * cleaner. 746 * cleaner.
@@ -773,6 +893,14 @@ extern void i2o_debug_state(struct i2o_controller *c);
773#define I2O_CMD_SCSI_BUSRESET 0x27 893#define I2O_CMD_SCSI_BUSRESET 0x27
774 894
775/* 895/*
896 * Bus Adapter Class
897 */
898#define I2O_CMD_BUS_ADAPTER_RESET 0x85
899#define I2O_CMD_BUS_RESET 0x87
900#define I2O_CMD_BUS_SCAN 0x89
901#define I2O_CMD_BUS_QUIESCE 0x8b
902
903/*
776 * Random Block Storage Class 904 * Random Block Storage Class
777 */ 905 */
778#define I2O_CMD_BLOCK_READ 0x30 906#define I2O_CMD_BLOCK_READ 0x30
@@ -784,7 +912,7 @@ extern void i2o_debug_state(struct i2o_controller *c);
784#define I2O_CMD_BLOCK_MEJECT 0x43 912#define I2O_CMD_BLOCK_MEJECT 0x43
785#define I2O_CMD_BLOCK_POWER 0x70 913#define I2O_CMD_BLOCK_POWER 0x70
786 914
787#define I2O_PRIVATE_MSG 0xFF 915#define I2O_CMD_PRIVATE 0xFF
788 916
789/* Command status values */ 917/* Command status values */
790 918
@@ -922,7 +1050,7 @@ extern void i2o_debug_state(struct i2o_controller *c);
922#define I2OVER15 0x0001 1050#define I2OVER15 0x0001
923#define I2OVER20 0x0002 1051#define I2OVER20 0x0002
924 1052
925/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */ 1053/* Default is 1.5 */
926#define I2OVERSION I2OVER15 1054#define I2OVERSION I2OVER15
927 1055
928#define SGL_OFFSET_0 I2OVERSION 1056#define SGL_OFFSET_0 I2OVERSION
@@ -933,9 +1061,9 @@ extern void i2o_debug_state(struct i2o_controller *c);
933#define SGL_OFFSET_8 (0x0080 | I2OVERSION) 1061#define SGL_OFFSET_8 (0x0080 | I2OVERSION)
934#define SGL_OFFSET_9 (0x0090 | I2OVERSION) 1062#define SGL_OFFSET_9 (0x0090 | I2OVERSION)
935#define SGL_OFFSET_10 (0x00A0 | I2OVERSION) 1063#define SGL_OFFSET_10 (0x00A0 | I2OVERSION)
936 1064#define SGL_OFFSET_11 (0x00B0 | I2OVERSION)
937#define TRL_OFFSET_5 (0x0050 | I2OVERSION) 1065#define SGL_OFFSET_12 (0x00C0 | I2OVERSION)
938#define TRL_OFFSET_6 (0x0060 | I2OVERSION) 1066#define SGL_OFFSET(x) (((x)<<4) | I2OVERSION)
939 1067
940/* Transaction Reply Lists (TRL) Control Word structure */ 1068/* Transaction Reply Lists (TRL) Control Word structure */
941#define TRL_SINGLE_FIXED_LENGTH 0x00 1069#define TRL_SINGLE_FIXED_LENGTH 0x00
@@ -962,17 +1090,13 @@ extern void i2o_debug_state(struct i2o_controller *c);
962#define ELEVEN_WORD_MSG_SIZE 0x000B0000 1090#define ELEVEN_WORD_MSG_SIZE 0x000B0000
963#define I2O_MESSAGE_SIZE(x) ((x)<<16) 1091#define I2O_MESSAGE_SIZE(x) ((x)<<16)
964 1092
965/* Special TID Assignments */ 1093/* special TID assignments */
966
967#define ADAPTER_TID 0 1094#define ADAPTER_TID 0
968#define HOST_TID 1 1095#define HOST_TID 1
969 1096
970#define MSG_FRAME_SIZE 128 /* i2o_scsi assumes >= 32 */ 1097/* outbound queue defines */
971#define REPLY_FRAME_SIZE 17 1098#define I2O_MAX_OUTBOUND_MSG_FRAMES 128
972#define SG_TABLESIZE 30 1099#define I2O_OUTBOUND_MSG_FRAME_SIZE 128 /* in 32-bit words */
973#define NMBR_MSG_FRAMES 128
974
975#define MSG_POOL_SIZE (MSG_FRAME_SIZE*NMBR_MSG_FRAMES*sizeof(u32))
976 1100
977#define I2O_POST_WAIT_OK 0 1101#define I2O_POST_WAIT_OK 0
978#define I2O_POST_WAIT_TIMEOUT -ETIMEDOUT 1102#define I2O_POST_WAIT_TIMEOUT -ETIMEDOUT
@@ -993,11 +1117,10 @@ extern void i2o_debug_state(struct i2o_controller *c);
993#define I2O_HRT_GET_TRIES 3 1117#define I2O_HRT_GET_TRIES 3
994#define I2O_LCT_GET_TRIES 3 1118#define I2O_LCT_GET_TRIES 3
995 1119
996/* request queue sizes */ 1120/* defines for max_sectors and max_phys_segments */
997#define I2O_MAX_SECTORS 1024 1121#define I2O_MAX_SECTORS 1024
998#define I2O_MAX_SEGMENTS 128 1122#define I2O_MAX_SECTORS_LIMITED 256
999 1123#define I2O_MAX_PHYS_SEGMENTS MAX_PHYS_SEGMENTS
1000#define I2O_REQ_MEMPOOL_SIZE 32
1001 1124
1002#endif /* __KERNEL__ */ 1125#endif /* __KERNEL__ */
1003#endif /* _I2O_H */ 1126#endif /* _I2O_H */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 336d6e509f59..92129078d4f3 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -917,7 +917,7 @@ typedef struct hwif_s {
917 unsigned dma; 917 unsigned dma;
918 918
919 void (*led_act)(void *data, int rw); 919 void (*led_act)(void *data, int rw);
920} ide_hwif_t; 920} ____cacheline_maxaligned_in_smp ide_hwif_t;
921 921
922/* 922/*
923 * internal ide interrupt handler type 923 * internal ide interrupt handler type
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 2ec265e1045f..596ca6130159 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -209,6 +209,11 @@ struct kernel_ipmi_msg
209#include <linux/list.h> 209#include <linux/list.h>
210#include <linux/module.h> 210#include <linux/module.h>
211 211
212#ifdef CONFIG_PROC_FS
213#include <linux/proc_fs.h>
214extern struct proc_dir_entry *proc_ipmi_root;
215#endif /* CONFIG_PROC_FS */
216
212/* Opaque type for a IPMI message user. One of these is needed to 217/* Opaque type for a IPMI message user. One of these is needed to
213 send and receive messages. */ 218 send and receive messages. */
214typedef struct ipmi_user *ipmi_user_t; 219typedef struct ipmi_user *ipmi_user_t;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 7fc1022be9ee..12277799c007 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -88,7 +88,6 @@ extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
88 struct irqaction *action); 88 struct irqaction *action);
89extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); 89extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
90extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret); 90extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret);
91extern void report_bad_irq(unsigned int irq, irq_desc_t *desc, int action_ret);
92extern int can_request_irq(unsigned int irq, unsigned long irqflags); 91extern int can_request_irq(unsigned int irq, unsigned long irqflags);
93 92
94extern void init_irq_proc(void); 93extern void init_irq_proc(void);
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
index 60cc7b762e78..cc326174a808 100644
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -1,4 +1,4 @@
1/* key-ui.h: key userspace interface stuff for use by keyfs 1/* key-ui.h: key userspace interface stuff
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -31,8 +31,10 @@ extern spinlock_t key_serial_lock;
31 * subscribed 31 * subscribed
32 */ 32 */
33struct keyring_list { 33struct keyring_list {
34 unsigned maxkeys; /* max keys this list can hold */ 34 struct rcu_head rcu; /* RCU deletion hook */
35 unsigned nkeys; /* number of keys currently held */ 35 unsigned short maxkeys; /* max keys this list can hold */
36 unsigned short nkeys; /* number of keys currently held */
37 unsigned short delkey; /* key to be unlinked by RCU */
36 struct key *keys[0]; 38 struct key *keys[0];
37}; 39};
38 40
@@ -82,8 +84,45 @@ static inline int key_any_permission(const struct key *key, key_perm_t perm)
82 return kperm != 0; 84 return kperm != 0;
83} 85}
84 86
87static inline int key_task_groups_search(struct task_struct *tsk, gid_t gid)
88{
89 int ret;
90
91 task_lock(tsk);
92 ret = groups_search(tsk->group_info, gid);
93 task_unlock(tsk);
94 return ret;
95}
96
97static inline int key_task_permission(const struct key *key,
98 struct task_struct *context,
99 key_perm_t perm)
100{
101 key_perm_t kperm;
102
103 if (key->uid == context->fsuid) {
104 kperm = key->perm >> 16;
105 }
106 else if (key->gid != -1 &&
107 key->perm & KEY_GRP_ALL && (
108 key->gid == context->fsgid ||
109 key_task_groups_search(context, key->gid)
110 )
111 ) {
112 kperm = key->perm >> 8;
113 }
114 else {
115 kperm = key->perm;
116 }
117
118 kperm = kperm & perm & KEY_ALL;
119
120 return kperm == perm;
121
122}
85 123
86extern struct key *lookup_user_key(key_serial_t id, int create, int part, 124extern struct key *lookup_user_key(struct task_struct *context,
125 key_serial_t id, int create, int partial,
87 key_perm_t perm); 126 key_perm_t perm);
88 127
89extern long join_session_keyring(const char *name); 128extern long join_session_keyring(const char *name);
diff --git a/include/linux/key.h b/include/linux/key.h
index 6aa46d0e812f..970bbd916cf4 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -18,7 +18,7 @@
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/rbtree.h> 20#include <linux/rbtree.h>
21#include <linux/spinlock.h> 21#include <linux/rcupdate.h>
22#include <asm/atomic.h> 22#include <asm/atomic.h>
23 23
24#ifdef __KERNEL__ 24#ifdef __KERNEL__
@@ -78,7 +78,6 @@ struct key {
78 key_serial_t serial; /* key serial number */ 78 key_serial_t serial; /* key serial number */
79 struct rb_node serial_node; 79 struct rb_node serial_node;
80 struct key_type *type; /* type of key */ 80 struct key_type *type; /* type of key */
81 rwlock_t lock; /* examination vs change lock */
82 struct rw_semaphore sem; /* change vs change sem */ 81 struct rw_semaphore sem; /* change vs change sem */
83 struct key_user *user; /* owner of this key */ 82 struct key_user *user; /* owner of this key */
84 time_t expiry; /* time at which key expires (or 0) */ 83 time_t expiry; /* time at which key expires (or 0) */
@@ -86,14 +85,10 @@ struct key {
86 gid_t gid; 85 gid_t gid;
87 key_perm_t perm; /* access permissions */ 86 key_perm_t perm; /* access permissions */
88 unsigned short quotalen; /* length added to quota */ 87 unsigned short quotalen; /* length added to quota */
89 unsigned short datalen; /* payload data length */ 88 unsigned short datalen; /* payload data length
90 unsigned short flags; /* status flags (change with lock writelocked) */ 89 * - may not match RCU dereferenced payload
91#define KEY_FLAG_INSTANTIATED 0x00000001 /* set if key has been instantiated */ 90 * - payload should contain own length
92#define KEY_FLAG_DEAD 0x00000002 /* set if key type has been deleted */ 91 */
93#define KEY_FLAG_REVOKED 0x00000004 /* set if key had been revoked */
94#define KEY_FLAG_IN_QUOTA 0x00000008 /* set if key consumes quota */
95#define KEY_FLAG_USER_CONSTRUCT 0x00000010 /* set if key is being constructed in userspace */
96#define KEY_FLAG_NEGATIVE 0x00000020 /* set if key is negative */
97 92
98#ifdef KEY_DEBUGGING 93#ifdef KEY_DEBUGGING
99 unsigned magic; 94 unsigned magic;
@@ -101,6 +96,14 @@ struct key {
101#define KEY_DEBUG_MAGIC_X 0xf8e9dacbu 96#define KEY_DEBUG_MAGIC_X 0xf8e9dacbu
102#endif 97#endif
103 98
99 unsigned long flags; /* status flags (change with bitops) */
100#define KEY_FLAG_INSTANTIATED 0 /* set if key has been instantiated */
101#define KEY_FLAG_DEAD 1 /* set if key type has been deleted */
102#define KEY_FLAG_REVOKED 2 /* set if key had been revoked */
103#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */
104#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */
105#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */
106
104 /* the description string 107 /* the description string
105 * - this is used to match a key against search criteria 108 * - this is used to match a key against search criteria
106 * - this should be a printable string 109 * - this should be a printable string
@@ -196,10 +199,12 @@ extern int key_payload_reserve(struct key *key, size_t datalen);
196extern int key_instantiate_and_link(struct key *key, 199extern int key_instantiate_and_link(struct key *key,
197 const void *data, 200 const void *data,
198 size_t datalen, 201 size_t datalen,
199 struct key *keyring); 202 struct key *keyring,
203 struct key *instkey);
200extern int key_negate_and_link(struct key *key, 204extern int key_negate_and_link(struct key *key,
201 unsigned timeout, 205 unsigned timeout,
202 struct key *keyring); 206 struct key *keyring,
207 struct key *instkey);
203extern void key_revoke(struct key *key); 208extern void key_revoke(struct key *key);
204extern void key_put(struct key *key); 209extern void key_put(struct key *key);
205 210
@@ -242,14 +247,13 @@ extern struct key *keyring_search(struct key *keyring,
242 struct key_type *type, 247 struct key_type *type,
243 const char *description); 248 const char *description);
244 249
245extern struct key *search_process_keyrings(struct key_type *type,
246 const char *description);
247
248extern int keyring_add_key(struct key *keyring, 250extern int keyring_add_key(struct key *keyring,
249 struct key *key); 251 struct key *key);
250 252
251extern struct key *key_lookup(key_serial_t id); 253extern struct key *key_lookup(key_serial_t id);
252 254
255extern void keyring_replace_payload(struct key *key, void *replacement);
256
253#define key_serial(key) ((key) ? (key)->serial : 0) 257#define key_serial(key) ((key) ? (key)->serial : 0)
254 258
255/* 259/*
@@ -268,14 +272,22 @@ extern void key_fsuid_changed(struct task_struct *tsk);
268extern void key_fsgid_changed(struct task_struct *tsk); 272extern void key_fsgid_changed(struct task_struct *tsk);
269extern void key_init(void); 273extern void key_init(void);
270 274
275#define __install_session_keyring(tsk, keyring) \
276({ \
277 struct key *old_session = tsk->signal->session_keyring; \
278 tsk->signal->session_keyring = keyring; \
279 old_session; \
280})
281
271#else /* CONFIG_KEYS */ 282#else /* CONFIG_KEYS */
272 283
273#define key_validate(k) 0 284#define key_validate(k) 0
274#define key_serial(k) 0 285#define key_serial(k) 0
275#define key_get(k) NULL 286#define key_get(k) ({ NULL; })
276#define key_put(k) do { } while(0) 287#define key_put(k) do { } while(0)
277#define alloc_uid_keyring(u) 0 288#define alloc_uid_keyring(u) 0
278#define switch_uid_keyring(u) do { } while(0) 289#define switch_uid_keyring(u) do { } while(0)
290#define __install_session_keyring(t, k) ({ NULL; })
279#define copy_keys(f,t) 0 291#define copy_keys(f,t) 0
280#define copy_thread_group_keys(t) 0 292#define copy_thread_group_keys(t) 0
281#define exit_keys(t) do { } while(0) 293#define exit_keys(t) do { } while(0)
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 381dedc370a3..8d7c59a29e09 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -20,6 +20,16 @@
20#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */ 20#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
21#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */ 21#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
22 22
23/* request-key default keyrings */
24#define KEY_REQKEY_DEFL_NO_CHANGE -1
25#define KEY_REQKEY_DEFL_DEFAULT 0
26#define KEY_REQKEY_DEFL_THREAD_KEYRING 1
27#define KEY_REQKEY_DEFL_PROCESS_KEYRING 2
28#define KEY_REQKEY_DEFL_SESSION_KEYRING 3
29#define KEY_REQKEY_DEFL_USER_KEYRING 4
30#define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5
31#define KEY_REQKEY_DEFL_GROUP_KEYRING 6
32
23/* keyctl commands */ 33/* keyctl commands */
24#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */ 34#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */
25#define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */ 35#define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */
@@ -35,5 +45,6 @@
35#define KEYCTL_READ 11 /* read a key or keyring's contents */ 45#define KEYCTL_READ 11 /* read a key or keyring's contents */
36#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ 46#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
37#define KEYCTL_NEGATE 13 /* negate a partially constructed key */ 47#define KEYCTL_NEGATE 13 /* negate a partially constructed key */
48#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
38 49
39#endif /* _LINUX_KEYCTL_H */ 50#endif /* _LINUX_KEYCTL_H */
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 95d0e4b0814d..e4a231549407 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -19,6 +19,7 @@
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20 */
21 21
22#include <linux/stddef.h>
22#include <linux/config.h> 23#include <linux/config.h>
23#include <linux/errno.h> 24#include <linux/errno.h>
24#include <linux/compiler.h> 25#include <linux/compiler.h>
@@ -34,7 +35,17 @@ static inline int request_module(const char * name, ...) { return -ENOSYS; }
34#endif 35#endif
35 36
36#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x))) 37#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
37extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait); 38
39struct key;
40extern int call_usermodehelper_keys(char *path, char *argv[], char *envp[],
41 struct key *session_keyring, int wait);
42
43static inline int
44call_usermodehelper(char *path, char **argv, char **envp, int wait)
45{
46 return call_usermodehelper_keys(path, argv, envp, NULL, wait);
47}
48
38extern void usermodehelper_init(void); 49extern void usermodehelper_init(void);
39 50
40#endif /* __LINUX_KMOD_H__ */ 51#endif /* __LINUX_KMOD_H__ */
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 99ddba5a4e00..5e1a7b0d7b3f 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -25,27 +25,45 @@
25 * Rusty Russell). 25 * Rusty Russell).
26 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes 26 * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
27 * interface to access function arguments. 27 * interface to access function arguments.
28 * 2005-May Hien Nguyen <hien@us.ibm.com> and Jim Keniston
29 * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
30 * <prasanna@in.ibm.com> added function-return probes.
28 */ 31 */
29#include <linux/config.h> 32#include <linux/config.h>
30#include <linux/list.h> 33#include <linux/list.h>
31#include <linux/notifier.h> 34#include <linux/notifier.h>
32#include <linux/smp.h> 35#include <linux/smp.h>
36
33#include <asm/kprobes.h> 37#include <asm/kprobes.h>
34 38
39/* kprobe_status settings */
40#define KPROBE_HIT_ACTIVE 0x00000001
41#define KPROBE_HIT_SS 0x00000002
42#define KPROBE_REENTER 0x00000004
43#define KPROBE_HIT_SSDONE 0x00000008
44
35struct kprobe; 45struct kprobe;
36struct pt_regs; 46struct pt_regs;
47struct kretprobe;
48struct kretprobe_instance;
37typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *); 49typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *);
38typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *); 50typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *);
39typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *, 51typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *,
40 unsigned long flags); 52 unsigned long flags);
41typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *, 53typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *,
42 int trapnr); 54 int trapnr);
55typedef int (*kretprobe_handler_t) (struct kretprobe_instance *,
56 struct pt_regs *);
57
43struct kprobe { 58struct kprobe {
44 struct hlist_node hlist; 59 struct hlist_node hlist;
45 60
46 /* list of kprobes for multi-handler support */ 61 /* list of kprobes for multi-handler support */
47 struct list_head list; 62 struct list_head list;
48 63
64 /*count the number of times this probe was temporarily disarmed */
65 unsigned long nmissed;
66
49 /* location of the probe point */ 67 /* location of the probe point */
50 kprobe_opcode_t *addr; 68 kprobe_opcode_t *addr;
51 69
@@ -85,6 +103,62 @@ struct jprobe {
85 kprobe_opcode_t *entry; /* probe handling code to jump to */ 103 kprobe_opcode_t *entry; /* probe handling code to jump to */
86}; 104};
87 105
106#ifdef ARCH_SUPPORTS_KRETPROBES
107extern int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs);
108extern void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs,
109 unsigned long flags);
110extern struct task_struct *arch_get_kprobe_task(void *ptr);
111extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
112extern void arch_kprobe_flush_task(struct task_struct *tk);
113#else /* ARCH_SUPPORTS_KRETPROBES */
114static inline void kretprobe_trampoline(void)
115{
116}
117static inline int trampoline_probe_handler(struct kprobe *p,
118 struct pt_regs *regs)
119{
120 return 0;
121}
122static inline void trampoline_post_handler(struct kprobe *p,
123 struct pt_regs *regs, unsigned long flags)
124{
125}
126static inline void arch_prepare_kretprobe(struct kretprobe *rp,
127 struct pt_regs *regs)
128{
129}
130static inline void arch_kprobe_flush_task(struct task_struct *tk)
131{
132}
133#define arch_get_kprobe_task(ptr) ((struct task_struct *)NULL)
134#endif /* ARCH_SUPPORTS_KRETPROBES */
135/*
136 * Function-return probe -
137 * Note:
138 * User needs to provide a handler function, and initialize maxactive.
139 * maxactive - The maximum number of instances of the probed function that
140 * can be active concurrently.
141 * nmissed - tracks the number of times the probed function's return was
142 * ignored, due to maxactive being too low.
143 *
144 */
145struct kretprobe {
146 struct kprobe kp;
147 kretprobe_handler_t handler;
148 int maxactive;
149 int nmissed;
150 struct hlist_head free_instances;
151 struct hlist_head used_instances;
152};
153
154struct kretprobe_instance {
155 struct hlist_node uflist; /* either on free list or used list */
156 struct hlist_node hlist;
157 struct kretprobe *rp;
158 void *ret_addr;
159 void *stack_addr;
160};
161
88#ifdef CONFIG_KPROBES 162#ifdef CONFIG_KPROBES
89/* Locks kprobe: irq must be disabled */ 163/* Locks kprobe: irq must be disabled */
90void lock_kprobes(void); 164void lock_kprobes(void);
@@ -99,11 +173,14 @@ static inline int kprobe_running(void)
99 173
100extern int arch_prepare_kprobe(struct kprobe *p); 174extern int arch_prepare_kprobe(struct kprobe *p);
101extern void arch_copy_kprobe(struct kprobe *p); 175extern void arch_copy_kprobe(struct kprobe *p);
176extern void arch_arm_kprobe(struct kprobe *p);
177extern void arch_disarm_kprobe(struct kprobe *p);
102extern void arch_remove_kprobe(struct kprobe *p); 178extern void arch_remove_kprobe(struct kprobe *p);
103extern void show_registers(struct pt_regs *regs); 179extern void show_registers(struct pt_regs *regs);
104 180
105/* Get the kprobe at this addr (if any). Must have called lock_kprobes */ 181/* Get the kprobe at this addr (if any). Must have called lock_kprobes */
106struct kprobe *get_kprobe(void *addr); 182struct kprobe *get_kprobe(void *addr);
183struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk);
107 184
108int register_kprobe(struct kprobe *p); 185int register_kprobe(struct kprobe *p);
109void unregister_kprobe(struct kprobe *p); 186void unregister_kprobe(struct kprobe *p);
@@ -113,7 +190,16 @@ int register_jprobe(struct jprobe *p);
113void unregister_jprobe(struct jprobe *p); 190void unregister_jprobe(struct jprobe *p);
114void jprobe_return(void); 191void jprobe_return(void);
115 192
116#else 193int register_kretprobe(struct kretprobe *rp);
194void unregister_kretprobe(struct kretprobe *rp);
195
196struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
197struct kretprobe_instance *get_rp_inst(void *sara);
198struct kretprobe_instance *get_rp_inst_tsk(struct task_struct *tk);
199void add_rp_inst(struct kretprobe_instance *ri);
200void kprobe_flush_task(struct task_struct *tk);
201void recycle_rp_inst(struct kretprobe_instance *ri);
202#else /* CONFIG_KPROBES */
117static inline int kprobe_running(void) 203static inline int kprobe_running(void)
118{ 204{
119 return 0; 205 return 0;
@@ -135,5 +221,15 @@ static inline void unregister_jprobe(struct jprobe *p)
135static inline void jprobe_return(void) 221static inline void jprobe_return(void)
136{ 222{
137} 223}
138#endif 224static inline int register_kretprobe(struct kretprobe *rp)
225{
226 return -ENOSYS;
227}
228static inline void unregister_kretprobe(struct kretprobe *rp)
229{
230}
231static inline void kprobe_flush_task(struct task_struct *tk)
232{
233}
234#endif /* CONFIG_KPROBES */
139#endif /* _LINUX_KPROBES_H */ 235#endif /* _LINUX_KPROBES_H */
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 8220d9c9da00..53fa51595443 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -61,7 +61,7 @@ struct loop_device {
61 struct semaphore lo_sem; 61 struct semaphore lo_sem;
62 struct semaphore lo_ctl_mutex; 62 struct semaphore lo_ctl_mutex;
63 struct semaphore lo_bh_mutex; 63 struct semaphore lo_bh_mutex;
64 atomic_t lo_pending; 64 int lo_pending;
65 65
66 request_queue_t *lo_queue; 66 request_queue_t *lo_queue;
67}; 67};
diff --git a/include/linux/mempool.h b/include/linux/mempool.h
index 4a36edf1c974..796220ce47cc 100644
--- a/include/linux/mempool.h
+++ b/include/linux/mempool.h
@@ -20,9 +20,14 @@ typedef struct mempool_s {
20 mempool_free_t *free; 20 mempool_free_t *free;
21 wait_queue_head_t wait; 21 wait_queue_head_t wait;
22} mempool_t; 22} mempool_t;
23extern mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn, 23
24 mempool_free_t *free_fn, void *pool_data); 24extern mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
25extern int mempool_resize(mempool_t *pool, int new_min_nr, unsigned int __nocast gfp_mask); 25 mempool_free_t *free_fn, void *pool_data);
26extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
27 mempool_free_t *free_fn, void *pool_data, int nid);
28
29extern int mempool_resize(mempool_t *pool, int new_min_nr,
30 unsigned int __nocast gfp_mask);
26extern void mempool_destroy(mempool_t *pool); 31extern void mempool_destroy(mempool_t *pool);
27extern void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask); 32extern void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask);
28extern void mempool_free(void *element, mempool_t *pool); 33extern void mempool_free(void *element, mempool_t *pool);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1813b162b0a8..6eb7f48317f8 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -395,19 +395,81 @@ static inline void put_page(struct page *page)
395/* 395/*
396 * The zone field is never updated after free_area_init_core() 396 * The zone field is never updated after free_area_init_core()
397 * sets it, so none of the operations on it need to be atomic. 397 * sets it, so none of the operations on it need to be atomic.
398 * We'll have up to (MAX_NUMNODES * MAX_NR_ZONES) zones total,
399 * so we use (MAX_NODES_SHIFT + MAX_ZONES_SHIFT) here to get enough bits.
400 */ 398 */
401#define NODEZONE_SHIFT (sizeof(page_flags_t)*8 - MAX_NODES_SHIFT - MAX_ZONES_SHIFT) 399
402#define NODEZONE(node, zone) ((node << ZONES_SHIFT) | zone) 400
401/*
402 * page->flags layout:
403 *
404 * There are three possibilities for how page->flags get
405 * laid out. The first is for the normal case, without
406 * sparsemem. The second is for sparsemem when there is
407 * plenty of space for node and section. The last is when
408 * we have run out of space and have to fall back to an
409 * alternate (slower) way of determining the node.
410 *
411 * No sparsemem: | NODE | ZONE | ... | FLAGS |
412 * with space for node: | SECTION | NODE | ZONE | ... | FLAGS |
413 * no space for node: | SECTION | ZONE | ... | FLAGS |
414 */
415#ifdef CONFIG_SPARSEMEM
416#define SECTIONS_WIDTH SECTIONS_SHIFT
417#else
418#define SECTIONS_WIDTH 0
419#endif
420
421#define ZONES_WIDTH ZONES_SHIFT
422
423#if SECTIONS_WIDTH+ZONES_WIDTH+NODES_SHIFT <= FLAGS_RESERVED
424#define NODES_WIDTH NODES_SHIFT
425#else
426#define NODES_WIDTH 0
427#endif
428
429/* Page flags: | [SECTION] | [NODE] | ZONE | ... | FLAGS | */
430#define SECTIONS_PGOFF ((sizeof(page_flags_t)*8) - SECTIONS_WIDTH)
431#define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH)
432#define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH)
433
434/*
435 * We are going to use the flags for the page to node mapping if its in
436 * there. This includes the case where there is no node, so it is implicit.
437 */
438#define FLAGS_HAS_NODE (NODES_WIDTH > 0 || NODES_SHIFT == 0)
439
440#ifndef PFN_SECTION_SHIFT
441#define PFN_SECTION_SHIFT 0
442#endif
443
444/*
445 * Define the bit shifts to access each section. For non-existant
446 * sections we define the shift as 0; that plus a 0 mask ensures
447 * the compiler will optimise away reference to them.
448 */
449#define SECTIONS_PGSHIFT (SECTIONS_PGOFF * (SECTIONS_WIDTH != 0))
450#define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0))
451#define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0))
452
453/* NODE:ZONE or SECTION:ZONE is used to lookup the zone from a page. */
454#if FLAGS_HAS_NODE
455#define ZONETABLE_SHIFT (NODES_SHIFT + ZONES_SHIFT)
456#else
457#define ZONETABLE_SHIFT (SECTIONS_SHIFT + ZONES_SHIFT)
458#endif
459#define ZONETABLE_PGSHIFT ZONES_PGSHIFT
460
461#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
462#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
463#endif
464
465#define ZONES_MASK ((1UL << ZONES_WIDTH) - 1)
466#define NODES_MASK ((1UL << NODES_WIDTH) - 1)
467#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1)
468#define ZONETABLE_MASK ((1UL << ZONETABLE_SHIFT) - 1)
403 469
404static inline unsigned long page_zonenum(struct page *page) 470static inline unsigned long page_zonenum(struct page *page)
405{ 471{
406 return (page->flags >> NODEZONE_SHIFT) & (~(~0UL << ZONES_SHIFT)); 472 return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK;
407}
408static inline unsigned long page_to_nid(struct page *page)
409{
410 return (page->flags >> (NODEZONE_SHIFT + ZONES_SHIFT));
411} 473}
412 474
413struct zone; 475struct zone;
@@ -415,13 +477,44 @@ extern struct zone *zone_table[];
415 477
416static inline struct zone *page_zone(struct page *page) 478static inline struct zone *page_zone(struct page *page)
417{ 479{
418 return zone_table[page->flags >> NODEZONE_SHIFT]; 480 return zone_table[(page->flags >> ZONETABLE_PGSHIFT) &
481 ZONETABLE_MASK];
482}
483
484static inline unsigned long page_to_nid(struct page *page)
485{
486 if (FLAGS_HAS_NODE)
487 return (page->flags >> NODES_PGSHIFT) & NODES_MASK;
488 else
489 return page_zone(page)->zone_pgdat->node_id;
490}
491static inline unsigned long page_to_section(struct page *page)
492{
493 return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
494}
495
496static inline void set_page_zone(struct page *page, unsigned long zone)
497{
498 page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT);
499 page->flags |= (zone & ZONES_MASK) << ZONES_PGSHIFT;
500}
501static inline void set_page_node(struct page *page, unsigned long node)
502{
503 page->flags &= ~(NODES_MASK << NODES_PGSHIFT);
504 page->flags |= (node & NODES_MASK) << NODES_PGSHIFT;
505}
506static inline void set_page_section(struct page *page, unsigned long section)
507{
508 page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT);
509 page->flags |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT;
419} 510}
420 511
421static inline void set_page_zone(struct page *page, unsigned long nodezone_num) 512static inline void set_page_links(struct page *page, unsigned long zone,
513 unsigned long node, unsigned long pfn)
422{ 514{
423 page->flags &= ~(~0UL << NODEZONE_SHIFT); 515 set_page_zone(page, zone);
424 page->flags |= nodezone_num << NODEZONE_SHIFT; 516 set_page_node(page, node);
517 set_page_section(page, pfn_to_section_nr(pfn));
425} 518}
426 519
427#ifndef CONFIG_DISCONTIGMEM 520#ifndef CONFIG_DISCONTIGMEM
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 4733d35d8223..6c90461ed99f 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -269,7 +269,9 @@ typedef struct pglist_data {
269 struct zone node_zones[MAX_NR_ZONES]; 269 struct zone node_zones[MAX_NR_ZONES];
270 struct zonelist node_zonelists[GFP_ZONETYPES]; 270 struct zonelist node_zonelists[GFP_ZONETYPES];
271 int nr_zones; 271 int nr_zones;
272#ifdef CONFIG_FLAT_NODE_MEM_MAP
272 struct page *node_mem_map; 273 struct page *node_mem_map;
274#endif
273 struct bootmem_data *bdata; 275 struct bootmem_data *bdata;
274 unsigned long node_start_pfn; 276 unsigned long node_start_pfn;
275 unsigned long node_present_pages; /* total number of physical pages */ 277 unsigned long node_present_pages; /* total number of physical pages */
@@ -284,6 +286,12 @@ typedef struct pglist_data {
284 286
285#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages) 287#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)
286#define node_spanned_pages(nid) (NODE_DATA(nid)->node_spanned_pages) 288#define node_spanned_pages(nid) (NODE_DATA(nid)->node_spanned_pages)
289#ifdef CONFIG_FLAT_NODE_MEM_MAP
290#define pgdat_page_nr(pgdat, pagenr) ((pgdat)->node_mem_map + (pagenr))
291#else
292#define pgdat_page_nr(pgdat, pagenr) pfn_to_page((pgdat)->node_start_pfn + (pagenr))
293#endif
294#define nid_page_nr(nid, pagenr) pgdat_page_nr(NODE_DATA(nid),(pagenr))
287 295
288extern struct pglist_data *pgdat_list; 296extern struct pglist_data *pgdat_list;
289 297
@@ -400,7 +408,7 @@ int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *,
400/* Returns the number of the current Node. */ 408/* Returns the number of the current Node. */
401#define numa_node_id() (cpu_to_node(raw_smp_processor_id())) 409#define numa_node_id() (cpu_to_node(raw_smp_processor_id()))
402 410
403#ifndef CONFIG_DISCONTIGMEM 411#ifndef CONFIG_NEED_MULTIPLE_NODES
404 412
405extern struct pglist_data contig_page_data; 413extern struct pglist_data contig_page_data;
406#define NODE_DATA(nid) (&contig_page_data) 414#define NODE_DATA(nid) (&contig_page_data)
@@ -408,36 +416,177 @@ extern struct pglist_data contig_page_data;
408#define MAX_NODES_SHIFT 1 416#define MAX_NODES_SHIFT 1
409#define pfn_to_nid(pfn) (0) 417#define pfn_to_nid(pfn) (0)
410 418
411#else /* CONFIG_DISCONTIGMEM */ 419#else /* CONFIG_NEED_MULTIPLE_NODES */
412 420
413#include <asm/mmzone.h> 421#include <asm/mmzone.h>
414 422
423#endif /* !CONFIG_NEED_MULTIPLE_NODES */
424
425#ifdef CONFIG_SPARSEMEM
426#include <asm/sparsemem.h>
427#endif
428
415#if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED) 429#if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED)
416/* 430/*
417 * with 32 bit page->flags field, we reserve 8 bits for node/zone info. 431 * with 32 bit page->flags field, we reserve 8 bits for node/zone info.
418 * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes. 432 * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes.
419 */ 433 */
420#define MAX_NODES_SHIFT 6 434#define FLAGS_RESERVED 8
435
421#elif BITS_PER_LONG == 64 436#elif BITS_PER_LONG == 64
422/* 437/*
423 * with 64 bit flags field, there's plenty of room. 438 * with 64 bit flags field, there's plenty of room.
424 */ 439 */
425#define MAX_NODES_SHIFT 10 440#define FLAGS_RESERVED 32
441
442#else
443
444#error BITS_PER_LONG not defined
445
446#endif
447
448#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
449#define early_pfn_to_nid(nid) (0UL)
426#endif 450#endif
427 451
428#endif /* !CONFIG_DISCONTIGMEM */ 452#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)
453#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT)
454
455#ifdef CONFIG_SPARSEMEM
456
457/*
458 * SECTION_SHIFT #bits space required to store a section #
459 *
460 * PA_SECTION_SHIFT physical address to/from section number
461 * PFN_SECTION_SHIFT pfn to/from section number
462 */
463#define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS)
464
465#define PA_SECTION_SHIFT (SECTION_SIZE_BITS)
466#define PFN_SECTION_SHIFT (SECTION_SIZE_BITS - PAGE_SHIFT)
467
468#define NR_MEM_SECTIONS (1UL << SECTIONS_SHIFT)
429 469
430#if NODES_SHIFT > MAX_NODES_SHIFT 470#define PAGES_PER_SECTION (1UL << PFN_SECTION_SHIFT)
431#error NODES_SHIFT > MAX_NODES_SHIFT 471#define PAGE_SECTION_MASK (~(PAGES_PER_SECTION-1))
472
473#if (MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS
474#error Allocator MAX_ORDER exceeds SECTION_SIZE
432#endif 475#endif
433 476
434/* There are currently 3 zones: DMA, Normal & Highmem, thus we need 2 bits */ 477struct page;
435#define MAX_ZONES_SHIFT 2 478struct mem_section {
479 /*
480 * This is, logically, a pointer to an array of struct
481 * pages. However, it is stored with some other magic.
482 * (see sparse.c::sparse_init_one_section())
483 *
484 * Making it a UL at least makes someone do a cast
485 * before using it wrong.
486 */
487 unsigned long section_mem_map;
488};
489
490extern struct mem_section mem_section[NR_MEM_SECTIONS];
436 491
437#if ZONES_SHIFT > MAX_ZONES_SHIFT 492static inline struct mem_section *__nr_to_section(unsigned long nr)
438#error ZONES_SHIFT > MAX_ZONES_SHIFT 493{
494 return &mem_section[nr];
495}
496
497/*
498 * We use the lower bits of the mem_map pointer to store
499 * a little bit of information. There should be at least
500 * 3 bits here due to 32-bit alignment.
501 */
502#define SECTION_MARKED_PRESENT (1UL<<0)
503#define SECTION_HAS_MEM_MAP (1UL<<1)
504#define SECTION_MAP_LAST_BIT (1UL<<2)
505#define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1))
506
507static inline struct page *__section_mem_map_addr(struct mem_section *section)
508{
509 unsigned long map = section->section_mem_map;
510 map &= SECTION_MAP_MASK;
511 return (struct page *)map;
512}
513
514static inline int valid_section(struct mem_section *section)
515{
516 return (section->section_mem_map & SECTION_MARKED_PRESENT);
517}
518
519static inline int section_has_mem_map(struct mem_section *section)
520{
521 return (section->section_mem_map & SECTION_HAS_MEM_MAP);
522}
523
524static inline int valid_section_nr(unsigned long nr)
525{
526 return valid_section(__nr_to_section(nr));
527}
528
529/*
530 * Given a kernel address, find the home node of the underlying memory.
531 */
532#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
533
534static inline struct mem_section *__pfn_to_section(unsigned long pfn)
535{
536 return __nr_to_section(pfn_to_section_nr(pfn));
537}
538
539#define pfn_to_page(pfn) \
540({ \
541 unsigned long __pfn = (pfn); \
542 __section_mem_map_addr(__pfn_to_section(__pfn)) + __pfn; \
543})
544#define page_to_pfn(page) \
545({ \
546 page - __section_mem_map_addr(__nr_to_section( \
547 page_to_section(page))); \
548})
549
550static inline int pfn_valid(unsigned long pfn)
551{
552 if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
553 return 0;
554 return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
555}
556
557/*
558 * These are _only_ used during initialisation, therefore they
559 * can use __initdata ... They could have names to indicate
560 * this restriction.
561 */
562#ifdef CONFIG_NUMA
563#define pfn_to_nid early_pfn_to_nid
564#endif
565
566#define pfn_to_pgdat(pfn) \
567({ \
568 NODE_DATA(pfn_to_nid(pfn)); \
569})
570
571#define early_pfn_valid(pfn) pfn_valid(pfn)
572void sparse_init(void);
573#else
574#define sparse_init() do {} while (0)
575#endif /* CONFIG_SPARSEMEM */
576
577#ifdef CONFIG_NODES_SPAN_OTHER_NODES
578#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
579#else
580#define early_pfn_in_nid(pfn, nid) (1)
581#endif
582
583#ifndef early_pfn_valid
584#define early_pfn_valid(pfn) (1)
439#endif 585#endif
440 586
587void memory_present(int nid, unsigned long start, unsigned long end);
588unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long);
589
441#endif /* !__ASSEMBLY__ */ 590#endif /* !__ASSEMBLY__ */
442#endif /* __KERNEL__ */ 591#endif /* __KERNEL__ */
443#endif /* _LINUX_MMZONE_H */ 592#endif /* _LINUX_MMZONE_H */
diff --git a/include/linux/module.h b/include/linux/module.h
index 0e432a0f4aee..f05372b7fe77 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -51,6 +51,9 @@ struct module_attribute {
51 ssize_t (*show)(struct module_attribute *, struct module *, char *); 51 ssize_t (*show)(struct module_attribute *, struct module *, char *);
52 ssize_t (*store)(struct module_attribute *, struct module *, 52 ssize_t (*store)(struct module_attribute *, struct module *,
53 const char *, size_t count); 53 const char *, size_t count);
54 void (*setup)(struct module *, const char *);
55 int (*test)(struct module *);
56 void (*free)(struct module *);
54}; 57};
55 58
56struct module_kobject 59struct module_kobject
@@ -239,6 +242,8 @@ struct module
239 /* Sysfs stuff. */ 242 /* Sysfs stuff. */
240 struct module_kobject mkobj; 243 struct module_kobject mkobj;
241 struct module_param_attrs *param_attrs; 244 struct module_param_attrs *param_attrs;
245 const char *version;
246 const char *srcversion;
242 247
243 /* Exported symbols */ 248 /* Exported symbols */
244 const struct kernel_symbol *syms; 249 const struct kernel_symbol *syms;
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 9eca1558d72f..697991b69f9b 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -12,7 +12,6 @@ struct namespace {
12 struct rw_semaphore sem; 12 struct rw_semaphore sem;
13}; 13};
14 14
15extern void umount_tree(struct vfsmount *);
16extern int copy_namespace(int, struct task_struct *); 15extern int copy_namespace(int, struct task_struct *);
17extern void __put_namespace(struct namespace *namespace); 16extern void __put_namespace(struct namespace *namespace);
18 17
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d6afd440cf7b..3a0ed7f9e801 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -164,12 +164,6 @@ struct netif_rx_stats
164 unsigned total; 164 unsigned total;
165 unsigned dropped; 165 unsigned dropped;
166 unsigned time_squeeze; 166 unsigned time_squeeze;
167 unsigned throttled;
168 unsigned fastroute_hit;
169 unsigned fastroute_success;
170 unsigned fastroute_defer;
171 unsigned fastroute_deferred_out;
172 unsigned fastroute_latency_reduction;
173 unsigned cpu_collision; 167 unsigned cpu_collision;
174}; 168};
175 169
@@ -562,12 +556,9 @@ static inline int unregister_gifconf(unsigned int family)
562 556
563struct softnet_data 557struct softnet_data
564{ 558{
565 int throttle; 559 struct net_device *output_queue;
566 int cng_level;
567 int avg_blog;
568 struct sk_buff_head input_pkt_queue; 560 struct sk_buff_head input_pkt_queue;
569 struct list_head poll_list; 561 struct list_head poll_list;
570 struct net_device *output_queue;
571 struct sk_buff *completion_queue; 562 struct sk_buff *completion_queue;
572 563
573 struct net_device backlog_dev; /* Sorry. 8) */ 564 struct net_device backlog_dev; /* Sorry. 8) */
@@ -925,10 +916,6 @@ extern int skb_checksum_help(struct sk_buff *skb, int inward);
925extern void net_enable_timestamp(void); 916extern void net_enable_timestamp(void);
926extern void net_disable_timestamp(void); 917extern void net_disable_timestamp(void);
927 918
928#ifdef CONFIG_SYSCTL
929extern char *net_sysctl_strdup(const char *s);
930#endif
931
932#endif /* __KERNEL__ */ 919#endif /* __KERNEL__ */
933 920
934#endif /* _LINUX_DEV_H */ 921#endif /* _LINUX_DEV_H */
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 5bb5b2fd7ba2..0c1c306cdaec 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -28,7 +28,7 @@
28#define NFS4_ACCESS_DELETE 0x0010 28#define NFS4_ACCESS_DELETE 0x0010
29#define NFS4_ACCESS_EXECUTE 0x0020 29#define NFS4_ACCESS_EXECUTE 0x0020
30 30
31#define NFS4_FH_PERISTENT 0x0000 31#define NFS4_FH_PERSISTENT 0x0000
32#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001 32#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001
33#define NFS4_FH_VOLATILE_ANY 0x0002 33#define NFS4_FH_VOLATILE_ANY 0x0002
34#define NFS4_FH_VOL_MIGRATION 0x0004 34#define NFS4_FH_VOL_MIGRATION 0x0004
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 4bf931d5ff56..5791dfd30dd0 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -145,15 +145,19 @@ int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
145 * NFSv4 State 145 * NFSv4 State
146 */ 146 */
147#ifdef CONFIG_NFSD_V4 147#ifdef CONFIG_NFSD_V4
148int nfs4_state_init(void); 148void nfs4_state_init(void);
149int nfs4_state_start(void);
149void nfs4_state_shutdown(void); 150void nfs4_state_shutdown(void);
150time_t nfs4_lease_time(void); 151time_t nfs4_lease_time(void);
151void nfs4_reset_lease(time_t leasetime); 152void nfs4_reset_lease(time_t leasetime);
153int nfs4_reset_recoverydir(char *recdir);
152#else 154#else
153static inline int nfs4_state_init(void){return 0;} 155static inline void nfs4_state_init(void){};
156static inline int nfs4_state_start(void){return 0;}
154static inline void nfs4_state_shutdown(void){} 157static inline void nfs4_state_shutdown(void){}
155static inline time_t nfs4_lease_time(void){return 0;} 158static inline time_t nfs4_lease_time(void){return 0;}
156static inline void nfs4_reset_lease(time_t leasetime){} 159static inline void nfs4_reset_lease(time_t leasetime){}
160static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
157#endif 161#endif
158 162
159/* 163/*
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index b6b2fe1e7c63..a84a3fa99be1 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -61,11 +61,6 @@ typedef struct {
61#define si_stateownerid si_opaque.so_stateownerid 61#define si_stateownerid si_opaque.so_stateownerid
62#define si_fileid si_opaque.so_fileid 62#define si_fileid si_opaque.so_fileid
63 63
64extern stateid_t zerostateid;
65extern stateid_t onestateid;
66
67#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
68#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
69 64
70struct nfs4_cb_recall { 65struct nfs4_cb_recall {
71 u32 cbr_ident; 66 u32 cbr_ident;
@@ -77,8 +72,8 @@ struct nfs4_cb_recall {
77}; 72};
78 73
79struct nfs4_delegation { 74struct nfs4_delegation {
80 struct list_head dl_del_perfile; /* nfs4_file->fi_del_perfile */ 75 struct list_head dl_perfile;
81 struct list_head dl_del_perclnt; /* nfs4_client->cl_del_perclnt*/ 76 struct list_head dl_perclnt;
82 struct list_head dl_recall_lru; /* delegation recalled */ 77 struct list_head dl_recall_lru; /* delegation recalled */
83 atomic_t dl_count; /* ref count */ 78 atomic_t dl_count; /* ref count */
84 struct nfs4_client *dl_client; 79 struct nfs4_client *dl_client;
@@ -97,7 +92,6 @@ struct nfs4_delegation {
97/* client delegation callback info */ 92/* client delegation callback info */
98struct nfs4_callback { 93struct nfs4_callback {
99 /* SETCLIENTID info */ 94 /* SETCLIENTID info */
100 u32 cb_parsed; /* addr parsed */
101 u32 cb_addr; 95 u32 cb_addr;
102 unsigned short cb_port; 96 unsigned short cb_port;
103 u32 cb_prog; 97 u32 cb_prog;
@@ -109,6 +103,8 @@ struct nfs4_callback {
109 struct rpc_clnt * cb_client; 103 struct rpc_clnt * cb_client;
110}; 104};
111 105
106#define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */
107
112/* 108/*
113 * struct nfs4_client - one per client. Clientids live here. 109 * struct nfs4_client - one per client. Clientids live here.
114 * o Each nfs4_client is hashed by clientid. 110 * o Each nfs4_client is hashed by clientid.
@@ -122,10 +118,11 @@ struct nfs4_callback {
122struct nfs4_client { 118struct nfs4_client {
123 struct list_head cl_idhash; /* hash by cl_clientid.id */ 119 struct list_head cl_idhash; /* hash by cl_clientid.id */
124 struct list_head cl_strhash; /* hash by cl_name */ 120 struct list_head cl_strhash; /* hash by cl_name */
125 struct list_head cl_perclient; /* list: stateowners */ 121 struct list_head cl_openowners;
126 struct list_head cl_del_perclnt; /* list: delegations */ 122 struct list_head cl_delegations;
127 struct list_head cl_lru; /* tail queue */ 123 struct list_head cl_lru; /* tail queue */
128 struct xdr_netobj cl_name; /* id generated by client */ 124 struct xdr_netobj cl_name; /* id generated by client */
125 char cl_recdir[HEXDIR_LEN]; /* recovery dir */
129 nfs4_verifier cl_verifier; /* generated by client */ 126 nfs4_verifier cl_verifier; /* generated by client */
130 time_t cl_time; /* time of last lease renewal */ 127 time_t cl_time; /* time of last lease renewal */
131 u32 cl_addr; /* client ipaddress */ 128 u32 cl_addr; /* client ipaddress */
@@ -134,6 +131,7 @@ struct nfs4_client {
134 nfs4_verifier cl_confirm; /* generated by server */ 131 nfs4_verifier cl_confirm; /* generated by server */
135 struct nfs4_callback cl_callback; /* callback info */ 132 struct nfs4_callback cl_callback; /* callback info */
136 atomic_t cl_count; /* ref count */ 133 atomic_t cl_count; /* ref count */
134 u32 cl_firststate; /* recovery dir creation */
137}; 135};
138 136
139/* struct nfs4_client_reset 137/* struct nfs4_client_reset
@@ -143,7 +141,7 @@ struct nfs4_client {
143 */ 141 */
144struct nfs4_client_reclaim { 142struct nfs4_client_reclaim {
145 struct list_head cr_strhash; /* hash by cr_name */ 143 struct list_head cr_strhash; /* hash by cr_name */
146 struct xdr_netobj cr_name; /* id generated by client */ 144 char cr_recdir[HEXDIR_LEN]; /* recover dir */
147}; 145};
148 146
149static inline void 147static inline void
@@ -197,9 +195,9 @@ struct nfs4_stateowner {
197 struct kref so_ref; 195 struct kref so_ref;
198 struct list_head so_idhash; /* hash by so_id */ 196 struct list_head so_idhash; /* hash by so_id */
199 struct list_head so_strhash; /* hash by op_name */ 197 struct list_head so_strhash; /* hash by op_name */
200 struct list_head so_perclient; /* nfs4_client->cl_perclient */ 198 struct list_head so_perclient;
201 struct list_head so_perfilestate; /* list: nfs4_stateid */ 199 struct list_head so_stateids;
202 struct list_head so_perlockowner; /* nfs4_stateid->st_perlockowner */ 200 struct list_head so_perstateid; /* for lockowners only */
203 struct list_head so_close_lru; /* tail queue */ 201 struct list_head so_close_lru; /* tail queue */
204 time_t so_time; /* time of placement on so_close_lru */ 202 time_t so_time; /* time of placement on so_close_lru */
205 int so_is_open_owner; /* 1=openowner,0=lockowner */ 203 int so_is_open_owner; /* 1=openowner,0=lockowner */
@@ -217,9 +215,10 @@ struct nfs4_stateowner {
217* share_acces, share_deny on the file. 215* share_acces, share_deny on the file.
218*/ 216*/
219struct nfs4_file { 217struct nfs4_file {
218 struct kref fi_ref;
220 struct list_head fi_hash; /* hash by "struct inode *" */ 219 struct list_head fi_hash; /* hash by "struct inode *" */
221 struct list_head fi_perfile; /* list: nfs4_stateid */ 220 struct list_head fi_stateids;
222 struct list_head fi_del_perfile; /* list: nfs4_delegation */ 221 struct list_head fi_delegations;
223 struct inode *fi_inode; 222 struct inode *fi_inode;
224 u32 fi_id; /* used with stateowner->so_id 223 u32 fi_id; /* used with stateowner->so_id
225 * for stateid_hashtbl hash */ 224 * for stateid_hashtbl hash */
@@ -241,8 +240,8 @@ struct nfs4_file {
241struct nfs4_stateid { 240struct nfs4_stateid {
242 struct list_head st_hash; 241 struct list_head st_hash;
243 struct list_head st_perfile; 242 struct list_head st_perfile;
244 struct list_head st_perfilestate; 243 struct list_head st_perstateowner;
245 struct list_head st_perlockowner; 244 struct list_head st_lockowners;
246 struct nfs4_stateowner * st_stateowner; 245 struct nfs4_stateowner * st_stateowner;
247 struct nfs4_file * st_file; 246 struct nfs4_file * st_file;
248 stateid_t st_stateid; 247 stateid_t st_stateid;
@@ -267,12 +266,9 @@ struct nfs4_stateid {
267 ((err) != nfserr_stale_stateid) && \ 266 ((err) != nfserr_stale_stateid) && \
268 ((err) != nfserr_bad_stateid)) 267 ((err) != nfserr_bad_stateid))
269 268
270extern time_t nfs4_laundromat(void);
271extern int nfsd4_renew(clientid_t *clid); 269extern int nfsd4_renew(clientid_t *clid);
272extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, 270extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh,
273 stateid_t *stateid, int flags, struct file **filp); 271 stateid_t *stateid, int flags, struct file **filp);
274extern int nfs4_share_conflict(struct svc_fh *current_fh,
275 unsigned int deny_type);
276extern void nfs4_lock_state(void); 272extern void nfs4_lock_state(void);
277extern void nfs4_unlock_state(void); 273extern void nfs4_unlock_state(void);
278extern int nfs4_in_grace(void); 274extern int nfs4_in_grace(void);
@@ -282,6 +278,15 @@ extern void nfs4_free_stateowner(struct kref *kref);
282extern void nfsd4_probe_callback(struct nfs4_client *clp); 278extern void nfsd4_probe_callback(struct nfs4_client *clp);
283extern void nfsd4_cb_recall(struct nfs4_delegation *dp); 279extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
284extern void nfs4_put_delegation(struct nfs4_delegation *dp); 280extern void nfs4_put_delegation(struct nfs4_delegation *dp);
281extern int nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
282extern void nfsd4_init_recdir(char *recdir_name);
283extern int nfsd4_recdir_load(void);
284extern void nfsd4_shutdown_recdir(void);
285extern int nfs4_client_to_reclaim(const char *name);
286extern int nfs4_has_reclaimed_state(const char *name);
287extern void nfsd4_recdir_purge_old(void);
288extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
289extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
285 290
286static inline void 291static inline void
287nfs4_put_stateowner(struct nfs4_stateowner *so) 292nfs4_put_stateowner(struct nfs4_stateowner *so)
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index a1f5ad0be1bf..4d24d65c0e88 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -210,6 +210,7 @@ struct nfsd4_open {
210 u32 op_share_access; /* request */ 210 u32 op_share_access; /* request */
211 u32 op_share_deny; /* request */ 211 u32 op_share_deny; /* request */
212 stateid_t op_stateid; /* response */ 212 stateid_t op_stateid; /* response */
213 u32 op_recall; /* recall */
213 struct nfsd4_change_info op_cinfo; /* response */ 214 struct nfsd4_change_info op_cinfo; /* response */
214 u32 op_rflags; /* response */ 215 u32 op_rflags; /* response */
215 int op_truncate; /* used during processing */ 216 int op_truncate; /* used during processing */
diff --git a/include/linux/nfsd_idmap.h b/include/linux/nfsd_idmap.h
index 9bb7f30e923b..e82746fcad14 100644
--- a/include/linux/nfsd_idmap.h
+++ b/include/linux/nfsd_idmap.h
@@ -43,8 +43,13 @@
43/* XXX from linux/nfs_idmap.h */ 43/* XXX from linux/nfs_idmap.h */
44#define IDMAP_NAMESZ 128 44#define IDMAP_NAMESZ 128
45 45
46#ifdef CONFIG_NFSD_V4
46void nfsd_idmap_init(void); 47void nfsd_idmap_init(void);
47void nfsd_idmap_shutdown(void); 48void nfsd_idmap_shutdown(void);
49#else
50static inline void nfsd_idmap_init(void) {};
51static inline void nfsd_idmap_shutdown(void) {};
52#endif
48 53
49int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); 54int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
50int nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *); 55int nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *);
diff --git a/include/linux/numa.h b/include/linux/numa.h
index bd0c8c4e9a95..f0c539bd3cfc 100644
--- a/include/linux/numa.h
+++ b/include/linux/numa.h
@@ -3,7 +3,7 @@
3 3
4#include <linux/config.h> 4#include <linux/config.h>
5 5
6#ifdef CONFIG_DISCONTIGMEM 6#ifndef CONFIG_FLATMEM
7#include <asm/numnodes.h> 7#include <asm/numnodes.h>
8#endif 8#endif
9 9
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 63e89e47b8e9..bf608808a60c 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1568,6 +1568,7 @@
1568#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 1568#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
1569#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB 1569#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
1570#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221 1570#define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221
1571#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
1571#define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225 1572#define PCI_DEVICE_ID_SERVERWORKS_GCLE 0x0225
1572#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227 1573#define PCI_DEVICE_ID_SERVERWORKS_GCLE2 0x0227
1573#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230 1574#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index d2aa214d6803..25d2d67c1faf 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -408,6 +408,7 @@ enum
408 TCF_EM_NBYTE, 408 TCF_EM_NBYTE,
409 TCF_EM_U32, 409 TCF_EM_U32,
410 TCF_EM_META, 410 TCF_EM_META,
411 TCF_EM_TEXT,
411 __TCF_EM_MAX 412 __TCF_EM_MAX
412}; 413};
413 414
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
index 4e2d2a942ecb..4b32bce9a289 100644
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -159,7 +159,7 @@ struct packet_iosched
159 struct bio *read_queue_tail; 159 struct bio *read_queue_tail;
160 struct bio *write_queue; 160 struct bio *write_queue;
161 struct bio *write_queue_tail; 161 struct bio *write_queue_tail;
162 int high_prio_read; /* An important read request has been queued */ 162 sector_t last_write; /* The sector where the last write ended */
163 int successive_reads; 163 int successive_reads;
164}; 164};
165 165
diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h
index 5efd0a6dad94..6e53c34035cd 100644
--- a/include/linux/posix_acl_xattr.h
+++ b/include/linux/posix_acl_xattr.h
@@ -23,13 +23,13 @@
23#define ACL_UNDEFINED_ID (-1) 23#define ACL_UNDEFINED_ID (-1)
24 24
25typedef struct { 25typedef struct {
26 __u16 e_tag; 26 __le16 e_tag;
27 __u16 e_perm; 27 __le16 e_perm;
28 __u32 e_id; 28 __le32 e_id;
29} posix_acl_xattr_entry; 29} posix_acl_xattr_entry;
30 30
31typedef struct { 31typedef struct {
32 __u32 a_version; 32 __le32 a_version;
33 posix_acl_xattr_entry a_entries[0]; 33 posix_acl_xattr_entry a_entries[0];
34} posix_acl_xattr_header; 34} posix_acl_xattr_header;
35 35
@@ -52,4 +52,7 @@ posix_acl_xattr_count(size_t size)
52 return size / sizeof(posix_acl_xattr_entry); 52 return size / sizeof(posix_acl_xattr_entry);
53} 53}
54 54
55struct posix_acl *posix_acl_from_xattr(const void *value, size_t size);
56int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size);
57
55#endif /* _POSIX_ACL_XATTR_H */ 58#endif /* _POSIX_ACL_XATTR_H */
diff --git a/include/linux/qnx4_fs.h b/include/linux/qnx4_fs.h
index 22ba580b0ae8..fc610bb0f733 100644
--- a/include/linux/qnx4_fs.h
+++ b/include/linux/qnx4_fs.h
@@ -46,11 +46,11 @@ struct qnx4_inode_entry {
46 char di_fname[QNX4_SHORT_NAME_MAX]; 46 char di_fname[QNX4_SHORT_NAME_MAX];
47 qnx4_off_t di_size; 47 qnx4_off_t di_size;
48 qnx4_xtnt_t di_first_xtnt; 48 qnx4_xtnt_t di_first_xtnt;
49 __u32 di_xblk; 49 __le32 di_xblk;
50 __s32 di_ftime; 50 __le32 di_ftime;
51 __s32 di_mtime; 51 __le32 di_mtime;
52 __s32 di_atime; 52 __le32 di_atime;
53 __s32 di_ctime; 53 __le32 di_ctime;
54 qnx4_nxtnt_t di_num_xtnts; 54 qnx4_nxtnt_t di_num_xtnts;
55 qnx4_mode_t di_mode; 55 qnx4_mode_t di_mode;
56 qnx4_muid_t di_uid; 56 qnx4_muid_t di_uid;
@@ -63,18 +63,18 @@ struct qnx4_inode_entry {
63 63
64struct qnx4_link_info { 64struct qnx4_link_info {
65 char dl_fname[QNX4_NAME_MAX]; 65 char dl_fname[QNX4_NAME_MAX];
66 __u32 dl_inode_blk; 66 __le32 dl_inode_blk;
67 __u8 dl_inode_ndx; 67 __u8 dl_inode_ndx;
68 __u8 dl_spare[10]; 68 __u8 dl_spare[10];
69 __u8 dl_status; 69 __u8 dl_status;
70}; 70};
71 71
72struct qnx4_xblk { 72struct qnx4_xblk {
73 __u32 xblk_next_xblk; 73 __le32 xblk_next_xblk;
74 __u32 xblk_prev_xblk; 74 __le32 xblk_prev_xblk;
75 __u8 xblk_num_xtnts; 75 __u8 xblk_num_xtnts;
76 __u8 xblk_spare[3]; 76 __u8 xblk_spare[3];
77 __s32 xblk_num_blocks; 77 __le32 xblk_num_blocks;
78 qnx4_xtnt_t xblk_xtnts[QNX4_MAX_XTNTS_PER_XBLK]; 78 qnx4_xtnt_t xblk_xtnts[QNX4_MAX_XTNTS_PER_XBLK];
79 char xblk_signature[8]; 79 char xblk_signature[8];
80 qnx4_xtnt_t xblk_first_xtnt; 80 qnx4_xtnt_t xblk_first_xtnt;
diff --git a/include/linux/qnxtypes.h b/include/linux/qnxtypes.h
index fb518e318c7c..a3eb1137857b 100644
--- a/include/linux/qnxtypes.h
+++ b/include/linux/qnxtypes.h
@@ -12,18 +12,18 @@
12#ifndef _QNX4TYPES_H 12#ifndef _QNX4TYPES_H
13#define _QNX4TYPES_H 13#define _QNX4TYPES_H
14 14
15typedef __u16 qnx4_nxtnt_t; 15typedef __le16 qnx4_nxtnt_t;
16typedef __u8 qnx4_ftype_t; 16typedef __u8 qnx4_ftype_t;
17 17
18typedef struct { 18typedef struct {
19 __u32 xtnt_blk; 19 __le32 xtnt_blk;
20 __u32 xtnt_size; 20 __le32 xtnt_size;
21} qnx4_xtnt_t; 21} qnx4_xtnt_t;
22 22
23typedef __u16 qnx4_mode_t; 23typedef __le16 qnx4_mode_t;
24typedef __u16 qnx4_muid_t; 24typedef __le16 qnx4_muid_t;
25typedef __u16 qnx4_mgid_t; 25typedef __le16 qnx4_mgid_t;
26typedef __u32 qnx4_off_t; 26typedef __le32 qnx4_off_t;
27typedef __u16 qnx4_nlink_t; 27typedef __le16 qnx4_nlink_t;
28 28
29#endif 29#endif
diff --git a/include/linux/quota.h b/include/linux/quota.h
index ac5b90f4f256..700ead45084f 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -138,8 +138,11 @@ struct if_dqinfo {
138#include <linux/dqblk_v2.h> 138#include <linux/dqblk_v2.h>
139 139
140/* Maximal numbers of writes for quota operation (insert/delete/update) 140/* Maximal numbers of writes for quota operation (insert/delete/update)
141 * (over all formats) - info block, 4 pointer blocks, data block */ 141 * (over VFS all formats) */
142#define DQUOT_MAX_WRITES 6 142#define DQUOT_INIT_ALLOC max(V1_INIT_ALLOC, V2_INIT_ALLOC)
143#define DQUOT_INIT_REWRITE max(V1_INIT_REWRITE, V2_INIT_REWRITE)
144#define DQUOT_DEL_ALLOC max(V1_DEL_ALLOC, V2_DEL_ALLOC)
145#define DQUOT_DEL_REWRITE max(V1_DEL_REWRITE, V2_DEL_REWRITE)
143 146
144/* 147/*
145 * Data for one user/group kept in memory 148 * Data for one user/group kept in memory
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index e57baa85e744..d211507ab246 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -39,7 +39,8 @@ extern int dquot_commit_info(struct super_block *sb, int type);
39extern int dquot_mark_dquot_dirty(struct dquot *dquot); 39extern int dquot_mark_dquot_dirty(struct dquot *dquot);
40 40
41extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path); 41extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
42extern int vfs_quota_on_mount(int type, int format_id, struct dentry *dentry); 42extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
43 int format_id, int type);
43extern int vfs_quota_off(struct super_block *sb, int type); 44extern int vfs_quota_off(struct super_block *sb, int type);
44#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type) 45#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type)
45extern int vfs_quota_sync(struct super_block *sb, int type); 46extern int vfs_quota_sync(struct super_block *sb, int type);
diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h
index 2aef9c3f5ce8..0760507a545b 100644
--- a/include/linux/reiserfs_acl.h
+++ b/include/linux/reiserfs_acl.h
@@ -1,6 +1,5 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <linux/posix_acl.h> 2#include <linux/posix_acl.h>
3#include <linux/xattr_acl.h>
4 3
5#define REISERFS_ACL_VERSION 0x0001 4#define REISERFS_ACL_VERSION 0x0001
6 5
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 32148625fc2f..4c7c5689ad93 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1644,11 +1644,18 @@ struct reiserfs_journal_header {
1644#define JOURNAL_MAX_TRANS_AGE 30 1644#define JOURNAL_MAX_TRANS_AGE 30
1645#define JOURNAL_PER_BALANCE_CNT (3 * (MAX_HEIGHT-2) + 9) 1645#define JOURNAL_PER_BALANCE_CNT (3 * (MAX_HEIGHT-2) + 9)
1646#ifdef CONFIG_QUOTA 1646#ifdef CONFIG_QUOTA
1647#define REISERFS_QUOTA_TRANS_BLOCKS 2 /* We need to update data and inode (atime) */ 1647/* We need to update data and inode (atime) */
1648#define REISERFS_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*(JOURNAL_PER_BALANCE_CNT+2)+1) /* 1 balancing, 1 bitmap, 1 data per write + stat data update */ 1648#define REISERFS_QUOTA_TRANS_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<<REISERFS_QUOTA) ? 2 : 0)
1649/* 1 balancing, 1 bitmap, 1 data per write + stat data update */
1650#define REISERFS_QUOTA_INIT_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<<REISERFS_QUOTA) ? \
1651(DQUOT_INIT_ALLOC*(JOURNAL_PER_BALANCE_CNT+2)+DQUOT_INIT_REWRITE+1) : 0)
1652/* same as with INIT */
1653#define REISERFS_QUOTA_DEL_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<<REISERFS_QUOTA) ? \
1654(DQUOT_DEL_ALLOC*(JOURNAL_PER_BALANCE_CNT+2)+DQUOT_DEL_REWRITE+1) : 0)
1649#else 1655#else
1650#define REISERFS_QUOTA_TRANS_BLOCKS 0 1656#define REISERFS_QUOTA_TRANS_BLOCKS(s) 0
1651#define REISERFS_QUOTA_INIT_BLOCKS 0 1657#define REISERFS_QUOTA_INIT_BLOCKS(s) 0
1658#define REISERFS_QUOTA_DEL_BLOCKS(s) 0
1652#endif 1659#endif
1653 1660
1654/* both of these can be as low as 1, or as high as you want. The min is the 1661/* both of these can be as low as 1, or as high as you want. The min is the
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 37a3a7afbec7..31c709d0fe18 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -467,6 +467,8 @@ enum reiserfs_mount_options {
467 REISERFS_ERROR_RO, 467 REISERFS_ERROR_RO,
468 REISERFS_ERROR_CONTINUE, 468 REISERFS_ERROR_CONTINUE,
469 469
470 REISERFS_QUOTA, /* Some quota option specified */
471
470 REISERFS_TEST1, 472 REISERFS_TEST1,
471 REISERFS_TEST2, 473 REISERFS_TEST2,
472 REISERFS_TEST3, 474 REISERFS_TEST3,
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 11b484e37ac9..e80fb7ee6efd 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -93,6 +93,12 @@ int page_referenced(struct page *, int is_locked, int ignore_token);
93int try_to_unmap(struct page *); 93int try_to_unmap(struct page *);
94 94
95/* 95/*
96 * Called from mm/filemap_xip.c to unmap empty zero page
97 */
98pte_t *page_check_address(struct page *, struct mm_struct *, unsigned long);
99
100
101/*
96 * Used by swapoff to help locate where page is expected in vma. 102 * Used by swapoff to help locate where page is expected in vma.
97 */ 103 */
98unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); 104unsigned long page_address_in_vma(struct page *, struct vm_area_struct *);
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index e68dbf0bf579..d021888b58f1 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -892,10 +892,13 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi
892 goto rtattr_failure; \ 892 goto rtattr_failure; \
893 __rta_fill(skb, attrtype, attrlen, data); }) 893 __rta_fill(skb, attrtype, attrlen, data); })
894 894
895#define RTA_PUT_NOHDR(skb, attrlen, data) \ 895#define RTA_APPEND(skb, attrlen, data) \
896({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \ 896({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \
897 goto rtattr_failure; \ 897 goto rtattr_failure; \
898 memcpy(skb_put(skb, RTA_ALIGN(attrlen)), data, attrlen); }) 898 memcpy(skb_put(skb, attrlen), data, attrlen); })
899
900#define RTA_PUT_NOHDR(skb, attrlen, data) \
901 RTA_APPEND(skb, RTA_ALIGN(attrlen), data)
899 902
900#define RTA_PUT_U8(skb, attrtype, value) \ 903#define RTA_PUT_U8(skb, attrtype, value) \
901({ u8 _tmp = (value); \ 904({ u8 _tmp = (value); \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b58afd97a180..2c69682b0444 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -246,7 +246,7 @@ struct mm_struct {
246 246
247 unsigned long saved_auxv[42]; /* for /proc/PID/auxv */ 247 unsigned long saved_auxv[42]; /* for /proc/PID/auxv */
248 248
249 unsigned dumpable:1; 249 unsigned dumpable:2;
250 cpumask_t cpu_vm_mask; 250 cpumask_t cpu_vm_mask;
251 251
252 /* Architecture-specific MM context */ 252 /* Architecture-specific MM context */
@@ -561,9 +561,10 @@ struct group_info {
561 groups_free(group_info); \ 561 groups_free(group_info); \
562} while (0) 562} while (0)
563 563
564struct group_info *groups_alloc(int gidsetsize); 564extern struct group_info *groups_alloc(int gidsetsize);
565void groups_free(struct group_info *group_info); 565extern void groups_free(struct group_info *group_info);
566int set_current_groups(struct group_info *group_info); 566extern int set_current_groups(struct group_info *group_info);
567extern int groups_search(struct group_info *group_info, gid_t grp);
567/* access the groups "array" with this macro */ 568/* access the groups "array" with this macro */
568#define GROUP_AT(gi, i) \ 569#define GROUP_AT(gi, i) \
569 ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK]) 570 ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
@@ -660,6 +661,7 @@ struct task_struct {
660 struct user_struct *user; 661 struct user_struct *user;
661#ifdef CONFIG_KEYS 662#ifdef CONFIG_KEYS
662 struct key *thread_keyring; /* keyring private to this thread */ 663 struct key *thread_keyring; /* keyring private to this thread */
664 unsigned char jit_keyring; /* default keyring to attach requested keys to */
663#endif 665#endif
664 int oomkilladj; /* OOM kill score adjustment (bit shift). */ 666 int oomkilladj; /* OOM kill score adjustment (bit shift). */
665 char comm[TASK_COMM_LEN]; /* executable name excluding path 667 char comm[TASK_COMM_LEN]; /* executable name excluding path
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d7c839a21842..416a2e4024b2 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -27,6 +27,7 @@
27#include <linux/highmem.h> 27#include <linux/highmem.h>
28#include <linux/poll.h> 28#include <linux/poll.h>
29#include <linux/net.h> 29#include <linux/net.h>
30#include <linux/textsearch.h>
30#include <net/checksum.h> 31#include <net/checksum.h>
31 32
32#define HAVE_ALLOC_SKB /* For the drivers to know */ 33#define HAVE_ALLOC_SKB /* For the drivers to know */
@@ -321,6 +322,28 @@ extern void skb_over_panic(struct sk_buff *skb, int len,
321extern void skb_under_panic(struct sk_buff *skb, int len, 322extern void skb_under_panic(struct sk_buff *skb, int len,
322 void *here); 323 void *here);
323 324
325struct skb_seq_state
326{
327 __u32 lower_offset;
328 __u32 upper_offset;
329 __u32 frag_idx;
330 __u32 stepped_offset;
331 struct sk_buff *root_skb;
332 struct sk_buff *cur_skb;
333 __u8 *frag_data;
334};
335
336extern void skb_prepare_seq_read(struct sk_buff *skb,
337 unsigned int from, unsigned int to,
338 struct skb_seq_state *st);
339extern unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
340 struct skb_seq_state *st);
341extern void skb_abort_seq_read(struct skb_seq_state *st);
342
343extern unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
344 unsigned int to, struct ts_config *config,
345 struct ts_state *state);
346
324/* Internal */ 347/* Internal */
325#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) 348#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end))
326 349
diff --git a/include/linux/string.h b/include/linux/string.h
index b9fc59469956..93994c613095 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -88,6 +88,8 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
88extern void * memchr(const void *,int,__kernel_size_t); 88extern void * memchr(const void *,int,__kernel_size_t);
89#endif 89#endif
90 90
91extern char *kstrdup(const char *s, int gfp);
92
91#ifdef __cplusplus 93#ifdef __cplusplus
92} 94}
93#endif 95#endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index a17745c80a91..ebfe1250f0a4 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -136,6 +136,7 @@ enum
136 KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */ 136 KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
137 KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */ 137 KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */
138 KERN_RANDOMIZE=68, /* int: randomize virtual address space */ 138 KERN_RANDOMIZE=68, /* int: randomize virtual address space */
139 KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */
139}; 140};
140 141
141 142
@@ -242,6 +243,7 @@ enum
242 NET_CORE_MOD_CONG=16, 243 NET_CORE_MOD_CONG=16,
243 NET_CORE_DEV_WEIGHT=17, 244 NET_CORE_DEV_WEIGHT=17,
244 NET_CORE_SOMAXCONN=18, 245 NET_CORE_SOMAXCONN=18,
246 NET_CORE_BUDGET=19,
245}; 247};
246 248
247/* /proc/sys/net/ethernet */ 249/* /proc/sys/net/ethernet */
@@ -332,21 +334,14 @@ enum
332 NET_TCP_FRTO=92, 334 NET_TCP_FRTO=92,
333 NET_TCP_LOW_LATENCY=93, 335 NET_TCP_LOW_LATENCY=93,
334 NET_IPV4_IPFRAG_SECRET_INTERVAL=94, 336 NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
335 NET_TCP_WESTWOOD=95,
336 NET_IPV4_IGMP_MAX_MSF=96, 337 NET_IPV4_IGMP_MAX_MSF=96,
337 NET_TCP_NO_METRICS_SAVE=97, 338 NET_TCP_NO_METRICS_SAVE=97,
338 NET_TCP_VEGAS=98,
339 NET_TCP_VEGAS_ALPHA=99,
340 NET_TCP_VEGAS_BETA=100,
341 NET_TCP_VEGAS_GAMMA=101,
342 NET_TCP_BIC=102,
343 NET_TCP_BIC_FAST_CONVERGENCE=103,
344 NET_TCP_BIC_LOW_WINDOW=104,
345 NET_TCP_DEFAULT_WIN_SCALE=105, 339 NET_TCP_DEFAULT_WIN_SCALE=105,
346 NET_TCP_MODERATE_RCVBUF=106, 340 NET_TCP_MODERATE_RCVBUF=106,
347 NET_TCP_TSO_WIN_DIVISOR=107, 341 NET_TCP_TSO_WIN_DIVISOR=107,
348 NET_TCP_BIC_BETA=108, 342 NET_TCP_BIC_BETA=108,
349 NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109, 343 NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
344 NET_TCP_CONG_CONTROL=110,
350}; 345};
351 346
352enum { 347enum {
diff --git a/include/linux/tc_ematch/tc_em_text.h b/include/linux/tc_ematch/tc_em_text.h
new file mode 100644
index 000000000000..7cd43e99c7f5
--- /dev/null
+++ b/include/linux/tc_ematch/tc_em_text.h
@@ -0,0 +1,19 @@
1#ifndef __LINUX_TC_EM_TEXT_H
2#define __LINUX_TC_EM_TEXT_H
3
4#include <linux/pkt_cls.h>
5
6#define TC_EM_TEXT_ALGOSIZ 16
7
8struct tcf_em_text
9{
10 char algo[TC_EM_TEXT_ALGOSIZ];
11 __u16 from_offset;
12 __u16 to_offset;
13 __u16 pattern_len;
14 __u8 from_layer:4;
15 __u8 to_layer:4;
16 __u8 pad;
17};
18
19#endif
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 97a7c9e03df5..dfd93d03f5d2 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -127,6 +127,7 @@ enum {
127#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ 127#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
128#define TCP_INFO 11 /* Information about this connection. */ 128#define TCP_INFO 11 /* Information about this connection. */
129#define TCP_QUICKACK 12 /* Block/reenable quick acks */ 129#define TCP_QUICKACK 12 /* Block/reenable quick acks */
130#define TCP_CONGESTION 13 /* Congestion control algorithm */
130 131
131#define TCPI_OPT_TIMESTAMPS 1 132#define TCPI_OPT_TIMESTAMPS 1
132#define TCPI_OPT_SACK 2 133#define TCPI_OPT_SACK 2
@@ -203,13 +204,6 @@ struct tcp_sack_block {
203 __u32 end_seq; 204 __u32 end_seq;
204}; 205};
205 206
206enum tcp_congestion_algo {
207 TCP_RENO=0,
208 TCP_VEGAS,
209 TCP_WESTWOOD,
210 TCP_BIC,
211};
212
213struct tcp_options_received { 207struct tcp_options_received {
214/* PAWS/RTTM data */ 208/* PAWS/RTTM data */
215 long ts_recent_stamp;/* Time we stored ts_recent (for aging) */ 209 long ts_recent_stamp;/* Time we stored ts_recent (for aging) */
@@ -305,7 +299,7 @@ struct tcp_sock {
305 __u8 reordering; /* Packet reordering metric. */ 299 __u8 reordering; /* Packet reordering metric. */
306 __u8 frto_counter; /* Number of new acks after RTO */ 300 __u8 frto_counter; /* Number of new acks after RTO */
307 301
308 __u8 adv_cong; /* Using Vegas, Westwood, or BIC */ 302 __u8 unused;
309 __u8 defer_accept; /* User waits for some data after accept() */ 303 __u8 defer_accept; /* User waits for some data after accept() */
310 304
311/* RTT measurement */ 305/* RTT measurement */
@@ -401,37 +395,10 @@ struct tcp_sock {
401 __u32 time; 395 __u32 time;
402 } rcvq_space; 396 } rcvq_space;
403 397
404/* TCP Westwood structure */ 398 /* Pluggable TCP congestion control hook */
405 struct { 399 struct tcp_congestion_ops *ca_ops;
406 __u32 bw_ns_est; /* first bandwidth estimation..not too smoothed 8) */ 400 u32 ca_priv[16];
407 __u32 bw_est; /* bandwidth estimate */ 401#define TCP_CA_PRIV_SIZE (16*sizeof(u32))
408 __u32 rtt_win_sx; /* here starts a new evaluation... */
409 __u32 bk;
410 __u32 snd_una; /* used for evaluating the number of acked bytes */
411 __u32 cumul_ack;
412 __u32 accounted;
413 __u32 rtt;
414 __u32 rtt_min; /* minimum observed RTT */
415 } westwood;
416
417/* Vegas variables */
418 struct {
419 __u32 beg_snd_nxt; /* right edge during last RTT */
420 __u32 beg_snd_una; /* left edge during last RTT */
421 __u32 beg_snd_cwnd; /* saves the size of the cwnd */
422 __u8 doing_vegas_now;/* if true, do vegas for this RTT */
423 __u16 cntRTT; /* # of RTTs measured within last RTT */
424 __u32 minRTT; /* min of RTTs measured within last RTT (in usec) */
425 __u32 baseRTT; /* the min of all Vegas RTT measurements seen (in usec) */
426 } vegas;
427
428 /* BI TCP Parameters */
429 struct {
430 __u32 cnt; /* increase cwnd by 1 after this number of ACKs */
431 __u32 last_max_cwnd; /* last maximium snd_cwnd */
432 __u32 last_cwnd; /* the last snd_cwnd */
433 __u32 last_stamp; /* time when updated last_cwnd */
434 } bictcp;
435}; 402};
436 403
437static inline struct tcp_sock *tcp_sk(const struct sock *sk) 404static inline struct tcp_sock *tcp_sk(const struct sock *sk)
@@ -439,6 +406,11 @@ static inline struct tcp_sock *tcp_sk(const struct sock *sk)
439 return (struct tcp_sock *)sk; 406 return (struct tcp_sock *)sk;
440} 407}
441 408
409static inline void *tcp_ca(const struct tcp_sock *tp)
410{
411 return (void *) tp->ca_priv;
412}
413
442#endif 414#endif
443 415
444#endif /* _LINUX_TCP_H */ 416#endif /* _LINUX_TCP_H */
diff --git a/include/linux/tcp_diag.h b/include/linux/tcp_diag.h
index ceee962e1d15..7a5996743946 100644
--- a/include/linux/tcp_diag.h
+++ b/include/linux/tcp_diag.h
@@ -99,9 +99,10 @@ enum
99 TCPDIAG_MEMINFO, 99 TCPDIAG_MEMINFO,
100 TCPDIAG_INFO, 100 TCPDIAG_INFO,
101 TCPDIAG_VEGASINFO, 101 TCPDIAG_VEGASINFO,
102 TCPDIAG_CONG,
102}; 103};
103 104
104#define TCPDIAG_MAX TCPDIAG_VEGASINFO 105#define TCPDIAG_MAX TCPDIAG_CONG
105 106
106 107
107/* TCPDIAG_MEM */ 108/* TCPDIAG_MEM */
@@ -123,5 +124,4 @@ struct tcpvegas_info {
123 __u32 tcpv_minrtt; 124 __u32 tcpv_minrtt;
124}; 125};
125 126
126
127#endif /* _TCP_DIAG_H_ */ 127#endif /* _TCP_DIAG_H_ */
diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h
new file mode 100644
index 000000000000..941f45ac117a
--- /dev/null
+++ b/include/linux/textsearch.h
@@ -0,0 +1,180 @@
1#ifndef __LINUX_TEXTSEARCH_H
2#define __LINUX_TEXTSEARCH_H
3
4#ifdef __KERNEL__
5
6#include <linux/types.h>
7#include <linux/list.h>
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/err.h>
11
12struct ts_config;
13
14/**
15 * TS_AUTOLOAD - Automatically load textsearch modules when needed
16 */
17#define TS_AUTOLOAD 1
18
19/**
20 * struct ts_state - search state
21 * @offset: offset for next match
22 * @cb: control buffer, for persistant variables of get_next_block()
23 */
24struct ts_state
25{
26 unsigned int offset;
27 char cb[40];
28};
29
30/**
31 * struct ts_ops - search module operations
32 * @name: name of search algorithm
33 * @init: initialization function to prepare a search
34 * @find: find the next occurrence of the pattern
35 * @destroy: destroy algorithm specific parts of a search configuration
36 * @get_pattern: return head of pattern
37 * @get_pattern_len: return length of pattern
38 * @owner: module reference to algorithm
39 */
40struct ts_ops
41{
42 const char *name;
43 struct ts_config * (*init)(const void *, unsigned int, int);
44 unsigned int (*find)(struct ts_config *,
45 struct ts_state *);
46 void (*destroy)(struct ts_config *);
47 void * (*get_pattern)(struct ts_config *);
48 unsigned int (*get_pattern_len)(struct ts_config *);
49 struct module *owner;
50 struct list_head list;
51};
52
53/**
54 * struct ts_config - search configuration
55 * @ops: operations of chosen algorithm
56 * @get_next_block: callback to fetch the next block to search in
57 * @finish: callback to finalize a search
58 */
59struct ts_config
60{
61 struct ts_ops *ops;
62
63 /**
64 * get_next_block - fetch next block of data
65 * @consumed: number of bytes consumed by the caller
66 * @dst: destination buffer
67 * @conf: search configuration
68 * @state: search state
69 *
70 * Called repeatedly until 0 is returned. Must assign the
71 * head of the next block of data to &*dst and return the length
72 * of the block or 0 if at the end. consumed == 0 indicates
73 * a new search. May store/read persistant values in state->cb.
74 */
75 unsigned int (*get_next_block)(unsigned int consumed,
76 const u8 **dst,
77 struct ts_config *conf,
78 struct ts_state *state);
79
80 /**
81 * finish - finalize/clean a series of get_next_block() calls
82 * @conf: search configuration
83 * @state: search state
84 *
85 * Called after the last use of get_next_block(), may be used
86 * to cleanup any leftovers.
87 */
88 void (*finish)(struct ts_config *conf,
89 struct ts_state *state);
90};
91
92/**
93 * textsearch_next - continue searching for a pattern
94 * @conf: search configuration
95 * @state: search state
96 *
97 * Continues a search looking for more occurrences of the pattern.
98 * textsearch_find() must be called to find the first occurrence
99 * in order to reset the state.
100 *
101 * Returns the position of the next occurrence of the pattern or
102 * UINT_MAX if not match was found.
103 */
104static inline unsigned int textsearch_next(struct ts_config *conf,
105 struct ts_state *state)
106{
107 unsigned int ret = conf->ops->find(conf, state);
108
109 if (conf->finish)
110 conf->finish(conf, state);
111
112 return ret;
113}
114
115/**
116 * textsearch_find - start searching for a pattern
117 * @conf: search configuration
118 * @state: search state
119 *
120 * Returns the position of first occurrence of the pattern or
121 * UINT_MAX if no match was found.
122 */
123static inline unsigned int textsearch_find(struct ts_config *conf,
124 struct ts_state *state)
125{
126 state->offset = 0;
127 return textsearch_next(conf, state);
128}
129
130/**
131 * textsearch_get_pattern - return head of the pattern
132 * @conf: search configuration
133 */
134static inline void *textsearch_get_pattern(struct ts_config *conf)
135{
136 return conf->ops->get_pattern(conf);
137}
138
139/**
140 * textsearch_get_pattern_len - return length of the pattern
141 * @conf: search configuration
142 */
143static inline unsigned int textsearch_get_pattern_len(struct ts_config *conf)
144{
145 return conf->ops->get_pattern_len(conf);
146}
147
148extern int textsearch_register(struct ts_ops *);
149extern int textsearch_unregister(struct ts_ops *);
150extern struct ts_config *textsearch_prepare(const char *, const void *,
151 unsigned int, int, int);
152extern void textsearch_destroy(struct ts_config *conf);
153extern unsigned int textsearch_find_continuous(struct ts_config *,
154 struct ts_state *,
155 const void *, unsigned int);
156
157
158#define TS_PRIV_ALIGNTO 8
159#define TS_PRIV_ALIGN(len) (((len) + TS_PRIV_ALIGNTO-1) & ~(TS_PRIV_ALIGNTO-1))
160
161static inline struct ts_config *alloc_ts_config(size_t payload, int gfp_mask)
162{
163 struct ts_config *conf;
164
165 conf = kmalloc(TS_PRIV_ALIGN(sizeof(*conf)) + payload, gfp_mask);
166 if (conf == NULL)
167 return ERR_PTR(-ENOMEM);
168
169 memset(conf, 0, TS_PRIV_ALIGN(sizeof(*conf)) + payload);
170 return conf;
171}
172
173static inline void *ts_config_priv(struct ts_config *conf)
174{
175 return ((u8 *) conf + TS_PRIV_ALIGN(sizeof(struct ts_config)));
176}
177
178#endif /* __KERNEL__ */
179
180#endif
diff --git a/include/linux/textsearch_fsm.h b/include/linux/textsearch_fsm.h
new file mode 100644
index 000000000000..fdfa078c66e5
--- /dev/null
+++ b/include/linux/textsearch_fsm.h
@@ -0,0 +1,48 @@
1#ifndef __LINUX_TEXTSEARCH_FSM_H
2#define __LINUX_TEXTSEARCH_FSM_H
3
4#include <linux/types.h>
5
6enum {
7 TS_FSM_SPECIFIC, /* specific character */
8 TS_FSM_WILDCARD, /* any character */
9 TS_FSM_DIGIT, /* isdigit() */
10 TS_FSM_XDIGIT, /* isxdigit() */
11 TS_FSM_PRINT, /* isprint() */
12 TS_FSM_ALPHA, /* isalpha() */
13 TS_FSM_ALNUM, /* isalnum() */
14 TS_FSM_ASCII, /* isascii() */
15 TS_FSM_CNTRL, /* iscntrl() */
16 TS_FSM_GRAPH, /* isgraph() */
17 TS_FSM_LOWER, /* islower() */
18 TS_FSM_UPPER, /* isupper() */
19 TS_FSM_PUNCT, /* ispunct() */
20 TS_FSM_SPACE, /* isspace() */
21 __TS_FSM_TYPE_MAX,
22};
23#define TS_FSM_TYPE_MAX (__TS_FSM_TYPE_MAX - 1)
24
25enum {
26 TS_FSM_SINGLE, /* 1 occurrence */
27 TS_FSM_PERHAPS, /* 1 or 0 occurrence */
28 TS_FSM_ANY, /* 0..n occurrences */
29 TS_FSM_MULTI, /* 1..n occurrences */
30 TS_FSM_HEAD_IGNORE, /* 0..n ignored occurrences at head */
31 __TS_FSM_RECUR_MAX,
32};
33#define TS_FSM_RECUR_MAX (__TS_FSM_RECUR_MAX - 1)
34
35/**
36 * struct ts_fsm_token - state machine token (state)
37 * @type: type of token
38 * @recur: number of recurrences
39 * @value: character value for TS_FSM_SPECIFIC
40 */
41struct ts_fsm_token
42{
43 __u16 type;
44 __u8 recur;
45 __u8 value;
46};
47
48#endif
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 90db1cc62ddd..221f81ac2002 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -6,45 +6,33 @@
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/stddef.h> 7#include <linux/stddef.h>
8 8
9struct tvec_t_base_s; 9struct timer_base_s;
10 10
11struct timer_list { 11struct timer_list {
12 struct list_head entry; 12 struct list_head entry;
13 unsigned long expires; 13 unsigned long expires;
14 14
15 spinlock_t lock;
16 unsigned long magic; 15 unsigned long magic;
17 16
18 void (*function)(unsigned long); 17 void (*function)(unsigned long);
19 unsigned long data; 18 unsigned long data;
20 19
21 struct tvec_t_base_s *base; 20 struct timer_base_s *base;
22}; 21};
23 22
24#define TIMER_MAGIC 0x4b87ad6e 23#define TIMER_MAGIC 0x4b87ad6e
25 24
25extern struct timer_base_s __init_timer_base;
26
26#define TIMER_INITIALIZER(_function, _expires, _data) { \ 27#define TIMER_INITIALIZER(_function, _expires, _data) { \
27 .function = (_function), \ 28 .function = (_function), \
28 .expires = (_expires), \ 29 .expires = (_expires), \
29 .data = (_data), \ 30 .data = (_data), \
30 .base = NULL, \ 31 .base = &__init_timer_base, \
31 .magic = TIMER_MAGIC, \ 32 .magic = TIMER_MAGIC, \
32 .lock = SPIN_LOCK_UNLOCKED, \
33 } 33 }
34 34
35/*** 35void fastcall init_timer(struct timer_list * timer);
36 * init_timer - initialize a timer.
37 * @timer: the timer to be initialized
38 *
39 * init_timer() must be done to a timer prior calling *any* of the
40 * other timer functions.
41 */
42static inline void init_timer(struct timer_list * timer)
43{
44 timer->base = NULL;
45 timer->magic = TIMER_MAGIC;
46 spin_lock_init(&timer->lock);
47}
48 36
49/*** 37/***
50 * timer_pending - is a timer pending? 38 * timer_pending - is a timer pending?
@@ -58,7 +46,7 @@ static inline void init_timer(struct timer_list * timer)
58 */ 46 */
59static inline int timer_pending(const struct timer_list * timer) 47static inline int timer_pending(const struct timer_list * timer)
60{ 48{
61 return timer->base != NULL; 49 return timer->entry.next != NULL;
62} 50}
63 51
64extern void add_timer_on(struct timer_list *timer, int cpu); 52extern void add_timer_on(struct timer_list *timer, int cpu);
@@ -88,13 +76,15 @@ static inline void add_timer(struct timer_list * timer)
88} 76}
89 77
90#ifdef CONFIG_SMP 78#ifdef CONFIG_SMP
79 extern int try_to_del_timer_sync(struct timer_list *timer);
91 extern int del_timer_sync(struct timer_list *timer); 80 extern int del_timer_sync(struct timer_list *timer);
92 extern int del_singleshot_timer_sync(struct timer_list *timer);
93#else 81#else
94# define del_timer_sync(t) del_timer(t) 82# define try_to_del_timer_sync(t) del_timer(t)
95# define del_singleshot_timer_sync(t) del_timer(t) 83# define del_timer_sync(t) del_timer(t)
96#endif 84#endif
97 85
86#define del_singleshot_timer_sync(t) del_timer_sync(t)
87
98extern void init_timers(void); 88extern void init_timers(void);
99extern void run_local_timers(void); 89extern void run_local_timers(void);
100extern void it_real_fn(unsigned long); 90extern void it_real_fn(unsigned long);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1b76106272d3..59ff42c629ec 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -345,6 +345,7 @@ extern int tty_check_change(struct tty_struct * tty);
345extern void stop_tty(struct tty_struct * tty); 345extern void stop_tty(struct tty_struct * tty);
346extern void start_tty(struct tty_struct * tty); 346extern void start_tty(struct tty_struct * tty);
347extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc); 347extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
348extern int tty_unregister_ldisc(int disc);
348extern int tty_register_driver(struct tty_driver *driver); 349extern int tty_register_driver(struct tty_driver *driver);
349extern int tty_unregister_driver(struct tty_driver *driver); 350extern int tty_unregister_driver(struct tty_driver *driver);
350extern void tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev); 351extern void tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 3d508bf08402..eb282b581546 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -290,7 +290,7 @@ struct usb_bus {
290 struct class_device *class_dev; /* class device for this bus */ 290 struct class_device *class_dev; /* class device for this bus */
291 struct kref kref; /* handles reference counting this bus */ 291 struct kref kref; /* handles reference counting this bus */
292 void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */ 292 void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */
293#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) 293#if defined(CONFIG_USB_MON)
294 struct mon_bus *mon_bus; /* non-null when associated */ 294 struct mon_bus *mon_bus; /* non-null when associated */
295 int monitored; /* non-zero when monitored */ 295 int monitored; /* non-zero when monitored */
296#endif 296#endif
diff --git a/include/linux/wait.h b/include/linux/wait.h
index c9486c3efb4a..d38c9fecdc36 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -33,7 +33,7 @@ int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key
33struct __wait_queue { 33struct __wait_queue {
34 unsigned int flags; 34 unsigned int flags;
35#define WQ_FLAG_EXCLUSIVE 0x01 35#define WQ_FLAG_EXCLUSIVE 0x01
36 struct task_struct * task; 36 void *private;
37 wait_queue_func_t func; 37 wait_queue_func_t func;
38 struct list_head task_list; 38 struct list_head task_list;
39}; 39};
@@ -60,7 +60,7 @@ typedef struct __wait_queue_head wait_queue_head_t;
60 */ 60 */
61 61
62#define __WAITQUEUE_INITIALIZER(name, tsk) { \ 62#define __WAITQUEUE_INITIALIZER(name, tsk) { \
63 .task = tsk, \ 63 .private = tsk, \
64 .func = default_wake_function, \ 64 .func = default_wake_function, \
65 .task_list = { NULL, NULL } } 65 .task_list = { NULL, NULL } }
66 66
@@ -86,7 +86,7 @@ static inline void init_waitqueue_head(wait_queue_head_t *q)
86static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p) 86static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
87{ 87{
88 q->flags = 0; 88 q->flags = 0;
89 q->task = p; 89 q->private = p;
90 q->func = default_wake_function; 90 q->func = default_wake_function;
91} 91}
92 92
@@ -94,7 +94,7 @@ static inline void init_waitqueue_func_entry(wait_queue_t *q,
94 wait_queue_func_t func) 94 wait_queue_func_t func)
95{ 95{
96 q->flags = 0; 96 q->flags = 0;
97 q->task = NULL; 97 q->private = NULL;
98 q->func = func; 98 q->func = func;
99} 99}
100 100
@@ -110,7 +110,7 @@ static inline int waitqueue_active(wait_queue_head_t *q)
110 * aio specifies a wait queue entry with an async notification 110 * aio specifies a wait queue entry with an async notification
111 * callback routine, not associated with any task. 111 * callback routine, not associated with any task.
112 */ 112 */
113#define is_sync_wait(wait) (!(wait) || ((wait)->task)) 113#define is_sync_wait(wait) (!(wait) || ((wait)->private))
114 114
115extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); 115extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
116extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)); 116extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
@@ -384,7 +384,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
384 384
385#define DEFINE_WAIT(name) \ 385#define DEFINE_WAIT(name) \
386 wait_queue_t name = { \ 386 wait_queue_t name = { \
387 .task = current, \ 387 .private = current, \
388 .func = autoremove_wake_function, \ 388 .func = autoremove_wake_function, \
389 .task_list = LIST_HEAD_INIT((name).task_list), \ 389 .task_list = LIST_HEAD_INIT((name).task_list), \
390 } 390 }
@@ -393,7 +393,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
393 struct wait_bit_queue name = { \ 393 struct wait_bit_queue name = { \
394 .key = __WAIT_BIT_KEY_INITIALIZER(word, bit), \ 394 .key = __WAIT_BIT_KEY_INITIALIZER(word, bit), \
395 .wait = { \ 395 .wait = { \
396 .task = current, \ 396 .private = current, \
397 .func = wake_bit_function, \ 397 .func = wake_bit_function, \
398 .task_list = \ 398 .task_list = \
399 LIST_HEAD_INIT((name).wait.task_list), \ 399 LIST_HEAD_INIT((name).wait.task_list), \
@@ -402,7 +402,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
402 402
403#define init_wait(wait) \ 403#define init_wait(wait) \
404 do { \ 404 do { \
405 (wait)->task = current; \ 405 (wait)->private = current; \
406 (wait)->func = autoremove_wake_function; \ 406 (wait)->func = autoremove_wake_function; \
407 INIT_LIST_HEAD(&(wait)->task_list); \ 407 INIT_LIST_HEAD(&(wait)->task_list); \
408 } while (0) 408 } while (0)
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index d3e9e30608dc..f345a61c3bdb 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -1,3 +1,7 @@
1/*
2 * $Id: audiochip.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $
3 */
4
1#ifndef AUDIOCHIP_H 5#ifndef AUDIOCHIP_H
2#define AUDIOCHIP_H 6#define AUDIOCHIP_H
3 7
diff --git a/include/media/id.h b/include/media/id.h
index 1b0320dc8f73..a39a6423914b 100644
--- a/include/media/id.h
+++ b/include/media/id.h
@@ -1,3 +1,7 @@
1/*
2 * $Id: id.h,v 1.4 2005/06/12 04:19:19 mchehab Exp $
3 */
4
1/* FIXME: this temporarely, until these are included in linux/i2c-id.h */ 5/* FIXME: this temporarely, until these are included in linux/i2c-id.h */
2 6
3/* drivers */ 7/* drivers */
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 62c963a52d86..698670547f16 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ir-common.h,v 1.8 2005/02/22 12:28:40 kraxel Exp $ 2 * $Id: ir-common.h,v 1.9 2005/05/15 19:01:26 mchehab Exp $
3 * 3 *
4 * some common structs and functions to handle infrared remotes via 4 * some common structs and functions to handle infrared remotes via
5 * input layer ... 5 * input layer ...
@@ -50,6 +50,7 @@ extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE];
50extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE]; 50extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE];
51extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; 51extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE];
52extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE]; 52extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
53extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE];
53 54
54void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, 55void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
55 int ir_type, IR_KEYTAB_TYPE *ir_codes); 56 int ir_type, IR_KEYTAB_TYPE *ir_codes);
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 156a9c51ffec..2dd8310901e8 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -25,6 +25,8 @@
25 25
26#include "id.h" 26#include "id.h"
27 27
28#define ADDR_UNSET (255)
29
28#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ 30#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
29#define TUNER_PHILIPS_PAL_I 1 31#define TUNER_PHILIPS_PAL_I 1
30#define TUNER_PHILIPS_NTSC 2 32#define TUNER_PHILIPS_NTSC 2
@@ -98,12 +100,23 @@
98#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ 100#define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
99#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ 101#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */
100 102
103#define TUNER_YMEC_TVF_8531MF 58
104#define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */
105#define TUNER_THOMSON_DTT7611 60
106#define TUNER_TENA_9533_DI 61
107#define TUNER_TEA5767 62 /* Only FM Radio Tuner */
108
109#define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio"
110
111#define TUNER_THOMSON_DTT7611 60
112
101#define NOTUNER 0 113#define NOTUNER 0
102#define PAL 1 /* PAL_BG */ 114#define PAL 1 /* PAL_BG */
103#define PAL_I 2 115#define PAL_I 2
104#define NTSC 3 116#define NTSC 3
105#define SECAM 4 117#define SECAM 4
106#define ATSC 5 118#define ATSC 5
119#define RADIO 6
107 120
108#define NoTuner 0 121#define NoTuner 0
109#define Philips 1 122#define Philips 1
@@ -119,10 +132,20 @@
119#define TCL 11 132#define TCL 11
120#define THOMSON 12 133#define THOMSON 12
121 134
135enum v4l_radio_tuner {
136 TEA5767_LOW_LO_32768 = 0,
137 TEA5767_HIGH_LO_32768 = 1,
138 TEA5767_LOW_LO_13MHz = 2,
139 TEA5767_HIGH_LO_13MHz = 3,
140};
141
142
122#define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */ 143#define TUNER_SET_TYPE _IOW('t',1,int) /* set tuner type */
123#define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */ 144#define TUNER_SET_TVFREQ _IOW('t',2,int) /* set tv freq */
145#define TUNER_SET_TYPE_ADDR _IOW('T',3,int) /* set tuner type and I2C addr */
124 146
125#define TDA9887_SET_CONFIG _IOW('t',5,int) 147#define TDA9887_SET_CONFIG _IOW('t',5,int)
148
126/* tv card specific */ 149/* tv card specific */
127# define TDA9887_PRESENT (1<<0) 150# define TDA9887_PRESENT (1<<0)
128# define TDA9887_PORT1_INACTIVE (1<<1) 151# define TDA9887_PORT1_INACTIVE (1<<1)
@@ -143,6 +166,12 @@
143#define I2C_ADDR_TDA8290 0x4b 166#define I2C_ADDR_TDA8290 0x4b
144#define I2C_ADDR_TDA8275 0x61 167#define I2C_ADDR_TDA8275 0x61
145 168
169struct tuner_addr {
170 enum v4l2_tuner_type v4l2_tuner;
171 unsigned int type;
172 unsigned short addr;
173};
174
146struct tuner { 175struct tuner {
147 /* device */ 176 /* device */
148 struct i2c_client i2c; 177 struct i2c_client i2c;
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index 627603e561a6..5c4fe30e8d1d 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -1,3 +1,7 @@
1/*
2 * $Id: tveeprom.h,v 1.2 2005/06/12 04:19:19 mchehab Exp $
3 */
4
1struct tveeprom { 5struct tveeprom {
2 u32 has_radio; 6 u32 has_radio;
3 7
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index a53e08a45e32..88d9fe5975d5 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -131,7 +131,6 @@ sctp_state_fn_t sctp_sf_do_ecne;
131sctp_state_fn_t sctp_sf_ootb; 131sctp_state_fn_t sctp_sf_ootb;
132sctp_state_fn_t sctp_sf_pdiscard; 132sctp_state_fn_t sctp_sf_pdiscard;
133sctp_state_fn_t sctp_sf_violation; 133sctp_state_fn_t sctp_sf_violation;
134sctp_state_fn_t sctp_sf_violation_chunklen;
135sctp_state_fn_t sctp_sf_discard_chunk; 134sctp_state_fn_t sctp_sf_discard_chunk;
136sctp_state_fn_t sctp_sf_do_5_2_1_siminit; 135sctp_state_fn_t sctp_sf_do_5_2_1_siminit;
137sctp_state_fn_t sctp_sf_do_5_2_2_dupinit; 136sctp_state_fn_t sctp_sf_do_5_2_2_dupinit;
@@ -259,11 +258,6 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
259void sctp_chunk_assign_tsn(struct sctp_chunk *); 258void sctp_chunk_assign_tsn(struct sctp_chunk *);
260void sctp_chunk_assign_ssn(struct sctp_chunk *); 259void sctp_chunk_assign_ssn(struct sctp_chunk *);
261 260
262sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
263 __u16 error,
264 const struct sctp_association *asoc,
265 struct sctp_transport *transport);
266
267/* Prototypes for statetable processing. */ 261/* Prototypes for statetable processing. */
268 262
269int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype, 263int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index f730935b824a..ec9e20c27179 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -505,25 +505,6 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
505#else 505#else
506# define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG) 506# define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG)
507#endif 507#endif
508
509#define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation
510 * max_cwnd = snd_cwnd * beta
511 */
512#define BICTCP_MAX_INCREMENT 32 /*
513 * Limit on the amount of
514 * increment allowed during
515 * binary search.
516 */
517#define BICTCP_FUNC_OF_MIN_INCR 11 /*
518 * log(B/Smin)/log(B/(B-1))+1,
519 * Smin:min increment
520 * B:log factor
521 */
522#define BICTCP_B 4 /*
523 * In binary search,
524 * go to point (max+min)/N
525 */
526
527/* 508/*
528 * TCP option 509 * TCP option
529 */ 510 */
@@ -596,16 +577,7 @@ extern int sysctl_tcp_adv_win_scale;
596extern int sysctl_tcp_tw_reuse; 577extern int sysctl_tcp_tw_reuse;
597extern int sysctl_tcp_frto; 578extern int sysctl_tcp_frto;
598extern int sysctl_tcp_low_latency; 579extern int sysctl_tcp_low_latency;
599extern int sysctl_tcp_westwood;
600extern int sysctl_tcp_vegas_cong_avoid;
601extern int sysctl_tcp_vegas_alpha;
602extern int sysctl_tcp_vegas_beta;
603extern int sysctl_tcp_vegas_gamma;
604extern int sysctl_tcp_nometrics_save; 580extern int sysctl_tcp_nometrics_save;
605extern int sysctl_tcp_bic;
606extern int sysctl_tcp_bic_fast_convergence;
607extern int sysctl_tcp_bic_low_window;
608extern int sysctl_tcp_bic_beta;
609extern int sysctl_tcp_moderate_rcvbuf; 581extern int sysctl_tcp_moderate_rcvbuf;
610extern int sysctl_tcp_tso_win_divisor; 582extern int sysctl_tcp_tso_win_divisor;
611 583
@@ -1136,6 +1108,82 @@ static inline void tcp_packets_out_dec(struct tcp_sock *tp,
1136 tp->packets_out -= tcp_skb_pcount(skb); 1108 tp->packets_out -= tcp_skb_pcount(skb);
1137} 1109}
1138 1110
1111/* Events passed to congestion control interface */
1112enum tcp_ca_event {
1113 CA_EVENT_TX_START, /* first transmit when no packets in flight */
1114 CA_EVENT_CWND_RESTART, /* congestion window restart */
1115 CA_EVENT_COMPLETE_CWR, /* end of congestion recovery */
1116 CA_EVENT_FRTO, /* fast recovery timeout */
1117 CA_EVENT_LOSS, /* loss timeout */
1118 CA_EVENT_FAST_ACK, /* in sequence ack */
1119 CA_EVENT_SLOW_ACK, /* other ack */
1120};
1121
1122/*
1123 * Interface for adding new TCP congestion control handlers
1124 */
1125#define TCP_CA_NAME_MAX 16
1126struct tcp_congestion_ops {
1127 struct list_head list;
1128
1129 /* initialize private data (optional) */
1130 void (*init)(struct tcp_sock *tp);
1131 /* cleanup private data (optional) */
1132 void (*release)(struct tcp_sock *tp);
1133
1134 /* return slow start threshold (required) */
1135 u32 (*ssthresh)(struct tcp_sock *tp);
1136 /* lower bound for congestion window (optional) */
1137 u32 (*min_cwnd)(struct tcp_sock *tp);
1138 /* do new cwnd calculation (required) */
1139 void (*cong_avoid)(struct tcp_sock *tp, u32 ack,
1140 u32 rtt, u32 in_flight, int good_ack);
1141 /* round trip time sample per acked packet (optional) */
1142 void (*rtt_sample)(struct tcp_sock *tp, u32 usrtt);
1143 /* call before changing ca_state (optional) */
1144 void (*set_state)(struct tcp_sock *tp, u8 new_state);
1145 /* call when cwnd event occurs (optional) */
1146 void (*cwnd_event)(struct tcp_sock *tp, enum tcp_ca_event ev);
1147 /* new value of cwnd after loss (optional) */
1148 u32 (*undo_cwnd)(struct tcp_sock *tp);
1149 /* hook for packet ack accounting (optional) */
1150 void (*pkts_acked)(struct tcp_sock *tp, u32 num_acked);
1151 /* get info for tcp_diag (optional) */
1152 void (*get_info)(struct tcp_sock *tp, u32 ext, struct sk_buff *skb);
1153
1154 char name[TCP_CA_NAME_MAX];
1155 struct module *owner;
1156};
1157
1158extern int tcp_register_congestion_control(struct tcp_congestion_ops *type);
1159extern void tcp_unregister_congestion_control(struct tcp_congestion_ops *type);
1160
1161extern void tcp_init_congestion_control(struct tcp_sock *tp);
1162extern void tcp_cleanup_congestion_control(struct tcp_sock *tp);
1163extern int tcp_set_default_congestion_control(const char *name);
1164extern void tcp_get_default_congestion_control(char *name);
1165extern int tcp_set_congestion_control(struct tcp_sock *tp, const char *name);
1166
1167extern struct tcp_congestion_ops tcp_init_congestion_ops;
1168extern u32 tcp_reno_ssthresh(struct tcp_sock *tp);
1169extern void tcp_reno_cong_avoid(struct tcp_sock *tp, u32 ack,
1170 u32 rtt, u32 in_flight, int flag);
1171extern u32 tcp_reno_min_cwnd(struct tcp_sock *tp);
1172extern struct tcp_congestion_ops tcp_reno;
1173
1174static inline void tcp_set_ca_state(struct tcp_sock *tp, u8 ca_state)
1175{
1176 if (tp->ca_ops->set_state)
1177 tp->ca_ops->set_state(tp, ca_state);
1178 tp->ca_state = ca_state;
1179}
1180
1181static inline void tcp_ca_event(struct tcp_sock *tp, enum tcp_ca_event event)
1182{
1183 if (tp->ca_ops->cwnd_event)
1184 tp->ca_ops->cwnd_event(tp, event);
1185}
1186
1139/* This determines how many packets are "in the network" to the best 1187/* This determines how many packets are "in the network" to the best
1140 * of our knowledge. In many cases it is conservative, but where 1188 * of our knowledge. In many cases it is conservative, but where
1141 * detailed information is available from the receiver (via SACK 1189 * detailed information is available from the receiver (via SACK
@@ -1155,91 +1203,6 @@ static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
1155 return (tp->packets_out - tp->left_out + tp->retrans_out); 1203 return (tp->packets_out - tp->left_out + tp->retrans_out);
1156} 1204}
1157 1205
1158/*
1159 * Which congestion algorithim is in use on the connection.
1160 */
1161#define tcp_is_vegas(__tp) ((__tp)->adv_cong == TCP_VEGAS)
1162#define tcp_is_westwood(__tp) ((__tp)->adv_cong == TCP_WESTWOOD)
1163#define tcp_is_bic(__tp) ((__tp)->adv_cong == TCP_BIC)
1164
1165/* Recalculate snd_ssthresh, we want to set it to:
1166 *
1167 * Reno:
1168 * one half the current congestion window, but no
1169 * less than two segments
1170 *
1171 * BIC:
1172 * behave like Reno until low_window is reached,
1173 * then increase congestion window slowly
1174 */
1175static inline __u32 tcp_recalc_ssthresh(struct tcp_sock *tp)
1176{
1177 if (tcp_is_bic(tp)) {
1178 if (sysctl_tcp_bic_fast_convergence &&
1179 tp->snd_cwnd < tp->bictcp.last_max_cwnd)
1180 tp->bictcp.last_max_cwnd = (tp->snd_cwnd *
1181 (BICTCP_BETA_SCALE
1182 + sysctl_tcp_bic_beta))
1183 / (2 * BICTCP_BETA_SCALE);
1184 else
1185 tp->bictcp.last_max_cwnd = tp->snd_cwnd;
1186
1187 if (tp->snd_cwnd > sysctl_tcp_bic_low_window)
1188 return max((tp->snd_cwnd * sysctl_tcp_bic_beta)
1189 / BICTCP_BETA_SCALE, 2U);
1190 }
1191
1192 return max(tp->snd_cwnd >> 1U, 2U);
1193}
1194
1195/* Stop taking Vegas samples for now. */
1196#define tcp_vegas_disable(__tp) ((__tp)->vegas.doing_vegas_now = 0)
1197
1198static inline void tcp_vegas_enable(struct tcp_sock *tp)
1199{
1200 /* There are several situations when we must "re-start" Vegas:
1201 *
1202 * o when a connection is established
1203 * o after an RTO
1204 * o after fast recovery
1205 * o when we send a packet and there is no outstanding
1206 * unacknowledged data (restarting an idle connection)
1207 *
1208 * In these circumstances we cannot do a Vegas calculation at the
1209 * end of the first RTT, because any calculation we do is using
1210 * stale info -- both the saved cwnd and congestion feedback are
1211 * stale.
1212 *
1213 * Instead we must wait until the completion of an RTT during
1214 * which we actually receive ACKs.
1215 */
1216
1217 /* Begin taking Vegas samples next time we send something. */
1218 tp->vegas.doing_vegas_now = 1;
1219
1220 /* Set the beginning of the next send window. */
1221 tp->vegas.beg_snd_nxt = tp->snd_nxt;
1222
1223 tp->vegas.cntRTT = 0;
1224 tp->vegas.minRTT = 0x7fffffff;
1225}
1226
1227/* Should we be taking Vegas samples right now? */
1228#define tcp_vegas_enabled(__tp) ((__tp)->vegas.doing_vegas_now)
1229
1230extern void tcp_ca_init(struct tcp_sock *tp);
1231
1232static inline void tcp_set_ca_state(struct tcp_sock *tp, u8 ca_state)
1233{
1234 if (tcp_is_vegas(tp)) {
1235 if (ca_state == TCP_CA_Open)
1236 tcp_vegas_enable(tp);
1237 else
1238 tcp_vegas_disable(tp);
1239 }
1240 tp->ca_state = ca_state;
1241}
1242
1243/* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd. 1206/* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
1244 * The exception is rate halving phase, when cwnd is decreasing towards 1207 * The exception is rate halving phase, when cwnd is decreasing towards
1245 * ssthresh. 1208 * ssthresh.
@@ -1288,7 +1251,7 @@ static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
1288static inline void __tcp_enter_cwr(struct tcp_sock *tp) 1251static inline void __tcp_enter_cwr(struct tcp_sock *tp)
1289{ 1252{
1290 tp->undo_marker = 0; 1253 tp->undo_marker = 0;
1291 tp->snd_ssthresh = tcp_recalc_ssthresh(tp); 1254 tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
1292 tp->snd_cwnd = min(tp->snd_cwnd, 1255 tp->snd_cwnd = min(tp->snd_cwnd,
1293 tcp_packets_in_flight(tp) + 1U); 1256 tcp_packets_in_flight(tp) + 1U);
1294 tp->snd_cwnd_cnt = 0; 1257 tp->snd_cwnd_cnt = 0;
@@ -1876,52 +1839,4 @@ struct tcp_iter_state {
1876extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo); 1839extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo);
1877extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo); 1840extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);
1878 1841
1879/* TCP Westwood functions and constants */
1880
1881#define TCP_WESTWOOD_INIT_RTT (20*HZ) /* maybe too conservative?! */
1882#define TCP_WESTWOOD_RTT_MIN (HZ/20) /* 50ms */
1883
1884static inline void tcp_westwood_update_rtt(struct tcp_sock *tp, __u32 rtt_seq)
1885{
1886 if (tcp_is_westwood(tp))
1887 tp->westwood.rtt = rtt_seq;
1888}
1889
1890static inline __u32 __tcp_westwood_bw_rttmin(const struct tcp_sock *tp)
1891{
1892 return max((tp->westwood.bw_est) * (tp->westwood.rtt_min) /
1893 (__u32) (tp->mss_cache_std),
1894 2U);
1895}
1896
1897static inline __u32 tcp_westwood_bw_rttmin(const struct tcp_sock *tp)
1898{
1899 return tcp_is_westwood(tp) ? __tcp_westwood_bw_rttmin(tp) : 0;
1900}
1901
1902static inline int tcp_westwood_ssthresh(struct tcp_sock *tp)
1903{
1904 __u32 ssthresh = 0;
1905
1906 if (tcp_is_westwood(tp)) {
1907 ssthresh = __tcp_westwood_bw_rttmin(tp);
1908 if (ssthresh)
1909 tp->snd_ssthresh = ssthresh;
1910 }
1911
1912 return (ssthresh != 0);
1913}
1914
1915static inline int tcp_westwood_cwnd(struct tcp_sock *tp)
1916{
1917 __u32 cwnd = 0;
1918
1919 if (tcp_is_westwood(tp)) {
1920 cwnd = __tcp_westwood_bw_rttmin(tp);
1921 if (cwnd)
1922 tp->snd_cwnd = cwnd;
1923 }
1924
1925 return (cwnd != 0);
1926}
1927#endif /* _TCP_H */ 1842#endif /* _TCP_H */
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 6d3413a56708..67b867f31fe4 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -77,6 +77,11 @@ extern socket_state_t dead_socket;
77/* Use this just for bridge windows */ 77/* Use this just for bridge windows */
78#define MAP_IOSPACE 0x20 78#define MAP_IOSPACE 0x20
79 79
80/* power hook operations */
81#define HOOK_POWER_PRE 0x01
82#define HOOK_POWER_POST 0x02
83
84
80typedef struct pccard_io_map { 85typedef struct pccard_io_map {
81 u_char map; 86 u_char map;
82 u_char flags; 87 u_char flags;
@@ -222,6 +227,9 @@ struct pcmcia_socket {
222 /* Zoom video behaviour is so chip specific its not worth adding 227 /* Zoom video behaviour is so chip specific its not worth adding
223 this to _ops */ 228 this to _ops */
224 void (*zoom_video)(struct pcmcia_socket *, int); 229 void (*zoom_video)(struct pcmcia_socket *, int);
230
231 /* so is power hook */
232 int (*power_hook)(struct pcmcia_socket *sock, int operation);
225 233
226 /* state thread */ 234 /* state thread */
227 struct semaphore skt_sem; /* protects socket h/w state */ 235 struct semaphore skt_sem; /* protects socket h/w state */
diff --git a/include/scsi/sg_request.h b/include/scsi/sg_request.h
new file mode 100644
index 000000000000..57ff525bdd3b
--- /dev/null
+++ b/include/scsi/sg_request.h
@@ -0,0 +1,26 @@
1typedef struct scsi_request Scsi_Request;
2
3static Scsi_Request *dummy_cmdp; /* only used for sizeof */
4
5typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
6 unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
7 unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */
8 unsigned bufflen; /* Size of (aggregate) data buffer */
9 unsigned b_malloc_len; /* actual len malloc'ed in buffer */
10 void *buffer; /* Data buffer or scatter list (k_use_sg>0) */
11 char dio_in_use; /* 0->indirect IO (or mmap), 1->dio */
12 unsigned char cmd_opcode; /* first byte of command */
13} Sg_scatter_hold;
14
15typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */
16 Scsi_Request *my_cmdp; /* != 0 when request with lower levels */
17 struct sg_request *nextrp; /* NULL -> tail request (slist) */
18 struct sg_fd *parentfp; /* NULL -> not in use */
19 Sg_scatter_hold data; /* hold buffer, perhaps scatter list */
20 sg_io_hdr_t header; /* scsi command+info, see <scsi/sg.h> */
21 unsigned char sense_b[sizeof (dummy_cmdp->sr_sense_buffer)];
22 char res_used; /* 1 -> using reserve buffer, 0 -> not ... */
23 char orphan; /* 1 -> drop on sight, 0 -> normal */
24 char sg_io_owned; /* 1 -> packet belongs to SG_IO */
25 volatile char done; /* 0->before bh, 1->before read, 2->read */
26} Sg_request;
diff --git a/include/sound/core.h b/include/sound/core.h
index 9117c23e3a01..f8c4ef0aa352 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -292,6 +292,7 @@ void *snd_hidden_kcalloc(size_t n, size_t size, int flags);
292void snd_hidden_kfree(const void *obj); 292void snd_hidden_kfree(const void *obj);
293void *snd_hidden_vmalloc(unsigned long size); 293void *snd_hidden_vmalloc(unsigned long size);
294void snd_hidden_vfree(void *obj); 294void snd_hidden_vfree(void *obj);
295char *snd_hidden_kstrdup(const char *s, int flags);
295#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags) 296#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
296#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags) 297#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
297#define kfree(obj) snd_hidden_kfree(obj) 298#define kfree(obj) snd_hidden_kfree(obj)
@@ -301,6 +302,7 @@ void snd_hidden_vfree(void *obj);
301#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size) 302#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
302#define kfree_nocheck(obj) snd_wrapper_kfree(obj) 303#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
303#define vfree_nocheck(obj) snd_wrapper_vfree(obj) 304#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
305#define kstrdup(s, flags) snd_hidden_kstrdup(s, flags)
304#else 306#else
305#define snd_memory_init() /*NOP*/ 307#define snd_memory_init() /*NOP*/
306#define snd_memory_done() /*NOP*/ 308#define snd_memory_done() /*NOP*/
@@ -311,7 +313,6 @@ void snd_hidden_vfree(void *obj);
311#define kfree_nocheck(obj) kfree(obj) 313#define kfree_nocheck(obj) kfree(obj)
312#define vfree_nocheck(obj) vfree(obj) 314#define vfree_nocheck(obj) vfree(obj)
313#endif 315#endif
314char *snd_kmalloc_strdup(const char *string, int flags);
315int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count); 316int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
316int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count); 317int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
317 318
diff --git a/init/calibrate.c b/init/calibrate.c
index c698e04a3dbe..d206c7548fe6 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -8,6 +8,8 @@
8#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/init.h> 9#include <linux/init.h>
10 10
11#include <asm/timex.h>
12
11static unsigned long preset_lpj; 13static unsigned long preset_lpj;
12static int __init lpj_setup(char *str) 14static int __init lpj_setup(char *str)
13{ 15{
@@ -17,6 +19,92 @@ static int __init lpj_setup(char *str)
17 19
18__setup("lpj=", lpj_setup); 20__setup("lpj=", lpj_setup);
19 21
22#ifdef ARCH_HAS_READ_CURRENT_TIMER
23
24/* This routine uses the read_current_timer() routine and gets the
25 * loops per jiffy directly, instead of guessing it using delay().
26 * Also, this code tries to handle non-maskable asynchronous events
27 * (like SMIs)
28 */
29#define DELAY_CALIBRATION_TICKS ((HZ < 100) ? 1 : (HZ/100))
30#define MAX_DIRECT_CALIBRATION_RETRIES 5
31
32static unsigned long __devinit calibrate_delay_direct(void)
33{
34 unsigned long pre_start, start, post_start;
35 unsigned long pre_end, end, post_end;
36 unsigned long start_jiffies;
37 unsigned long tsc_rate_min, tsc_rate_max;
38 unsigned long good_tsc_sum = 0;
39 unsigned long good_tsc_count = 0;
40 int i;
41
42 if (read_current_timer(&pre_start) < 0 )
43 return 0;
44
45 /*
46 * A simple loop like
47 * while ( jiffies < start_jiffies+1)
48 * start = read_current_timer();
49 * will not do. As we don't really know whether jiffy switch
50 * happened first or timer_value was read first. And some asynchronous
51 * event can happen between these two events introducing errors in lpj.
52 *
53 * So, we do
54 * 1. pre_start <- When we are sure that jiffy switch hasn't happened
55 * 2. check jiffy switch
56 * 3. start <- timer value before or after jiffy switch
57 * 4. post_start <- When we are sure that jiffy switch has happened
58 *
59 * Note, we don't know anything about order of 2 and 3.
60 * Now, by looking at post_start and pre_start difference, we can
61 * check whether any asynchronous event happened or not
62 */
63
64 for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) {
65 pre_start = 0;
66 read_current_timer(&start);
67 start_jiffies = jiffies;
68 while (jiffies <= (start_jiffies + 1)) {
69 pre_start = start;
70 read_current_timer(&start);
71 }
72 read_current_timer(&post_start);
73
74 pre_end = 0;
75 end = post_start;
76 while (jiffies <=
77 (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) {
78 pre_end = end;
79 read_current_timer(&end);
80 }
81 read_current_timer(&post_end);
82
83 tsc_rate_max = (post_end - pre_start) / DELAY_CALIBRATION_TICKS;
84 tsc_rate_min = (pre_end - post_start) / DELAY_CALIBRATION_TICKS;
85
86 /*
87 * If the upper limit and lower limit of the tsc_rate is
88 * >= 12.5% apart, redo calibration.
89 */
90 if (pre_start != 0 && pre_end != 0 &&
91 (tsc_rate_max - tsc_rate_min) < (tsc_rate_max >> 3)) {
92 good_tsc_count++;
93 good_tsc_sum += tsc_rate_max;
94 }
95 }
96
97 if (good_tsc_count)
98 return (good_tsc_sum/good_tsc_count);
99
100 printk(KERN_WARNING "calibrate_delay_direct() failed to get a good "
101 "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n");
102 return 0;
103}
104#else
105static unsigned long __devinit calibrate_delay_direct(void) {return 0;}
106#endif
107
20/* 108/*
21 * This is the number of bits of precision for the loops_per_jiffy. Each 109 * This is the number of bits of precision for the loops_per_jiffy. Each
22 * bit takes on average 1.5/HZ seconds. This (like the original) is a little 110 * bit takes on average 1.5/HZ seconds. This (like the original) is a little
@@ -35,6 +123,12 @@ void __devinit calibrate_delay(void)
35 "%lu.%02lu BogoMIPS preset\n", 123 "%lu.%02lu BogoMIPS preset\n",
36 loops_per_jiffy/(500000/HZ), 124 loops_per_jiffy/(500000/HZ),
37 (loops_per_jiffy/(5000/HZ)) % 100); 125 (loops_per_jiffy/(5000/HZ)) % 100);
126 } else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
127 printk("Calibrating delay using timer specific routine.. ");
128 printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
129 loops_per_jiffy/(500000/HZ),
130 (loops_per_jiffy/(5000/HZ)) % 100,
131 loops_per_jiffy);
38 } else { 132 } else {
39 loops_per_jiffy = (1<<12); 133 loops_per_jiffy = (1<<12);
40 134
diff --git a/ipc/sem.c b/ipc/sem.c
index 5ad7ac0ed60d..7e8a25c82ef3 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1054,7 +1054,7 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
1054 struct sembuf fast_sops[SEMOPM_FAST]; 1054 struct sembuf fast_sops[SEMOPM_FAST];
1055 struct sembuf* sops = fast_sops, *sop; 1055 struct sembuf* sops = fast_sops, *sop;
1056 struct sem_undo *un; 1056 struct sem_undo *un;
1057 int undos = 0, decrease = 0, alter = 0, max; 1057 int undos = 0, alter = 0, max;
1058 struct sem_queue queue; 1058 struct sem_queue queue;
1059 unsigned long jiffies_left = 0; 1059 unsigned long jiffies_left = 0;
1060 1060
@@ -1089,13 +1089,10 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops,
1089 if (sop->sem_num >= max) 1089 if (sop->sem_num >= max)
1090 max = sop->sem_num; 1090 max = sop->sem_num;
1091 if (sop->sem_flg & SEM_UNDO) 1091 if (sop->sem_flg & SEM_UNDO)
1092 undos++; 1092 undos = 1;
1093 if (sop->sem_op < 0) 1093 if (sop->sem_op != 0)
1094 decrease = 1;
1095 if (sop->sem_op > 0)
1096 alter = 1; 1094 alter = 1;
1097 } 1095 }
1098 alter |= decrease;
1099 1096
1100retry_undos: 1097retry_undos:
1101 if (undos) { 1098 if (undos) {
diff --git a/kernel/Kconfig.hz b/kernel/Kconfig.hz
new file mode 100644
index 000000000000..248e1c396f8b
--- /dev/null
+++ b/kernel/Kconfig.hz
@@ -0,0 +1,46 @@
1#
2# Timer Interrupt Frequency Configuration
3#
4
5choice
6 prompt "Timer frequency"
7 default HZ_250
8 help
9 Allows the configuration of the timer frequency. It is customary
10 to have the timer interrupt run at 1000 HZ but 100 HZ may be more
11 beneficial for servers and NUMA systems that do not need to have
12 a fast response for user interaction and that may experience bus
13 contention and cacheline bounces as a result of timer interrupts.
14 Note that the timer interrupt occurs on each processor in an SMP
15 environment leading to NR_CPUS * HZ number of timer interrupts
16 per second.
17
18
19 config HZ_100
20 bool "100 HZ"
21 help
22 100 HZ is a typical choice for servers, SMP and NUMA systems
23 with lots of processors that may show reduced performance if
24 too many timer interrupts are occurring.
25
26 config HZ_250
27 bool "250 HZ"
28 help
29 250 HZ is a good compromise choice allowing server performance
30 while also showing good interactive responsiveness even
31 on SMP and NUMA systems.
32
33 config HZ_1000
34 bool "1000 HZ"
35 help
36 1000 HZ is the preferred choice for desktop systems and other
37 systems requiring fast interactive responses to events.
38
39endchoice
40
41config HZ
42 int
43 default 100 if HZ_100
44 default 250 if HZ_250
45 default 1000 if HZ_1000
46
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 00e8f2575512..79dd929f4084 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -228,13 +228,7 @@ static struct dentry_operations cpuset_dops = {
228 228
229static struct dentry *cpuset_get_dentry(struct dentry *parent, const char *name) 229static struct dentry *cpuset_get_dentry(struct dentry *parent, const char *name)
230{ 230{
231 struct qstr qstr; 231 struct dentry *d = lookup_one_len(name, parent, strlen(name));
232 struct dentry *d;
233
234 qstr.name = name;
235 qstr.len = strlen(name);
236 qstr.hash = full_name_hash(name, qstr.len);
237 d = lookup_hash(&qstr, parent);
238 if (!IS_ERR(d)) 232 if (!IS_ERR(d))
239 d->d_op = &cpuset_dops; 233 d->d_op = &cpuset_dops;
240 return d; 234 return d;
diff --git a/kernel/exit.c b/kernel/exit.c
index 2ef2ad540201..3ebcd60a19c6 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -72,6 +72,11 @@ repeat:
72 BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); 72 BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
73 __exit_signal(p); 73 __exit_signal(p);
74 __exit_sighand(p); 74 __exit_sighand(p);
75 /*
76 * Note that the fastpath in sys_times depends on __exit_signal having
77 * updated the counters before a task is removed from the tasklist of
78 * the process by __unhash_process.
79 */
75 __unhash_process(p); 80 __unhash_process(p);
76 81
77 /* 82 /*
@@ -793,6 +798,17 @@ fastcall NORET_TYPE void do_exit(long code)
793 ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP); 798 ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
794 } 799 }
795 800
801 /*
802 * We're taking recursive faults here in do_exit. Safest is to just
803 * leave this task alone and wait for reboot.
804 */
805 if (unlikely(tsk->flags & PF_EXITING)) {
806 printk(KERN_ALERT
807 "Fixing recursive fault but reboot is needed!\n");
808 set_current_state(TASK_UNINTERRUPTIBLE);
809 schedule();
810 }
811
796 tsk->flags |= PF_EXITING; 812 tsk->flags |= PF_EXITING;
797 813
798 /* 814 /*
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index f6297c306905..ba039e827d58 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -45,7 +45,7 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
45 } 45 }
46} 46}
47 47
48void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) 48static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
49{ 49{
50 static int count = 100; 50 static int count = 100;
51 51
diff --git a/kernel/kmod.c b/kernel/kmod.c
index eed53d4f5230..44166e3bb8af 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -120,6 +120,7 @@ struct subprocess_info {
120 char *path; 120 char *path;
121 char **argv; 121 char **argv;
122 char **envp; 122 char **envp;
123 struct key *ring;
123 int wait; 124 int wait;
124 int retval; 125 int retval;
125}; 126};
@@ -130,16 +131,21 @@ struct subprocess_info {
130static int ____call_usermodehelper(void *data) 131static int ____call_usermodehelper(void *data)
131{ 132{
132 struct subprocess_info *sub_info = data; 133 struct subprocess_info *sub_info = data;
134 struct key *old_session;
133 int retval; 135 int retval;
134 136
135 /* Unblock all signals. */ 137 /* Unblock all signals and set the session keyring. */
138 key_get(sub_info->ring);
136 flush_signals(current); 139 flush_signals(current);
137 spin_lock_irq(&current->sighand->siglock); 140 spin_lock_irq(&current->sighand->siglock);
141 old_session = __install_session_keyring(current, sub_info->ring);
138 flush_signal_handlers(current, 1); 142 flush_signal_handlers(current, 1);
139 sigemptyset(&current->blocked); 143 sigemptyset(&current->blocked);
140 recalc_sigpending(); 144 recalc_sigpending();
141 spin_unlock_irq(&current->sighand->siglock); 145 spin_unlock_irq(&current->sighand->siglock);
142 146
147 key_put(old_session);
148
143 /* We can run anywhere, unlike our parent keventd(). */ 149 /* We can run anywhere, unlike our parent keventd(). */
144 set_cpus_allowed(current, CPU_MASK_ALL); 150 set_cpus_allowed(current, CPU_MASK_ALL);
145 151
@@ -211,10 +217,11 @@ static void __call_usermodehelper(void *data)
211} 217}
212 218
213/** 219/**
214 * call_usermodehelper - start a usermode application 220 * call_usermodehelper_keys - start a usermode application
215 * @path: pathname for the application 221 * @path: pathname for the application
216 * @argv: null-terminated argument list 222 * @argv: null-terminated argument list
217 * @envp: null-terminated environment list 223 * @envp: null-terminated environment list
224 * @session_keyring: session keyring for process (NULL for an empty keyring)
218 * @wait: wait for the application to finish and return status. 225 * @wait: wait for the application to finish and return status.
219 * 226 *
220 * Runs a user-space application. The application is started 227 * Runs a user-space application. The application is started
@@ -224,7 +231,8 @@ static void __call_usermodehelper(void *data)
224 * Must be called from process context. Returns a negative error code 231 * Must be called from process context. Returns a negative error code
225 * if program was not execed successfully, or 0. 232 * if program was not execed successfully, or 0.
226 */ 233 */
227int call_usermodehelper(char *path, char **argv, char **envp, int wait) 234int call_usermodehelper_keys(char *path, char **argv, char **envp,
235 struct key *session_keyring, int wait)
228{ 236{
229 DECLARE_COMPLETION(done); 237 DECLARE_COMPLETION(done);
230 struct subprocess_info sub_info = { 238 struct subprocess_info sub_info = {
@@ -232,6 +240,7 @@ int call_usermodehelper(char *path, char **argv, char **envp, int wait)
232 .path = path, 240 .path = path,
233 .argv = argv, 241 .argv = argv,
234 .envp = envp, 242 .envp = envp,
243 .ring = session_keyring,
235 .wait = wait, 244 .wait = wait,
236 .retval = 0, 245 .retval = 0,
237 }; 246 };
@@ -247,7 +256,7 @@ int call_usermodehelper(char *path, char **argv, char **envp, int wait)
247 wait_for_completion(&done); 256 wait_for_completion(&done);
248 return sub_info.retval; 257 return sub_info.retval;
249} 258}
250EXPORT_SYMBOL(call_usermodehelper); 259EXPORT_SYMBOL(call_usermodehelper_keys);
251 260
252void __init usermodehelper_init(void) 261void __init usermodehelper_init(void)
253{ 262{
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 037142b72a49..334f37472c56 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -27,6 +27,9 @@
27 * interface to access function arguments. 27 * interface to access function arguments.
28 * 2004-Sep Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes 28 * 2004-Sep Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes
29 * exceptions notifier to be first on the priority list. 29 * exceptions notifier to be first on the priority list.
30 * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston
31 * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
32 * <prasanna@in.ibm.com> added function-return probes.
30 */ 33 */
31#include <linux/kprobes.h> 34#include <linux/kprobes.h>
32#include <linux/spinlock.h> 35#include <linux/spinlock.h>
@@ -41,6 +44,7 @@
41#define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) 44#define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
42 45
43static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; 46static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
47static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
44 48
45unsigned int kprobe_cpu = NR_CPUS; 49unsigned int kprobe_cpu = NR_CPUS;
46static DEFINE_SPINLOCK(kprobe_lock); 50static DEFINE_SPINLOCK(kprobe_lock);
@@ -78,22 +82,23 @@ struct kprobe *get_kprobe(void *addr)
78 * Aggregate handlers for multiple kprobes support - these handlers 82 * Aggregate handlers for multiple kprobes support - these handlers
79 * take care of invoking the individual kprobe handlers on p->list 83 * take care of invoking the individual kprobe handlers on p->list
80 */ 84 */
81int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs) 85static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
82{ 86{
83 struct kprobe *kp; 87 struct kprobe *kp;
84 88
85 list_for_each_entry(kp, &p->list, list) { 89 list_for_each_entry(kp, &p->list, list) {
86 if (kp->pre_handler) { 90 if (kp->pre_handler) {
87 curr_kprobe = kp; 91 curr_kprobe = kp;
88 kp->pre_handler(kp, regs); 92 if (kp->pre_handler(kp, regs))
89 curr_kprobe = NULL; 93 return 1;
90 } 94 }
95 curr_kprobe = NULL;
91 } 96 }
92 return 0; 97 return 0;
93} 98}
94 99
95void aggr_post_handler(struct kprobe *p, struct pt_regs *regs, 100static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
96 unsigned long flags) 101 unsigned long flags)
97{ 102{
98 struct kprobe *kp; 103 struct kprobe *kp;
99 104
@@ -107,7 +112,8 @@ void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
107 return; 112 return;
108} 113}
109 114
110int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr) 115static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
116 int trapnr)
111{ 117{
112 /* 118 /*
113 * if we faulted "during" the execution of a user specified 119 * if we faulted "during" the execution of a user specified
@@ -120,19 +126,191 @@ int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr)
120 return 0; 126 return 0;
121} 127}
122 128
129static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
130{
131 struct kprobe *kp = curr_kprobe;
132 if (curr_kprobe && kp->break_handler) {
133 if (kp->break_handler(kp, regs)) {
134 curr_kprobe = NULL;
135 return 1;
136 }
137 }
138 curr_kprobe = NULL;
139 return 0;
140}
141
142struct kprobe trampoline_p = {
143 .addr = (kprobe_opcode_t *) &kretprobe_trampoline,
144 .pre_handler = trampoline_probe_handler,
145 .post_handler = trampoline_post_handler
146};
147
148struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp)
149{
150 struct hlist_node *node;
151 struct kretprobe_instance *ri;
152 hlist_for_each_entry(ri, node, &rp->free_instances, uflist)
153 return ri;
154 return NULL;
155}
156
157static struct kretprobe_instance *get_used_rp_inst(struct kretprobe *rp)
158{
159 struct hlist_node *node;
160 struct kretprobe_instance *ri;
161 hlist_for_each_entry(ri, node, &rp->used_instances, uflist)
162 return ri;
163 return NULL;
164}
165
166struct kretprobe_instance *get_rp_inst(void *sara)
167{
168 struct hlist_head *head;
169 struct hlist_node *node;
170 struct task_struct *tsk;
171 struct kretprobe_instance *ri;
172
173 tsk = arch_get_kprobe_task(sara);
174 head = &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
175 hlist_for_each_entry(ri, node, head, hlist) {
176 if (ri->stack_addr == sara)
177 return ri;
178 }
179 return NULL;
180}
181
182void add_rp_inst(struct kretprobe_instance *ri)
183{
184 struct task_struct *tsk;
185 /*
186 * Remove rp inst off the free list -
187 * Add it back when probed function returns
188 */
189 hlist_del(&ri->uflist);
190 tsk = arch_get_kprobe_task(ri->stack_addr);
191 /* Add rp inst onto table */
192 INIT_HLIST_NODE(&ri->hlist);
193 hlist_add_head(&ri->hlist,
194 &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)]);
195
196 /* Also add this rp inst to the used list. */
197 INIT_HLIST_NODE(&ri->uflist);
198 hlist_add_head(&ri->uflist, &ri->rp->used_instances);
199}
200
201void recycle_rp_inst(struct kretprobe_instance *ri)
202{
203 /* remove rp inst off the rprobe_inst_table */
204 hlist_del(&ri->hlist);
205 if (ri->rp) {
206 /* remove rp inst off the used list */
207 hlist_del(&ri->uflist);
208 /* put rp inst back onto the free list */
209 INIT_HLIST_NODE(&ri->uflist);
210 hlist_add_head(&ri->uflist, &ri->rp->free_instances);
211 } else
212 /* Unregistering */
213 kfree(ri);
214}
215
216struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk)
217{
218 return &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
219}
220
221struct kretprobe_instance *get_rp_inst_tsk(struct task_struct *tk)
222{
223 struct task_struct *tsk;
224 struct hlist_head *head;
225 struct hlist_node *node;
226 struct kretprobe_instance *ri;
227
228 head = &kretprobe_inst_table[hash_ptr(tk, KPROBE_HASH_BITS)];
229
230 hlist_for_each_entry(ri, node, head, hlist) {
231 tsk = arch_get_kprobe_task(ri->stack_addr);
232 if (tsk == tk)
233 return ri;
234 }
235 return NULL;
236}
237
238/*
239 * This function is called from do_exit or do_execv when task tk's stack is
240 * about to be recycled. Recycle any function-return probe instances
241 * associated with this task. These represent probed functions that have
242 * been called but may never return.
243 */
244void kprobe_flush_task(struct task_struct *tk)
245{
246 unsigned long flags = 0;
247 spin_lock_irqsave(&kprobe_lock, flags);
248 arch_kprobe_flush_task(tk);
249 spin_unlock_irqrestore(&kprobe_lock, flags);
250}
251
252/*
253 * This kprobe pre_handler is registered with every kretprobe. When probe
254 * hits it will set up the return probe.
255 */
256static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
257{
258 struct kretprobe *rp = container_of(p, struct kretprobe, kp);
259
260 /*TODO: consider to only swap the RA after the last pre_handler fired */
261 arch_prepare_kretprobe(rp, regs);
262 return 0;
263}
264
265static inline void free_rp_inst(struct kretprobe *rp)
266{
267 struct kretprobe_instance *ri;
268 while ((ri = get_free_rp_inst(rp)) != NULL) {
269 hlist_del(&ri->uflist);
270 kfree(ri);
271 }
272}
273
274/*
275 * Keep all fields in the kprobe consistent
276 */
277static inline void copy_kprobe(struct kprobe *old_p, struct kprobe *p)
278{
279 memcpy(&p->opcode, &old_p->opcode, sizeof(kprobe_opcode_t));
280 memcpy(&p->ainsn, &old_p->ainsn, sizeof(struct arch_specific_insn));
281}
282
283/*
284* Add the new probe to old_p->list. Fail if this is the
285* second jprobe at the address - two jprobes can't coexist
286*/
287static int add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
288{
289 struct kprobe *kp;
290
291 if (p->break_handler) {
292 list_for_each_entry(kp, &old_p->list, list) {
293 if (kp->break_handler)
294 return -EEXIST;
295 }
296 list_add_tail(&p->list, &old_p->list);
297 } else
298 list_add(&p->list, &old_p->list);
299 return 0;
300}
301
123/* 302/*
124 * Fill in the required fields of the "manager kprobe". Replace the 303 * Fill in the required fields of the "manager kprobe". Replace the
125 * earlier kprobe in the hlist with the manager kprobe 304 * earlier kprobe in the hlist with the manager kprobe
126 */ 305 */
127static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p) 306static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
128{ 307{
308 copy_kprobe(p, ap);
129 ap->addr = p->addr; 309 ap->addr = p->addr;
130 ap->opcode = p->opcode;
131 memcpy(&ap->ainsn, &p->ainsn, sizeof(struct arch_specific_insn));
132
133 ap->pre_handler = aggr_pre_handler; 310 ap->pre_handler = aggr_pre_handler;
134 ap->post_handler = aggr_post_handler; 311 ap->post_handler = aggr_post_handler;
135 ap->fault_handler = aggr_fault_handler; 312 ap->fault_handler = aggr_fault_handler;
313 ap->break_handler = aggr_break_handler;
136 314
137 INIT_LIST_HEAD(&ap->list); 315 INIT_LIST_HEAD(&ap->list);
138 list_add(&p->list, &ap->list); 316 list_add(&p->list, &ap->list);
@@ -153,16 +331,16 @@ static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
153 int ret = 0; 331 int ret = 0;
154 struct kprobe *ap; 332 struct kprobe *ap;
155 333
156 if (old_p->break_handler || p->break_handler) { 334 if (old_p->pre_handler == aggr_pre_handler) {
157 ret = -EEXIST; /* kprobe and jprobe can't (yet) coexist */ 335 copy_kprobe(old_p, p);
158 } else if (old_p->pre_handler == aggr_pre_handler) { 336 ret = add_new_kprobe(old_p, p);
159 list_add(&p->list, &old_p->list);
160 } else { 337 } else {
161 ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC); 338 ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC);
162 if (!ap) 339 if (!ap)
163 return -ENOMEM; 340 return -ENOMEM;
164 add_aggr_kprobe(ap, old_p); 341 add_aggr_kprobe(ap, old_p);
165 list_add(&p->list, &ap->list); 342 copy_kprobe(ap, p);
343 ret = add_new_kprobe(ap, p);
166 } 344 }
167 return ret; 345 return ret;
168} 346}
@@ -170,10 +348,8 @@ static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
170/* kprobe removal house-keeping routines */ 348/* kprobe removal house-keeping routines */
171static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags) 349static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
172{ 350{
173 *p->addr = p->opcode; 351 arch_disarm_kprobe(p);
174 hlist_del(&p->hlist); 352 hlist_del(&p->hlist);
175 flush_icache_range((unsigned long) p->addr,
176 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
177 spin_unlock_irqrestore(&kprobe_lock, flags); 353 spin_unlock_irqrestore(&kprobe_lock, flags);
178 arch_remove_kprobe(p); 354 arch_remove_kprobe(p);
179} 355}
@@ -200,6 +376,7 @@ int register_kprobe(struct kprobe *p)
200 } 376 }
201 spin_lock_irqsave(&kprobe_lock, flags); 377 spin_lock_irqsave(&kprobe_lock, flags);
202 old_p = get_kprobe(p->addr); 378 old_p = get_kprobe(p->addr);
379 p->nmissed = 0;
203 if (old_p) { 380 if (old_p) {
204 ret = register_aggr_kprobe(old_p, p); 381 ret = register_aggr_kprobe(old_p, p);
205 goto out; 382 goto out;
@@ -210,10 +387,8 @@ int register_kprobe(struct kprobe *p)
210 hlist_add_head(&p->hlist, 387 hlist_add_head(&p->hlist,
211 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); 388 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
212 389
213 p->opcode = *p->addr; 390 arch_arm_kprobe(p);
214 *p->addr = BREAKPOINT_INSTRUCTION; 391
215 flush_icache_range((unsigned long) p->addr,
216 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
217out: 392out:
218 spin_unlock_irqrestore(&kprobe_lock, flags); 393 spin_unlock_irqrestore(&kprobe_lock, flags);
219rm_kprobe: 394rm_kprobe:
@@ -257,16 +432,82 @@ void unregister_jprobe(struct jprobe *jp)
257 unregister_kprobe(&jp->kp); 432 unregister_kprobe(&jp->kp);
258} 433}
259 434
435#ifdef ARCH_SUPPORTS_KRETPROBES
436
437int register_kretprobe(struct kretprobe *rp)
438{
439 int ret = 0;
440 struct kretprobe_instance *inst;
441 int i;
442
443 rp->kp.pre_handler = pre_handler_kretprobe;
444
445 /* Pre-allocate memory for max kretprobe instances */
446 if (rp->maxactive <= 0) {
447#ifdef CONFIG_PREEMPT
448 rp->maxactive = max(10, 2 * NR_CPUS);
449#else
450 rp->maxactive = NR_CPUS;
451#endif
452 }
453 INIT_HLIST_HEAD(&rp->used_instances);
454 INIT_HLIST_HEAD(&rp->free_instances);
455 for (i = 0; i < rp->maxactive; i++) {
456 inst = kmalloc(sizeof(struct kretprobe_instance), GFP_KERNEL);
457 if (inst == NULL) {
458 free_rp_inst(rp);
459 return -ENOMEM;
460 }
461 INIT_HLIST_NODE(&inst->uflist);
462 hlist_add_head(&inst->uflist, &rp->free_instances);
463 }
464
465 rp->nmissed = 0;
466 /* Establish function entry probe point */
467 if ((ret = register_kprobe(&rp->kp)) != 0)
468 free_rp_inst(rp);
469 return ret;
470}
471
472#else /* ARCH_SUPPORTS_KRETPROBES */
473
474int register_kretprobe(struct kretprobe *rp)
475{
476 return -ENOSYS;
477}
478
479#endif /* ARCH_SUPPORTS_KRETPROBES */
480
481void unregister_kretprobe(struct kretprobe *rp)
482{
483 unsigned long flags;
484 struct kretprobe_instance *ri;
485
486 unregister_kprobe(&rp->kp);
487 /* No race here */
488 spin_lock_irqsave(&kprobe_lock, flags);
489 free_rp_inst(rp);
490 while ((ri = get_used_rp_inst(rp)) != NULL) {
491 ri->rp = NULL;
492 hlist_del(&ri->uflist);
493 }
494 spin_unlock_irqrestore(&kprobe_lock, flags);
495}
496
260static int __init init_kprobes(void) 497static int __init init_kprobes(void)
261{ 498{
262 int i, err = 0; 499 int i, err = 0;
263 500
264 /* FIXME allocate the probe table, currently defined statically */ 501 /* FIXME allocate the probe table, currently defined statically */
265 /* initialize all list heads */ 502 /* initialize all list heads */
266 for (i = 0; i < KPROBE_TABLE_SIZE; i++) 503 for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
267 INIT_HLIST_HEAD(&kprobe_table[i]); 504 INIT_HLIST_HEAD(&kprobe_table[i]);
505 INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
506 }
268 507
269 err = register_die_notifier(&kprobe_exceptions_nb); 508 err = register_die_notifier(&kprobe_exceptions_nb);
509 /* Register the trampoline probe for return probe */
510 register_kprobe(&trampoline_p);
270 return err; 511 return err;
271} 512}
272 513
@@ -277,3 +518,6 @@ EXPORT_SYMBOL_GPL(unregister_kprobe);
277EXPORT_SYMBOL_GPL(register_jprobe); 518EXPORT_SYMBOL_GPL(register_jprobe);
278EXPORT_SYMBOL_GPL(unregister_jprobe); 519EXPORT_SYMBOL_GPL(unregister_jprobe);
279EXPORT_SYMBOL_GPL(jprobe_return); 520EXPORT_SYMBOL_GPL(jprobe_return);
521EXPORT_SYMBOL_GPL(register_kretprobe);
522EXPORT_SYMBOL_GPL(unregister_kretprobe);
523
diff --git a/kernel/module.c b/kernel/module.c
index a566745dde62..068e271ab3a5 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -35,6 +35,7 @@
35#include <linux/notifier.h> 35#include <linux/notifier.h>
36#include <linux/stop_machine.h> 36#include <linux/stop_machine.h>
37#include <linux/device.h> 37#include <linux/device.h>
38#include <linux/string.h>
38#include <asm/uaccess.h> 39#include <asm/uaccess.h>
39#include <asm/semaphore.h> 40#include <asm/semaphore.h>
40#include <asm/cacheflush.h> 41#include <asm/cacheflush.h>
@@ -370,6 +371,43 @@ static inline void percpu_modcopy(void *pcpudst, const void *src,
370#endif /* CONFIG_SMP */ 371#endif /* CONFIG_SMP */
371 372
372#ifdef CONFIG_MODULE_UNLOAD 373#ifdef CONFIG_MODULE_UNLOAD
374#define MODINFO_ATTR(field) \
375static void setup_modinfo_##field(struct module *mod, const char *s) \
376{ \
377 mod->field = kstrdup(s, GFP_KERNEL); \
378} \
379static ssize_t show_modinfo_##field(struct module_attribute *mattr, \
380 struct module *mod, char *buffer) \
381{ \
382 return sprintf(buffer, "%s\n", mod->field); \
383} \
384static int modinfo_##field##_exists(struct module *mod) \
385{ \
386 return mod->field != NULL; \
387} \
388static void free_modinfo_##field(struct module *mod) \
389{ \
390 kfree(mod->field); \
391 mod->field = NULL; \
392} \
393static struct module_attribute modinfo_##field = { \
394 .attr = { .name = __stringify(field), .mode = 0444, \
395 .owner = THIS_MODULE }, \
396 .show = show_modinfo_##field, \
397 .setup = setup_modinfo_##field, \
398 .test = modinfo_##field##_exists, \
399 .free = free_modinfo_##field, \
400};
401
402MODINFO_ATTR(version);
403MODINFO_ATTR(srcversion);
404
405static struct module_attribute *modinfo_attrs[] = {
406 &modinfo_version,
407 &modinfo_srcversion,
408 NULL,
409};
410
373/* Init the unload section of the module. */ 411/* Init the unload section of the module. */
374static void module_unload_init(struct module *mod) 412static void module_unload_init(struct module *mod)
375{ 413{
@@ -692,7 +730,7 @@ static int obsparm_copy_string(const char *val, struct kernel_param *kp)
692 return 0; 730 return 0;
693} 731}
694 732
695int set_obsolete(const char *val, struct kernel_param *kp) 733static int set_obsolete(const char *val, struct kernel_param *kp)
696{ 734{
697 unsigned int min, max; 735 unsigned int min, max;
698 unsigned int size, maxsize; 736 unsigned int size, maxsize;
@@ -1031,6 +1069,32 @@ static void module_remove_refcnt_attr(struct module *mod)
1031} 1069}
1032#endif 1070#endif
1033 1071
1072#ifdef CONFIG_MODULE_UNLOAD
1073static int module_add_modinfo_attrs(struct module *mod)
1074{
1075 struct module_attribute *attr;
1076 int error = 0;
1077 int i;
1078
1079 for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) {
1080 if (!attr->test ||
1081 (attr->test && attr->test(mod)))
1082 error = sysfs_create_file(&mod->mkobj.kobj,&attr->attr);
1083 }
1084 return error;
1085}
1086
1087static void module_remove_modinfo_attrs(struct module *mod)
1088{
1089 struct module_attribute *attr;
1090 int i;
1091
1092 for (i = 0; (attr = modinfo_attrs[i]); i++) {
1093 sysfs_remove_file(&mod->mkobj.kobj,&attr->attr);
1094 attr->free(mod);
1095 }
1096}
1097#endif
1034 1098
1035static int mod_sysfs_setup(struct module *mod, 1099static int mod_sysfs_setup(struct module *mod,
1036 struct kernel_param *kparam, 1100 struct kernel_param *kparam,
@@ -1056,6 +1120,12 @@ static int mod_sysfs_setup(struct module *mod,
1056 if (err) 1120 if (err)
1057 goto out_unreg; 1121 goto out_unreg;
1058 1122
1123#ifdef CONFIG_MODULE_UNLOAD
1124 err = module_add_modinfo_attrs(mod);
1125 if (err)
1126 goto out_unreg;
1127#endif
1128
1059 return 0; 1129 return 0;
1060 1130
1061out_unreg: 1131out_unreg:
@@ -1066,6 +1136,9 @@ out:
1066 1136
1067static void mod_kobject_remove(struct module *mod) 1137static void mod_kobject_remove(struct module *mod)
1068{ 1138{
1139#ifdef CONFIG_MODULE_UNLOAD
1140 module_remove_modinfo_attrs(mod);
1141#endif
1069 module_remove_refcnt_attr(mod); 1142 module_remove_refcnt_attr(mod);
1070 module_param_sysfs_remove(mod); 1143 module_param_sysfs_remove(mod);
1071 1144
@@ -1311,6 +1384,23 @@ static char *get_modinfo(Elf_Shdr *sechdrs,
1311 return NULL; 1384 return NULL;
1312} 1385}
1313 1386
1387#ifdef CONFIG_MODULE_UNLOAD
1388static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
1389 unsigned int infoindex)
1390{
1391 struct module_attribute *attr;
1392 int i;
1393
1394 for (i = 0; (attr = modinfo_attrs[i]); i++) {
1395 if (attr->setup)
1396 attr->setup(mod,
1397 get_modinfo(sechdrs,
1398 infoindex,
1399 attr->attr.name));
1400 }
1401}
1402#endif
1403
1314#ifdef CONFIG_KALLSYMS 1404#ifdef CONFIG_KALLSYMS
1315int is_exported(const char *name, const struct module *mod) 1405int is_exported(const char *name, const struct module *mod)
1316{ 1406{
@@ -1615,6 +1705,11 @@ static struct module *load_module(void __user *umod,
1615 /* Set up license info based on the info section */ 1705 /* Set up license info based on the info section */
1616 set_license(mod, get_modinfo(sechdrs, infoindex, "license")); 1706 set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
1617 1707
1708#ifdef CONFIG_MODULE_UNLOAD
1709 /* Set up MODINFO_ATTR fields */
1710 setup_modinfo(mod, sechdrs, infoindex);
1711#endif
1712
1618 /* Fix up syms, so that st_value is a pointer to location. */ 1713 /* Fix up syms, so that st_value is a pointer to location. */
1619 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex, 1714 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
1620 mod); 1715 mod);
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index cabb63fc9e16..5b7b4736d82b 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -89,23 +89,6 @@ static struct idr posix_timers_id;
89static DEFINE_SPINLOCK(idr_lock); 89static DEFINE_SPINLOCK(idr_lock);
90 90
91/* 91/*
92 * Just because the timer is not in the timer list does NOT mean it is
93 * inactive. It could be in the "fire" routine getting a new expire time.
94 */
95#define TIMER_INACTIVE 1
96
97#ifdef CONFIG_SMP
98# define timer_active(tmr) \
99 ((tmr)->it.real.timer.entry.prev != (void *)TIMER_INACTIVE)
100# define set_timer_inactive(tmr) \
101 do { \
102 (tmr)->it.real.timer.entry.prev = (void *)TIMER_INACTIVE; \
103 } while (0)
104#else
105# define timer_active(tmr) BARFY // error to use outside of SMP
106# define set_timer_inactive(tmr) do { } while (0)
107#endif
108/*
109 * we assume that the new SIGEV_THREAD_ID shares no bits with the other 92 * we assume that the new SIGEV_THREAD_ID shares no bits with the other
110 * SIGEV values. Here we put out an error if this assumption fails. 93 * SIGEV values. Here we put out an error if this assumption fails.
111 */ 94 */
@@ -226,7 +209,6 @@ static inline int common_timer_create(struct k_itimer *new_timer)
226 init_timer(&new_timer->it.real.timer); 209 init_timer(&new_timer->it.real.timer);
227 new_timer->it.real.timer.data = (unsigned long) new_timer; 210 new_timer->it.real.timer.data = (unsigned long) new_timer;
228 new_timer->it.real.timer.function = posix_timer_fn; 211 new_timer->it.real.timer.function = posix_timer_fn;
229 set_timer_inactive(new_timer);
230 return 0; 212 return 0;
231} 213}
232 214
@@ -480,7 +462,6 @@ static void posix_timer_fn(unsigned long __data)
480 int do_notify = 1; 462 int do_notify = 1;
481 463
482 spin_lock_irqsave(&timr->it_lock, flags); 464 spin_lock_irqsave(&timr->it_lock, flags);
483 set_timer_inactive(timr);
484 if (!list_empty(&timr->it.real.abs_timer_entry)) { 465 if (!list_empty(&timr->it.real.abs_timer_entry)) {
485 spin_lock(&abs_list.lock); 466 spin_lock(&abs_list.lock);
486 do { 467 do {
@@ -983,8 +964,8 @@ common_timer_set(struct k_itimer *timr, int flags,
983 * careful here. If smp we could be in the "fire" routine which will 964 * careful here. If smp we could be in the "fire" routine which will
984 * be spinning as we hold the lock. But this is ONLY an SMP issue. 965 * be spinning as we hold the lock. But this is ONLY an SMP issue.
985 */ 966 */
967 if (try_to_del_timer_sync(&timr->it.real.timer) < 0) {
986#ifdef CONFIG_SMP 968#ifdef CONFIG_SMP
987 if (timer_active(timr) && !del_timer(&timr->it.real.timer))
988 /* 969 /*
989 * It can only be active if on an other cpu. Since 970 * It can only be active if on an other cpu. Since
990 * we have cleared the interval stuff above, it should 971 * we have cleared the interval stuff above, it should
@@ -994,11 +975,9 @@ common_timer_set(struct k_itimer *timr, int flags,
994 * a "retry" exit status. 975 * a "retry" exit status.
995 */ 976 */
996 return TIMER_RETRY; 977 return TIMER_RETRY;
997
998 set_timer_inactive(timr);
999#else
1000 del_timer(&timr->it.real.timer);
1001#endif 978#endif
979 }
980
1002 remove_from_abslist(timr); 981 remove_from_abslist(timr);
1003 982
1004 timr->it_requeue_pending = (timr->it_requeue_pending + 2) & 983 timr->it_requeue_pending = (timr->it_requeue_pending + 2) &
@@ -1083,8 +1062,9 @@ retry:
1083static inline int common_timer_del(struct k_itimer *timer) 1062static inline int common_timer_del(struct k_itimer *timer)
1084{ 1063{
1085 timer->it.real.incr = 0; 1064 timer->it.real.incr = 0;
1065
1066 if (try_to_del_timer_sync(&timer->it.real.timer) < 0) {
1086#ifdef CONFIG_SMP 1067#ifdef CONFIG_SMP
1087 if (timer_active(timer) && !del_timer(&timer->it.real.timer))
1088 /* 1068 /*
1089 * It can only be active if on an other cpu. Since 1069 * It can only be active if on an other cpu. Since
1090 * we have cleared the interval stuff above, it should 1070 * we have cleared the interval stuff above, it should
@@ -1094,9 +1074,9 @@ static inline int common_timer_del(struct k_itimer *timer)
1094 * a "retry" exit status. 1074 * a "retry" exit status.
1095 */ 1075 */
1096 return TIMER_RETRY; 1076 return TIMER_RETRY;
1097#else
1098 del_timer(&timer->it.real.timer);
1099#endif 1077#endif
1078 }
1079
1100 remove_from_abslist(timer); 1080 remove_from_abslist(timer);
1101 1081
1102 return 0; 1082 return 0;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 90b3b68dee3f..53f9f8720ee4 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -81,7 +81,7 @@ static int nr_copy_pages_check;
81extern char resume_file[]; 81extern char resume_file[];
82 82
83/* Local variables that should not be affected by save */ 83/* Local variables that should not be affected by save */
84unsigned int nr_copy_pages __nosavedata = 0; 84static unsigned int nr_copy_pages __nosavedata = 0;
85 85
86/* Suspend pagedir is allocated before final copy, therefore it 86/* Suspend pagedir is allocated before final copy, therefore it
87 must be freed after resume 87 must be freed after resume
diff --git a/kernel/printk.c b/kernel/printk.c
index 01b58d7d17ff..3a442bfb8bee 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -876,8 +876,10 @@ void register_console(struct console * console)
876 break; 876 break;
877 console->flags |= CON_ENABLED; 877 console->flags |= CON_ENABLED;
878 console->index = console_cmdline[i].index; 878 console->index = console_cmdline[i].index;
879 if (i == preferred_console) 879 if (i == selected_console) {
880 console->flags |= CON_CONSDEV; 880 console->flags |= CON_CONSDEV;
881 preferred_console = selected_console;
882 }
881 break; 883 break;
882 } 884 }
883 885
@@ -897,6 +899,8 @@ void register_console(struct console * console)
897 if ((console->flags & CON_CONSDEV) || console_drivers == NULL) { 899 if ((console->flags & CON_CONSDEV) || console_drivers == NULL) {
898 console->next = console_drivers; 900 console->next = console_drivers;
899 console_drivers = console; 901 console_drivers = console;
902 if (console->next)
903 console->next->flags &= ~CON_CONSDEV;
900 } else { 904 } else {
901 console->next = console_drivers->next; 905 console->next = console_drivers->next;
902 console_drivers->next = console; 906 console_drivers->next = console;
@@ -937,10 +941,14 @@ int unregister_console(struct console * console)
937 /* If last console is removed, we re-enable picking the first 941 /* If last console is removed, we re-enable picking the first
938 * one that gets registered. Without that, pmac early boot console 942 * one that gets registered. Without that, pmac early boot console
939 * would prevent fbcon from taking over. 943 * would prevent fbcon from taking over.
944 *
945 * If this isn't the last console and it has CON_CONSDEV set, we
946 * need to set it on the next preferred console.
940 */ 947 */
941 if (console_drivers == NULL) 948 if (console_drivers == NULL)
942 preferred_console = selected_console; 949 preferred_console = selected_console;
943 950 else if (console->flags & CON_CONSDEV)
951 console_drivers->flags |= CON_CONSDEV;
944 952
945 release_console_sem(); 953 release_console_sem();
946 return res; 954 return res;
diff --git a/kernel/sched.c b/kernel/sched.c
index deca041fc364..76080d142e3d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2576,7 +2576,7 @@ void fastcall add_preempt_count(int val)
2576 /* 2576 /*
2577 * Underflow? 2577 * Underflow?
2578 */ 2578 */
2579 BUG_ON(((int)preempt_count() < 0)); 2579 BUG_ON((preempt_count() < 0));
2580 preempt_count() += val; 2580 preempt_count() += val;
2581 /* 2581 /*
2582 * Spinlock count overflowing soon? 2582 * Spinlock count overflowing soon?
@@ -2869,7 +2869,7 @@ need_resched:
2869 2869
2870int default_wake_function(wait_queue_t *curr, unsigned mode, int sync, void *key) 2870int default_wake_function(wait_queue_t *curr, unsigned mode, int sync, void *key)
2871{ 2871{
2872 task_t *p = curr->task; 2872 task_t *p = curr->private;
2873 return try_to_wake_up(p, mode, sync); 2873 return try_to_wake_up(p, mode, sync);
2874} 2874}
2875 2875
diff --git a/kernel/signal.c b/kernel/signal.c
index c89821b69ae3..d1258729a5f9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -213,6 +213,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
213fastcall void recalc_sigpending_tsk(struct task_struct *t) 213fastcall void recalc_sigpending_tsk(struct task_struct *t)
214{ 214{
215 if (t->signal->group_stop_count > 0 || 215 if (t->signal->group_stop_count > 0 ||
216 (t->flags & PF_FREEZE) ||
216 PENDING(&t->pending, &t->blocked) || 217 PENDING(&t->pending, &t->blocked) ||
217 PENDING(&t->signal->shared_pending, &t->blocked)) 218 PENDING(&t->signal->shared_pending, &t->blocked))
218 set_tsk_thread_flag(t, TIF_SIGPENDING); 219 set_tsk_thread_flag(t, TIF_SIGPENDING);
diff --git a/kernel/sys.c b/kernel/sys.c
index f006632c2ba7..da24bc1292db 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -525,7 +525,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
525 } 525 }
526 if (new_egid != old_egid) 526 if (new_egid != old_egid)
527 { 527 {
528 current->mm->dumpable = 0; 528 current->mm->dumpable = suid_dumpable;
529 smp_wmb(); 529 smp_wmb();
530 } 530 }
531 if (rgid != (gid_t) -1 || 531 if (rgid != (gid_t) -1 ||
@@ -556,7 +556,7 @@ asmlinkage long sys_setgid(gid_t gid)
556 { 556 {
557 if(old_egid != gid) 557 if(old_egid != gid)
558 { 558 {
559 current->mm->dumpable=0; 559 current->mm->dumpable = suid_dumpable;
560 smp_wmb(); 560 smp_wmb();
561 } 561 }
562 current->gid = current->egid = current->sgid = current->fsgid = gid; 562 current->gid = current->egid = current->sgid = current->fsgid = gid;
@@ -565,7 +565,7 @@ asmlinkage long sys_setgid(gid_t gid)
565 { 565 {
566 if(old_egid != gid) 566 if(old_egid != gid)
567 { 567 {
568 current->mm->dumpable=0; 568 current->mm->dumpable = suid_dumpable;
569 smp_wmb(); 569 smp_wmb();
570 } 570 }
571 current->egid = current->fsgid = gid; 571 current->egid = current->fsgid = gid;
@@ -596,7 +596,7 @@ static int set_user(uid_t new_ruid, int dumpclear)
596 596
597 if(dumpclear) 597 if(dumpclear)
598 { 598 {
599 current->mm->dumpable = 0; 599 current->mm->dumpable = suid_dumpable;
600 smp_wmb(); 600 smp_wmb();
601 } 601 }
602 current->uid = new_ruid; 602 current->uid = new_ruid;
@@ -653,7 +653,7 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
653 653
654 if (new_euid != old_euid) 654 if (new_euid != old_euid)
655 { 655 {
656 current->mm->dumpable=0; 656 current->mm->dumpable = suid_dumpable;
657 smp_wmb(); 657 smp_wmb();
658 } 658 }
659 current->fsuid = current->euid = new_euid; 659 current->fsuid = current->euid = new_euid;
@@ -703,7 +703,7 @@ asmlinkage long sys_setuid(uid_t uid)
703 703
704 if (old_euid != uid) 704 if (old_euid != uid)
705 { 705 {
706 current->mm->dumpable = 0; 706 current->mm->dumpable = suid_dumpable;
707 smp_wmb(); 707 smp_wmb();
708 } 708 }
709 current->fsuid = current->euid = uid; 709 current->fsuid = current->euid = uid;
@@ -748,7 +748,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
748 if (euid != (uid_t) -1) { 748 if (euid != (uid_t) -1) {
749 if (euid != current->euid) 749 if (euid != current->euid)
750 { 750 {
751 current->mm->dumpable = 0; 751 current->mm->dumpable = suid_dumpable;
752 smp_wmb(); 752 smp_wmb();
753 } 753 }
754 current->euid = euid; 754 current->euid = euid;
@@ -798,7 +798,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
798 if (egid != (gid_t) -1) { 798 if (egid != (gid_t) -1) {
799 if (egid != current->egid) 799 if (egid != current->egid)
800 { 800 {
801 current->mm->dumpable = 0; 801 current->mm->dumpable = suid_dumpable;
802 smp_wmb(); 802 smp_wmb();
803 } 803 }
804 current->egid = egid; 804 current->egid = egid;
@@ -845,7 +845,7 @@ asmlinkage long sys_setfsuid(uid_t uid)
845 { 845 {
846 if (uid != old_fsuid) 846 if (uid != old_fsuid)
847 { 847 {
848 current->mm->dumpable = 0; 848 current->mm->dumpable = suid_dumpable;
849 smp_wmb(); 849 smp_wmb();
850 } 850 }
851 current->fsuid = uid; 851 current->fsuid = uid;
@@ -875,7 +875,7 @@ asmlinkage long sys_setfsgid(gid_t gid)
875 { 875 {
876 if (gid != old_fsgid) 876 if (gid != old_fsgid)
877 { 877 {
878 current->mm->dumpable = 0; 878 current->mm->dumpable = suid_dumpable;
879 smp_wmb(); 879 smp_wmb();
880 } 880 }
881 current->fsgid = gid; 881 current->fsgid = gid;
@@ -894,35 +894,69 @@ asmlinkage long sys_times(struct tms __user * tbuf)
894 */ 894 */
895 if (tbuf) { 895 if (tbuf) {
896 struct tms tmp; 896 struct tms tmp;
897 struct task_struct *tsk = current;
898 struct task_struct *t;
899 cputime_t utime, stime, cutime, cstime; 897 cputime_t utime, stime, cutime, cstime;
900 898
901 read_lock(&tasklist_lock); 899#ifdef CONFIG_SMP
902 utime = tsk->signal->utime; 900 if (thread_group_empty(current)) {
903 stime = tsk->signal->stime; 901 /*
904 t = tsk; 902 * Single thread case without the use of any locks.
905 do { 903 *
906 utime = cputime_add(utime, t->utime); 904 * We may race with release_task if two threads are
907 stime = cputime_add(stime, t->stime); 905 * executing. However, release task first adds up the
908 t = next_thread(t); 906 * counters (__exit_signal) before removing the task
909 } while (t != tsk); 907 * from the process tasklist (__unhash_process).
910 908 * __exit_signal also acquires and releases the
911 /* 909 * siglock which results in the proper memory ordering
912 * While we have tasklist_lock read-locked, no dying thread 910 * so that the list modifications are always visible
913 * can be updating current->signal->[us]time. Instead, 911 * after the counters have been updated.
914 * we got their counts included in the live thread loop. 912 *
915 * However, another thread can come in right now and 913 * If the counters have been updated by the second thread
916 * do a wait call that updates current->signal->c[us]time. 914 * but the thread has not yet been removed from the list
917 * To make sure we always see that pair updated atomically, 915 * then the other branch will be executing which will
918 * we take the siglock around fetching them. 916 * block on tasklist_lock until the exit handling of the
919 */ 917 * other task is finished.
920 spin_lock_irq(&tsk->sighand->siglock); 918 *
921 cutime = tsk->signal->cutime; 919 * This also implies that the sighand->siglock cannot
922 cstime = tsk->signal->cstime; 920 * be held by another processor. So we can also
923 spin_unlock_irq(&tsk->sighand->siglock); 921 * skip acquiring that lock.
924 read_unlock(&tasklist_lock); 922 */
923 utime = cputime_add(current->signal->utime, current->utime);
924 stime = cputime_add(current->signal->utime, current->stime);
925 cutime = current->signal->cutime;
926 cstime = current->signal->cstime;
927 } else
928#endif
929 {
930
931 /* Process with multiple threads */
932 struct task_struct *tsk = current;
933 struct task_struct *t;
925 934
935 read_lock(&tasklist_lock);
936 utime = tsk->signal->utime;
937 stime = tsk->signal->stime;
938 t = tsk;
939 do {
940 utime = cputime_add(utime, t->utime);
941 stime = cputime_add(stime, t->stime);
942 t = next_thread(t);
943 } while (t != tsk);
944
945 /*
946 * While we have tasklist_lock read-locked, no dying thread
947 * can be updating current->signal->[us]time. Instead,
948 * we got their counts included in the live thread loop.
949 * However, another thread can come in right now and
950 * do a wait call that updates current->signal->c[us]time.
951 * To make sure we always see that pair updated atomically,
952 * we take the siglock around fetching them.
953 */
954 spin_lock_irq(&tsk->sighand->siglock);
955 cutime = tsk->signal->cutime;
956 cstime = tsk->signal->cstime;
957 spin_unlock_irq(&tsk->sighand->siglock);
958 read_unlock(&tasklist_lock);
959 }
926 tmp.tms_utime = cputime_to_clock_t(utime); 960 tmp.tms_utime = cputime_to_clock_t(utime);
927 tmp.tms_stime = cputime_to_clock_t(stime); 961 tmp.tms_stime = cputime_to_clock_t(stime);
928 tmp.tms_cutime = cputime_to_clock_t(cutime); 962 tmp.tms_cutime = cputime_to_clock_t(cutime);
@@ -1225,7 +1259,7 @@ static void groups_sort(struct group_info *group_info)
1225} 1259}
1226 1260
1227/* a simple bsearch */ 1261/* a simple bsearch */
1228static int groups_search(struct group_info *group_info, gid_t grp) 1262int groups_search(struct group_info *group_info, gid_t grp)
1229{ 1263{
1230 int left, right; 1264 int left, right;
1231 1265
@@ -1652,7 +1686,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1652 error = 1; 1686 error = 1;
1653 break; 1687 break;
1654 case PR_SET_DUMPABLE: 1688 case PR_SET_DUMPABLE:
1655 if (arg2 != 0 && arg2 != 1) { 1689 if (arg2 < 0 || arg2 > 2) {
1656 error = -EINVAL; 1690 error = -EINVAL;
1657 break; 1691 break;
1658 } 1692 }
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 701d12c63068..24a4d12d5aa9 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -58,6 +58,7 @@ extern int sysctl_overcommit_ratio;
58extern int max_threads; 58extern int max_threads;
59extern int sysrq_enabled; 59extern int sysrq_enabled;
60extern int core_uses_pid; 60extern int core_uses_pid;
61extern int suid_dumpable;
61extern char core_pattern[]; 62extern char core_pattern[];
62extern int cad_pid; 63extern int cad_pid;
63extern int pid_max; 64extern int pid_max;
@@ -950,6 +951,14 @@ static ctl_table fs_table[] = {
950 .proc_handler = &proc_dointvec, 951 .proc_handler = &proc_dointvec,
951 }, 952 },
952#endif 953#endif
954 {
955 .ctl_name = KERN_SETUID_DUMPABLE,
956 .procname = "suid_dumpable",
957 .data = &suid_dumpable,
958 .maxlen = sizeof(int),
959 .mode = 0644,
960 .proc_handler = &proc_dointvec,
961 },
953 { .ctl_name = 0 } 962 { .ctl_name = 0 }
954}; 963};
955 964
diff --git a/kernel/timer.c b/kernel/timer.c
index 207aa4f0aa10..51ff917c9590 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -57,6 +57,11 @@ static void time_interpolator_update(long delta_nsec);
57#define TVN_MASK (TVN_SIZE - 1) 57#define TVN_MASK (TVN_SIZE - 1)
58#define TVR_MASK (TVR_SIZE - 1) 58#define TVR_MASK (TVR_SIZE - 1)
59 59
60struct timer_base_s {
61 spinlock_t lock;
62 struct timer_list *running_timer;
63};
64
60typedef struct tvec_s { 65typedef struct tvec_s {
61 struct list_head vec[TVN_SIZE]; 66 struct list_head vec[TVN_SIZE];
62} tvec_t; 67} tvec_t;
@@ -66,9 +71,8 @@ typedef struct tvec_root_s {
66} tvec_root_t; 71} tvec_root_t;
67 72
68struct tvec_t_base_s { 73struct tvec_t_base_s {
69 spinlock_t lock; 74 struct timer_base_s t_base;
70 unsigned long timer_jiffies; 75 unsigned long timer_jiffies;
71 struct timer_list *running_timer;
72 tvec_root_t tv1; 76 tvec_root_t tv1;
73 tvec_t tv2; 77 tvec_t tv2;
74 tvec_t tv3; 78 tvec_t tv3;
@@ -77,18 +81,16 @@ struct tvec_t_base_s {
77} ____cacheline_aligned_in_smp; 81} ____cacheline_aligned_in_smp;
78 82
79typedef struct tvec_t_base_s tvec_base_t; 83typedef struct tvec_t_base_s tvec_base_t;
84static DEFINE_PER_CPU(tvec_base_t, tvec_bases);
80 85
81static inline void set_running_timer(tvec_base_t *base, 86static inline void set_running_timer(tvec_base_t *base,
82 struct timer_list *timer) 87 struct timer_list *timer)
83{ 88{
84#ifdef CONFIG_SMP 89#ifdef CONFIG_SMP
85 base->running_timer = timer; 90 base->t_base.running_timer = timer;
86#endif 91#endif
87} 92}
88 93
89/* Fake initialization */
90static DEFINE_PER_CPU(tvec_base_t, tvec_bases) = { SPIN_LOCK_UNLOCKED };
91
92static void check_timer_failed(struct timer_list *timer) 94static void check_timer_failed(struct timer_list *timer)
93{ 95{
94 static int whine_count; 96 static int whine_count;
@@ -103,7 +105,6 @@ static void check_timer_failed(struct timer_list *timer)
103 /* 105 /*
104 * Now fix it up 106 * Now fix it up
105 */ 107 */
106 spin_lock_init(&timer->lock);
107 timer->magic = TIMER_MAGIC; 108 timer->magic = TIMER_MAGIC;
108} 109}
109 110
@@ -156,65 +157,113 @@ static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
156 list_add_tail(&timer->entry, vec); 157 list_add_tail(&timer->entry, vec);
157} 158}
158 159
160typedef struct timer_base_s timer_base_t;
161/*
162 * Used by TIMER_INITIALIZER, we can't use per_cpu(tvec_bases)
163 * at compile time, and we need timer->base to lock the timer.
164 */
165timer_base_t __init_timer_base
166 ____cacheline_aligned_in_smp = { .lock = SPIN_LOCK_UNLOCKED };
167EXPORT_SYMBOL(__init_timer_base);
168
169/***
170 * init_timer - initialize a timer.
171 * @timer: the timer to be initialized
172 *
173 * init_timer() must be done to a timer prior calling *any* of the
174 * other timer functions.
175 */
176void fastcall init_timer(struct timer_list *timer)
177{
178 timer->entry.next = NULL;
179 timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base;
180 timer->magic = TIMER_MAGIC;
181}
182EXPORT_SYMBOL(init_timer);
183
184static inline void detach_timer(struct timer_list *timer,
185 int clear_pending)
186{
187 struct list_head *entry = &timer->entry;
188
189 __list_del(entry->prev, entry->next);
190 if (clear_pending)
191 entry->next = NULL;
192 entry->prev = LIST_POISON2;
193}
194
195/*
196 * We are using hashed locking: holding per_cpu(tvec_bases).t_base.lock
197 * means that all timers which are tied to this base via timer->base are
198 * locked, and the base itself is locked too.
199 *
200 * So __run_timers/migrate_timers can safely modify all timers which could
201 * be found on ->tvX lists.
202 *
203 * When the timer's base is locked, and the timer removed from list, it is
204 * possible to set timer->base = NULL and drop the lock: the timer remains
205 * locked.
206 */
207static timer_base_t *lock_timer_base(struct timer_list *timer,
208 unsigned long *flags)
209{
210 timer_base_t *base;
211
212 for (;;) {
213 base = timer->base;
214 if (likely(base != NULL)) {
215 spin_lock_irqsave(&base->lock, *flags);
216 if (likely(base == timer->base))
217 return base;
218 /* The timer has migrated to another CPU */
219 spin_unlock_irqrestore(&base->lock, *flags);
220 }
221 cpu_relax();
222 }
223}
224
159int __mod_timer(struct timer_list *timer, unsigned long expires) 225int __mod_timer(struct timer_list *timer, unsigned long expires)
160{ 226{
161 tvec_base_t *old_base, *new_base; 227 timer_base_t *base;
228 tvec_base_t *new_base;
162 unsigned long flags; 229 unsigned long flags;
163 int ret = 0; 230 int ret = 0;
164 231
165 BUG_ON(!timer->function); 232 BUG_ON(!timer->function);
166
167 check_timer(timer); 233 check_timer(timer);
168 234
169 spin_lock_irqsave(&timer->lock, flags); 235 base = lock_timer_base(timer, &flags);
236
237 if (timer_pending(timer)) {
238 detach_timer(timer, 0);
239 ret = 1;
240 }
241
170 new_base = &__get_cpu_var(tvec_bases); 242 new_base = &__get_cpu_var(tvec_bases);
171repeat:
172 old_base = timer->base;
173 243
174 /* 244 if (base != &new_base->t_base) {
175 * Prevent deadlocks via ordering by old_base < new_base.
176 */
177 if (old_base && (new_base != old_base)) {
178 if (old_base < new_base) {
179 spin_lock(&new_base->lock);
180 spin_lock(&old_base->lock);
181 } else {
182 spin_lock(&old_base->lock);
183 spin_lock(&new_base->lock);
184 }
185 /* 245 /*
186 * The timer base might have been cancelled while we were 246 * We are trying to schedule the timer on the local CPU.
187 * trying to take the lock(s): 247 * However we can't change timer's base while it is running,
248 * otherwise del_timer_sync() can't detect that the timer's
249 * handler yet has not finished. This also guarantees that
250 * the timer is serialized wrt itself.
188 */ 251 */
189 if (timer->base != old_base) { 252 if (unlikely(base->running_timer == timer)) {
190 spin_unlock(&new_base->lock); 253 /* The timer remains on a former base */
191 spin_unlock(&old_base->lock); 254 new_base = container_of(base, tvec_base_t, t_base);
192 goto repeat; 255 } else {
193 } 256 /* See the comment in lock_timer_base() */
194 } else { 257 timer->base = NULL;
195 spin_lock(&new_base->lock); 258 spin_unlock(&base->lock);
196 if (timer->base != old_base) { 259 spin_lock(&new_base->t_base.lock);
197 spin_unlock(&new_base->lock); 260 timer->base = &new_base->t_base;
198 goto repeat;
199 } 261 }
200 } 262 }
201 263
202 /*
203 * Delete the previous timeout (if there was any), and install
204 * the new one:
205 */
206 if (old_base) {
207 list_del(&timer->entry);
208 ret = 1;
209 }
210 timer->expires = expires; 264 timer->expires = expires;
211 internal_add_timer(new_base, timer); 265 internal_add_timer(new_base, timer);
212 timer->base = new_base; 266 spin_unlock_irqrestore(&new_base->t_base.lock, flags);
213
214 if (old_base && (new_base != old_base))
215 spin_unlock(&old_base->lock);
216 spin_unlock(&new_base->lock);
217 spin_unlock_irqrestore(&timer->lock, flags);
218 267
219 return ret; 268 return ret;
220} 269}
@@ -232,15 +281,15 @@ void add_timer_on(struct timer_list *timer, int cpu)
232{ 281{
233 tvec_base_t *base = &per_cpu(tvec_bases, cpu); 282 tvec_base_t *base = &per_cpu(tvec_bases, cpu);
234 unsigned long flags; 283 unsigned long flags;
235 284
236 BUG_ON(timer_pending(timer) || !timer->function); 285 BUG_ON(timer_pending(timer) || !timer->function);
237 286
238 check_timer(timer); 287 check_timer(timer);
239 288
240 spin_lock_irqsave(&base->lock, flags); 289 spin_lock_irqsave(&base->t_base.lock, flags);
290 timer->base = &base->t_base;
241 internal_add_timer(base, timer); 291 internal_add_timer(base, timer);
242 timer->base = base; 292 spin_unlock_irqrestore(&base->t_base.lock, flags);
243 spin_unlock_irqrestore(&base->lock, flags);
244} 293}
245 294
246 295
@@ -295,109 +344,84 @@ EXPORT_SYMBOL(mod_timer);
295 */ 344 */
296int del_timer(struct timer_list *timer) 345int del_timer(struct timer_list *timer)
297{ 346{
347 timer_base_t *base;
298 unsigned long flags; 348 unsigned long flags;
299 tvec_base_t *base; 349 int ret = 0;
300 350
301 check_timer(timer); 351 check_timer(timer);
302 352
303repeat: 353 if (timer_pending(timer)) {
304 base = timer->base; 354 base = lock_timer_base(timer, &flags);
305 if (!base) 355 if (timer_pending(timer)) {
306 return 0; 356 detach_timer(timer, 1);
307 spin_lock_irqsave(&base->lock, flags); 357 ret = 1;
308 if (base != timer->base) { 358 }
309 spin_unlock_irqrestore(&base->lock, flags); 359 spin_unlock_irqrestore(&base->lock, flags);
310 goto repeat;
311 } 360 }
312 list_del(&timer->entry);
313 /* Need to make sure that anybody who sees a NULL base also sees the list ops */
314 smp_wmb();
315 timer->base = NULL;
316 spin_unlock_irqrestore(&base->lock, flags);
317 361
318 return 1; 362 return ret;
319} 363}
320 364
321EXPORT_SYMBOL(del_timer); 365EXPORT_SYMBOL(del_timer);
322 366
323#ifdef CONFIG_SMP 367#ifdef CONFIG_SMP
324/*** 368/*
325 * del_timer_sync - deactivate a timer and wait for the handler to finish. 369 * This function tries to deactivate a timer. Upon successful (ret >= 0)
326 * @timer: the timer to be deactivated 370 * exit the timer is not queued and the handler is not running on any CPU.
327 *
328 * This function only differs from del_timer() on SMP: besides deactivating
329 * the timer it also makes sure the handler has finished executing on other
330 * CPUs.
331 *
332 * Synchronization rules: callers must prevent restarting of the timer,
333 * otherwise this function is meaningless. It must not be called from
334 * interrupt contexts. The caller must not hold locks which would prevent
335 * completion of the timer's handler. Upon exit the timer is not queued and
336 * the handler is not running on any CPU.
337 *
338 * The function returns whether it has deactivated a pending timer or not.
339 * 371 *
340 * del_timer_sync() is slow and complicated because it copes with timer 372 * It must not be called from interrupt contexts.
341 * handlers which re-arm the timer (periodic timers). If the timer handler
342 * is known to not do this (a single shot timer) then use
343 * del_singleshot_timer_sync() instead.
344 */ 373 */
345int del_timer_sync(struct timer_list *timer) 374int try_to_del_timer_sync(struct timer_list *timer)
346{ 375{
347 tvec_base_t *base; 376 timer_base_t *base;
348 int i, ret = 0; 377 unsigned long flags;
378 int ret = -1;
349 379
350 check_timer(timer); 380 base = lock_timer_base(timer, &flags);
351 381
352del_again: 382 if (base->running_timer == timer)
353 ret += del_timer(timer); 383 goto out;
354 384
355 for_each_online_cpu(i) { 385 ret = 0;
356 base = &per_cpu(tvec_bases, i); 386 if (timer_pending(timer)) {
357 if (base->running_timer == timer) { 387 detach_timer(timer, 1);
358 while (base->running_timer == timer) { 388 ret = 1;
359 cpu_relax();
360 preempt_check_resched();
361 }
362 break;
363 }
364 } 389 }
365 smp_rmb(); 390out:
366 if (timer_pending(timer)) 391 spin_unlock_irqrestore(&base->lock, flags);
367 goto del_again;
368 392
369 return ret; 393 return ret;
370} 394}
371EXPORT_SYMBOL(del_timer_sync);
372 395
373/*** 396/***
374 * del_singleshot_timer_sync - deactivate a non-recursive timer 397 * del_timer_sync - deactivate a timer and wait for the handler to finish.
375 * @timer: the timer to be deactivated 398 * @timer: the timer to be deactivated
376 * 399 *
377 * This function is an optimization of del_timer_sync for the case where the 400 * This function only differs from del_timer() on SMP: besides deactivating
378 * caller can guarantee the timer does not reschedule itself in its timer 401 * the timer it also makes sure the handler has finished executing on other
379 * function. 402 * CPUs.
380 * 403 *
381 * Synchronization rules: callers must prevent restarting of the timer, 404 * Synchronization rules: callers must prevent restarting of the timer,
382 * otherwise this function is meaningless. It must not be called from 405 * otherwise this function is meaningless. It must not be called from
383 * interrupt contexts. The caller must not hold locks which wold prevent 406 * interrupt contexts. The caller must not hold locks which would prevent
384 * completion of the timer's handler. Upon exit the timer is not queued and 407 * completion of the timer's handler. The timer's handler must not call
385 * the handler is not running on any CPU. 408 * add_timer_on(). Upon exit the timer is not queued and the handler is
409 * not running on any CPU.
386 * 410 *
387 * The function returns whether it has deactivated a pending timer or not. 411 * The function returns whether it has deactivated a pending timer or not.
388 */ 412 */
389int del_singleshot_timer_sync(struct timer_list *timer) 413int del_timer_sync(struct timer_list *timer)
390{ 414{
391 int ret = del_timer(timer); 415 check_timer(timer);
392 416
393 if (!ret) { 417 for (;;) {
394 ret = del_timer_sync(timer); 418 int ret = try_to_del_timer_sync(timer);
395 BUG_ON(ret); 419 if (ret >= 0)
420 return ret;
396 } 421 }
397
398 return ret;
399} 422}
400EXPORT_SYMBOL(del_singleshot_timer_sync); 423
424EXPORT_SYMBOL(del_timer_sync);
401#endif 425#endif
402 426
403static int cascade(tvec_base_t *base, tvec_t *tv, int index) 427static int cascade(tvec_base_t *base, tvec_t *tv, int index)
@@ -415,7 +439,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
415 struct timer_list *tmp; 439 struct timer_list *tmp;
416 440
417 tmp = list_entry(curr, struct timer_list, entry); 441 tmp = list_entry(curr, struct timer_list, entry);
418 BUG_ON(tmp->base != base); 442 BUG_ON(tmp->base != &base->t_base);
419 curr = curr->next; 443 curr = curr->next;
420 internal_add_timer(base, tmp); 444 internal_add_timer(base, tmp);
421 } 445 }
@@ -437,7 +461,7 @@ static inline void __run_timers(tvec_base_t *base)
437{ 461{
438 struct timer_list *timer; 462 struct timer_list *timer;
439 463
440 spin_lock_irq(&base->lock); 464 spin_lock_irq(&base->t_base.lock);
441 while (time_after_eq(jiffies, base->timer_jiffies)) { 465 while (time_after_eq(jiffies, base->timer_jiffies)) {
442 struct list_head work_list = LIST_HEAD_INIT(work_list); 466 struct list_head work_list = LIST_HEAD_INIT(work_list);
443 struct list_head *head = &work_list; 467 struct list_head *head = &work_list;
@@ -453,8 +477,7 @@ static inline void __run_timers(tvec_base_t *base)
453 cascade(base, &base->tv5, INDEX(3)); 477 cascade(base, &base->tv5, INDEX(3));
454 ++base->timer_jiffies; 478 ++base->timer_jiffies;
455 list_splice_init(base->tv1.vec + index, &work_list); 479 list_splice_init(base->tv1.vec + index, &work_list);
456repeat: 480 while (!list_empty(head)) {
457 if (!list_empty(head)) {
458 void (*fn)(unsigned long); 481 void (*fn)(unsigned long);
459 unsigned long data; 482 unsigned long data;
460 483
@@ -462,25 +485,26 @@ repeat:
462 fn = timer->function; 485 fn = timer->function;
463 data = timer->data; 486 data = timer->data;
464 487
465 list_del(&timer->entry);
466 set_running_timer(base, timer); 488 set_running_timer(base, timer);
467 smp_wmb(); 489 detach_timer(timer, 1);
468 timer->base = NULL; 490 spin_unlock_irq(&base->t_base.lock);
469 spin_unlock_irq(&base->lock);
470 { 491 {
471 u32 preempt_count = preempt_count(); 492 int preempt_count = preempt_count();
472 fn(data); 493 fn(data);
473 if (preempt_count != preempt_count()) { 494 if (preempt_count != preempt_count()) {
474 printk("huh, entered %p with %08x, exited with %08x?\n", fn, preempt_count, preempt_count()); 495 printk(KERN_WARNING "huh, entered %p "
496 "with preempt_count %08x, exited"
497 " with %08x?\n",
498 fn, preempt_count,
499 preempt_count());
475 BUG(); 500 BUG();
476 } 501 }
477 } 502 }
478 spin_lock_irq(&base->lock); 503 spin_lock_irq(&base->t_base.lock);
479 goto repeat;
480 } 504 }
481 } 505 }
482 set_running_timer(base, NULL); 506 set_running_timer(base, NULL);
483 spin_unlock_irq(&base->lock); 507 spin_unlock_irq(&base->t_base.lock);
484} 508}
485 509
486#ifdef CONFIG_NO_IDLE_HZ 510#ifdef CONFIG_NO_IDLE_HZ
@@ -499,7 +523,7 @@ unsigned long next_timer_interrupt(void)
499 int i, j; 523 int i, j;
500 524
501 base = &__get_cpu_var(tvec_bases); 525 base = &__get_cpu_var(tvec_bases);
502 spin_lock(&base->lock); 526 spin_lock(&base->t_base.lock);
503 expires = base->timer_jiffies + (LONG_MAX >> 1); 527 expires = base->timer_jiffies + (LONG_MAX >> 1);
504 list = 0; 528 list = 0;
505 529
@@ -547,7 +571,7 @@ found:
547 expires = nte->expires; 571 expires = nte->expires;
548 } 572 }
549 } 573 }
550 spin_unlock(&base->lock); 574 spin_unlock(&base->t_base.lock);
551 return expires; 575 return expires;
552} 576}
553#endif 577#endif
@@ -1286,9 +1310,9 @@ static void __devinit init_timers_cpu(int cpu)
1286{ 1310{
1287 int j; 1311 int j;
1288 tvec_base_t *base; 1312 tvec_base_t *base;
1289 1313
1290 base = &per_cpu(tvec_bases, cpu); 1314 base = &per_cpu(tvec_bases, cpu);
1291 spin_lock_init(&base->lock); 1315 spin_lock_init(&base->t_base.lock);
1292 for (j = 0; j < TVN_SIZE; j++) { 1316 for (j = 0; j < TVN_SIZE; j++) {
1293 INIT_LIST_HEAD(base->tv5.vec + j); 1317 INIT_LIST_HEAD(base->tv5.vec + j);
1294 INIT_LIST_HEAD(base->tv4.vec + j); 1318 INIT_LIST_HEAD(base->tv4.vec + j);
@@ -1302,22 +1326,16 @@ static void __devinit init_timers_cpu(int cpu)
1302} 1326}
1303 1327
1304#ifdef CONFIG_HOTPLUG_CPU 1328#ifdef CONFIG_HOTPLUG_CPU
1305static int migrate_timer_list(tvec_base_t *new_base, struct list_head *head) 1329static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
1306{ 1330{
1307 struct timer_list *timer; 1331 struct timer_list *timer;
1308 1332
1309 while (!list_empty(head)) { 1333 while (!list_empty(head)) {
1310 timer = list_entry(head->next, struct timer_list, entry); 1334 timer = list_entry(head->next, struct timer_list, entry);
1311 /* We're locking backwards from __mod_timer order here, 1335 detach_timer(timer, 0);
1312 beware deadlock. */ 1336 timer->base = &new_base->t_base;
1313 if (!spin_trylock(&timer->lock))
1314 return 0;
1315 list_del(&timer->entry);
1316 internal_add_timer(new_base, timer); 1337 internal_add_timer(new_base, timer);
1317 timer->base = new_base;
1318 spin_unlock(&timer->lock);
1319 } 1338 }
1320 return 1;
1321} 1339}
1322 1340
1323static void __devinit migrate_timers(int cpu) 1341static void __devinit migrate_timers(int cpu)
@@ -1331,39 +1349,24 @@ static void __devinit migrate_timers(int cpu)
1331 new_base = &get_cpu_var(tvec_bases); 1349 new_base = &get_cpu_var(tvec_bases);
1332 1350
1333 local_irq_disable(); 1351 local_irq_disable();
1334again: 1352 spin_lock(&new_base->t_base.lock);
1335 /* Prevent deadlocks via ordering by old_base < new_base. */ 1353 spin_lock(&old_base->t_base.lock);
1336 if (old_base < new_base) {
1337 spin_lock(&new_base->lock);
1338 spin_lock(&old_base->lock);
1339 } else {
1340 spin_lock(&old_base->lock);
1341 spin_lock(&new_base->lock);
1342 }
1343 1354
1344 if (old_base->running_timer) 1355 if (old_base->t_base.running_timer)
1345 BUG(); 1356 BUG();
1346 for (i = 0; i < TVR_SIZE; i++) 1357 for (i = 0; i < TVR_SIZE; i++)
1347 if (!migrate_timer_list(new_base, old_base->tv1.vec + i)) 1358 migrate_timer_list(new_base, old_base->tv1.vec + i);
1348 goto unlock_again; 1359 for (i = 0; i < TVN_SIZE; i++) {
1349 for (i = 0; i < TVN_SIZE; i++) 1360 migrate_timer_list(new_base, old_base->tv2.vec + i);
1350 if (!migrate_timer_list(new_base, old_base->tv2.vec + i) 1361 migrate_timer_list(new_base, old_base->tv3.vec + i);
1351 || !migrate_timer_list(new_base, old_base->tv3.vec + i) 1362 migrate_timer_list(new_base, old_base->tv4.vec + i);
1352 || !migrate_timer_list(new_base, old_base->tv4.vec + i) 1363 migrate_timer_list(new_base, old_base->tv5.vec + i);
1353 || !migrate_timer_list(new_base, old_base->tv5.vec + i)) 1364 }
1354 goto unlock_again; 1365
1355 spin_unlock(&old_base->lock); 1366 spin_unlock(&old_base->t_base.lock);
1356 spin_unlock(&new_base->lock); 1367 spin_unlock(&new_base->t_base.lock);
1357 local_irq_enable(); 1368 local_irq_enable();
1358 put_cpu_var(tvec_bases); 1369 put_cpu_var(tvec_bases);
1359 return;
1360
1361unlock_again:
1362 /* Avoid deadlock with __mod_timer, by backing off. */
1363 spin_unlock(&old_base->lock);
1364 spin_unlock(&new_base->lock);
1365 cpu_relax();
1366 goto again;
1367} 1370}
1368#endif /* CONFIG_HOTPLUG_CPU */ 1371#endif /* CONFIG_HOTPLUG_CPU */
1369 1372
diff --git a/lib/Kconfig b/lib/Kconfig
index 2d4d4e3bc4aa..455833a9e31a 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -63,5 +63,32 @@ config REED_SOLOMON_ENC16
63config REED_SOLOMON_DEC16 63config REED_SOLOMON_DEC16
64 boolean 64 boolean
65 65
66endmenu 66config TEXTSEARCH
67 boolean "Textsearch infrastructure"
68 default y
69 help
70 Say Y here if you want to provide a textsearch infrastructure
71 to other subsystems.
72
73config TEXTSEARCH_KMP
74 depends on TEXTSEARCH
75 tristate "Knuth-Morris-Pratt"
76 help
77 Say Y here if you want to be able to search text using the
78 Knuth-Morris-Pratt textsearch algorithm.
67 79
80 To compile this code as a module, choose M here: the
81 module will be called ts_kmp.
82
83config TEXTSEARCH_FSM
84 depends on TEXTSEARCH
85 tristate "Finite state machine"
86 help
87 Say Y here if you want to be able to search text using a
88 naive finite state machine approach implementing a subset
89 of regular expressions.
90
91 To compile this code as a module, choose M here: the
92 module will be called ts_fsm.
93
94endmenu
diff --git a/lib/Makefile b/lib/Makefile
index dcb4231916e2..beed1585294c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -36,6 +36,10 @@ obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
36obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ 36obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
37obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ 37obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
38 38
39obj-$(CONFIG_TEXTSEARCH) += textsearch.o
40obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
41obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
42
39hostprogs-y := gen_crc32table 43hostprogs-y := gen_crc32table
40clean-files := crc32table.h 44clean-files := crc32table.h
41 45
diff --git a/lib/textsearch.c b/lib/textsearch.c
new file mode 100644
index 000000000000..1e934c196f0f
--- /dev/null
+++ b/lib/textsearch.c
@@ -0,0 +1,317 @@
1/*
2 * lib/textsearch.c Generic text search interface
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Thomas Graf <tgraf@suug.ch>
10 * Pablo Neira Ayuso <pablo@eurodev.net>
11 *
12 * ==========================================================================
13 *
14 * INTRODUCTION
15 *
16 * The textsearch infrastructure provides text searching facitilies for
17 * both linear and non-linear data. Individual search algorithms are
18 * implemented in modules and chosen by the user.
19 *
20 * ARCHITECTURE
21 *
22 * User
23 * +----------------+
24 * | finish()|<--------------(6)-----------------+
25 * |get_next_block()|<--------------(5)---------------+ |
26 * | | Algorithm | |
27 * | | +------------------------------+
28 * | | | init() find() destroy() |
29 * | | +------------------------------+
30 * | | Core API ^ ^ ^
31 * | | +---------------+ (2) (4) (8)
32 * | (1)|----->| prepare() |---+ | |
33 * | (3)|----->| find()/next() |-----------+ |
34 * | (7)|----->| destroy() |----------------------+
35 * +----------------+ +---------------+
36 *
37 * (1) User configures a search by calling _prepare() specifying the
38 * search parameters such as the pattern and algorithm name.
39 * (2) Core requests the algorithm to allocate and initialize a search
40 * configuration according to the specified parameters.
41 * (3) User starts the search(es) by calling _find() or _next() to
42 * fetch subsequent occurrences. A state variable is provided
43 * to the algorihtm to store persistant variables.
44 * (4) Core eventually resets the search offset and forwards the find()
45 * request to the algorithm.
46 * (5) Algorithm calls get_next_block() provided by the user continously
47 * to fetch the data to be searched in block by block.
48 * (6) Algorithm invokes finish() after the last call to get_next_block
49 * to clean up any leftovers from get_next_block. (Optional)
50 * (7) User destroys the configuration by calling _destroy().
51 * (8) Core notifies the algorithm to destroy algorithm specific
52 * allocations. (Optional)
53 *
54 * USAGE
55 *
56 * Before a search can be performed, a configuration must be created
57 * by calling textsearch_prepare() specyfing the searching algorithm and
58 * the pattern to look for. The returned configuration may then be used
59 * for an arbitary amount of times and even in parallel as long as a
60 * separate struct ts_state variable is provided to every instance.
61 *
62 * The actual search is performed by either calling textsearch_find_-
63 * continuous() for linear data or by providing an own get_next_block()
64 * implementation and calling textsearch_find(). Both functions return
65 * the position of the first occurrence of the patern or UINT_MAX if
66 * no match was found. Subsequent occurences can be found by calling
67 * textsearch_next() regardless of the linearity of the data.
68 *
69 * Once you're done using a configuration it must be given back via
70 * textsearch_destroy.
71 *
72 * EXAMPLE
73 *
74 * int pos;
75 * struct ts_config *conf;
76 * struct ts_state state;
77 * const char *pattern = "chicken";
78 * const char *example = "We dance the funky chicken";
79 *
80 * conf = textsearch_prepare("kmp", pattern, strlen(pattern),
81 * GFP_KERNEL, TS_AUTOLOAD);
82 * if (IS_ERR(conf)) {
83 * err = PTR_ERR(conf);
84 * goto errout;
85 * }
86 *
87 * pos = textsearch_find_continuous(conf, &state, example, strlen(example));
88 * if (pos != UINT_MAX)
89 * panic("Oh my god, dancing chickens at %d\n", pos);
90 *
91 * textsearch_destroy(conf);
92 *
93 * ==========================================================================
94 */
95
96#include <linux/config.h>
97#include <linux/module.h>
98#include <linux/types.h>
99#include <linux/string.h>
100#include <linux/init.h>
101#include <linux/rcupdate.h>
102#include <linux/err.h>
103#include <linux/textsearch.h>
104
105static LIST_HEAD(ts_ops);
106static DEFINE_SPINLOCK(ts_mod_lock);
107
108static inline struct ts_ops *lookup_ts_algo(const char *name)
109{
110 struct ts_ops *o;
111
112 rcu_read_lock();
113 list_for_each_entry_rcu(o, &ts_ops, list) {
114 if (!strcmp(name, o->name)) {
115 if (!try_module_get(o->owner))
116 o = NULL;
117 rcu_read_unlock();
118 return o;
119 }
120 }
121 rcu_read_unlock();
122
123 return NULL;
124}
125
126/**
127 * textsearch_register - register a textsearch module
128 * @ops: operations lookup table
129 *
130 * This function must be called by textsearch modules to announce
131 * their presence. The specified &@ops must have %name set to a
132 * unique identifier and the callbacks find(), init(), get_pattern(),
133 * and get_pattern_len() must be implemented.
134 *
135 * Returns 0 or -EEXISTS if another module has already registered
136 * with same name.
137 */
138int textsearch_register(struct ts_ops *ops)
139{
140 int err = -EEXIST;
141 struct ts_ops *o;
142
143 if (ops->name == NULL || ops->find == NULL || ops->init == NULL ||
144 ops->get_pattern == NULL || ops->get_pattern_len == NULL)
145 return -EINVAL;
146
147 spin_lock(&ts_mod_lock);
148 list_for_each_entry(o, &ts_ops, list) {
149 if (!strcmp(ops->name, o->name))
150 goto errout;
151 }
152
153 list_add_tail_rcu(&ops->list, &ts_ops);
154 err = 0;
155errout:
156 spin_unlock(&ts_mod_lock);
157 return err;
158}
159
160/**
161 * textsearch_unregister - unregister a textsearch module
162 * @ops: operations lookup table
163 *
164 * This function must be called by textsearch modules to announce
165 * their disappearance for examples when the module gets unloaded.
166 * The &ops parameter must be the same as the one during the
167 * registration.
168 *
169 * Returns 0 on success or -ENOENT if no matching textsearch
170 * registration was found.
171 */
172int textsearch_unregister(struct ts_ops *ops)
173{
174 int err = 0;
175 struct ts_ops *o;
176
177 spin_lock(&ts_mod_lock);
178 list_for_each_entry(o, &ts_ops, list) {
179 if (o == ops) {
180 list_del_rcu(&o->list);
181 goto out;
182 }
183 }
184
185 err = -ENOENT;
186out:
187 spin_unlock(&ts_mod_lock);
188 return err;
189}
190
191struct ts_linear_state
192{
193 unsigned int len;
194 const void *data;
195};
196
197static unsigned int get_linear_data(unsigned int consumed, const u8 **dst,
198 struct ts_config *conf,
199 struct ts_state *state)
200{
201 struct ts_linear_state *st = (struct ts_linear_state *) state->cb;
202
203 if (likely(consumed < st->len)) {
204 *dst = st->data + consumed;
205 return st->len - consumed;
206 }
207
208 return 0;
209}
210
211/**
212 * textsearch_find_continuous - search a pattern in continuous/linear data
213 * @conf: search configuration
214 * @state: search state
215 * @data: data to search in
216 * @len: length of data
217 *
218 * A simplified version of textsearch_find() for continuous/linear data.
219 * Call textsearch_next() to retrieve subsequent matches.
220 *
221 * Returns the position of first occurrence of the pattern or
222 * UINT_MAX if no occurrence was found.
223 */
224unsigned int textsearch_find_continuous(struct ts_config *conf,
225 struct ts_state *state,
226 const void *data, unsigned int len)
227{
228 struct ts_linear_state *st = (struct ts_linear_state *) state->cb;
229
230 conf->get_next_block = get_linear_data;
231 st->data = data;
232 st->len = len;
233
234 return textsearch_find(conf, state);
235}
236
237/**
238 * textsearch_prepare - Prepare a search
239 * @algo: name of search algorithm
240 * @pattern: pattern data
241 * @len: length of pattern
242 * @gfp_mask: allocation mask
243 * @flags: search flags
244 *
245 * Looks up the search algorithm module and creates a new textsearch
246 * configuration for the specified pattern. Upon completion all
247 * necessary refcnts are held and the configuration must be put back
248 * using textsearch_put() after usage.
249 *
250 * Note: The format of the pattern may not be compatible between
251 * the various search algorithms.
252 *
253 * Returns a new textsearch configuration according to the specified
254 * parameters or a ERR_PTR().
255 */
256struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
257 unsigned int len, int gfp_mask, int flags)
258{
259 int err = -ENOENT;
260 struct ts_config *conf;
261 struct ts_ops *ops;
262
263 ops = lookup_ts_algo(algo);
264#ifdef CONFIG_KMOD
265 /*
266 * Why not always autoload you may ask. Some users are
267 * in a situation where requesting a module may deadlock,
268 * especially when the module is located on a NFS mount.
269 */
270 if (ops == NULL && flags & TS_AUTOLOAD) {
271 request_module("ts_%s", algo);
272 ops = lookup_ts_algo(algo);
273 }
274#endif
275
276 if (ops == NULL)
277 goto errout;
278
279 conf = ops->init(pattern, len, gfp_mask);
280 if (IS_ERR(conf)) {
281 err = PTR_ERR(conf);
282 goto errout;
283 }
284
285 conf->ops = ops;
286 return conf;
287
288errout:
289 if (ops)
290 module_put(ops->owner);
291
292 return ERR_PTR(err);
293}
294
295/**
296 * textsearch_destroy - destroy a search configuration
297 * @conf: search configuration
298 *
299 * Releases all references of the configuration and frees
300 * up the memory.
301 */
302void textsearch_destroy(struct ts_config *conf)
303{
304 if (conf->ops) {
305 if (conf->ops->destroy)
306 conf->ops->destroy(conf);
307 module_put(conf->ops->owner);
308 }
309
310 kfree(conf);
311}
312
313EXPORT_SYMBOL(textsearch_register);
314EXPORT_SYMBOL(textsearch_unregister);
315EXPORT_SYMBOL(textsearch_prepare);
316EXPORT_SYMBOL(textsearch_find_continuous);
317EXPORT_SYMBOL(textsearch_destroy);
diff --git a/lib/ts_fsm.c b/lib/ts_fsm.c
new file mode 100644
index 000000000000..d27c0a072940
--- /dev/null
+++ b/lib/ts_fsm.c
@@ -0,0 +1,338 @@
1/*
2 * lib/ts_fsm.c A naive finite state machine text search approach
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Thomas Graf <tgraf@suug.ch>
10 *
11 * ==========================================================================
12 *
13 * A finite state machine consists of n states (struct ts_fsm_token)
14 * representing the pattern as a finite automation. The data is read
15 * sequentially on a octet basis. Every state token specifies the number
16 * of recurrences and the type of value accepted which can be either a
17 * specific character or ctype based set of characters. The available
18 * type of recurrences include 1, (0|1), [0 n], and [1 n].
19 *
20 * The algorithm differs between strict/non-strict mode specyfing
21 * whether the pattern has to start at the first octect. Strict mode
22 * is enabled by default and can be disabled by inserting
23 * TS_FSM_HEAD_IGNORE as the first token in the chain.
24 *
25 * The runtime performance of the algorithm should be around O(n),
26 * however while in strict mode the average runtime can be better.
27 */
28
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/types.h>
32#include <linux/string.h>
33#include <linux/ctype.h>
34#include <linux/textsearch.h>
35#include <linux/textsearch_fsm.h>
36
37struct ts_fsm
38{
39 unsigned int ntokens;
40 struct ts_fsm_token tokens[0];
41};
42
43/* other values derived from ctype.h */
44#define _A 0x100 /* ascii */
45#define _W 0x200 /* wildcard */
46
47/* Map to _ctype flags and some magic numbers */
48static u16 token_map[TS_FSM_TYPE_MAX+1] = {
49 [TS_FSM_SPECIFIC] = 0,
50 [TS_FSM_WILDCARD] = _W,
51 [TS_FSM_CNTRL] = _C,
52 [TS_FSM_LOWER] = _L,
53 [TS_FSM_UPPER] = _U,
54 [TS_FSM_PUNCT] = _P,
55 [TS_FSM_SPACE] = _S,
56 [TS_FSM_DIGIT] = _D,
57 [TS_FSM_XDIGIT] = _D | _X,
58 [TS_FSM_ALPHA] = _U | _L,
59 [TS_FSM_ALNUM] = _U | _L | _D,
60 [TS_FSM_PRINT] = _P | _U | _L | _D | _SP,
61 [TS_FSM_GRAPH] = _P | _U | _L | _D,
62 [TS_FSM_ASCII] = _A,
63};
64
65static u16 token_lookup_tbl[256] = {
66_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 0- 3 */
67_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 4- 7 */
68_W|_A|_C, _W|_A|_C|_S, _W|_A|_C|_S, _W|_A|_C|_S, /* 8- 11 */
69_W|_A|_C|_S, _W|_A|_C|_S, _W|_A|_C, _W|_A|_C, /* 12- 15 */
70_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 16- 19 */
71_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 20- 23 */
72_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 24- 27 */
73_W|_A|_C, _W|_A|_C, _W|_A|_C, _W|_A|_C, /* 28- 31 */
74_W|_A|_S|_SP, _W|_A|_P, _W|_A|_P, _W|_A|_P, /* 32- 35 */
75_W|_A|_P, _W|_A|_P, _W|_A|_P, _W|_A|_P, /* 36- 39 */
76_W|_A|_P, _W|_A|_P, _W|_A|_P, _W|_A|_P, /* 40- 43 */
77_W|_A|_P, _W|_A|_P, _W|_A|_P, _W|_A|_P, /* 44- 47 */
78_W|_A|_D, _W|_A|_D, _W|_A|_D, _W|_A|_D, /* 48- 51 */
79_W|_A|_D, _W|_A|_D, _W|_A|_D, _W|_A|_D, /* 52- 55 */
80_W|_A|_D, _W|_A|_D, _W|_A|_P, _W|_A|_P, /* 56- 59 */
81_W|_A|_P, _W|_A|_P, _W|_A|_P, _W|_A|_P, /* 60- 63 */
82_W|_A|_P, _W|_A|_U|_X, _W|_A|_U|_X, _W|_A|_U|_X, /* 64- 67 */
83_W|_A|_U|_X, _W|_A|_U|_X, _W|_A|_U|_X, _W|_A|_U, /* 68- 71 */
84_W|_A|_U, _W|_A|_U, _W|_A|_U, _W|_A|_U, /* 72- 75 */
85_W|_A|_U, _W|_A|_U, _W|_A|_U, _W|_A|_U, /* 76- 79 */
86_W|_A|_U, _W|_A|_U, _W|_A|_U, _W|_A|_U, /* 80- 83 */
87_W|_A|_U, _W|_A|_U, _W|_A|_U, _W|_A|_U, /* 84- 87 */
88_W|_A|_U, _W|_A|_U, _W|_A|_U, _W|_A|_P, /* 88- 91 */
89_W|_A|_P, _W|_A|_P, _W|_A|_P, _W|_A|_P, /* 92- 95 */
90_W|_A|_P, _W|_A|_L|_X, _W|_A|_L|_X, _W|_A|_L|_X, /* 96- 99 */
91_W|_A|_L|_X, _W|_A|_L|_X, _W|_A|_L|_X, _W|_A|_L, /* 100-103 */
92_W|_A|_L, _W|_A|_L, _W|_A|_L, _W|_A|_L, /* 104-107 */
93_W|_A|_L, _W|_A|_L, _W|_A|_L, _W|_A|_L, /* 108-111 */
94_W|_A|_L, _W|_A|_L, _W|_A|_L, _W|_A|_L, /* 112-115 */
95_W|_A|_L, _W|_A|_L, _W|_A|_L, _W|_A|_L, /* 116-119 */
96_W|_A|_L, _W|_A|_L, _W|_A|_L, _W|_A|_P, /* 120-123 */
97_W|_A|_P, _W|_A|_P, _W|_A|_P, _W|_A|_C, /* 124-127 */
98_W, _W, _W, _W, /* 128-131 */
99_W, _W, _W, _W, /* 132-135 */
100_W, _W, _W, _W, /* 136-139 */
101_W, _W, _W, _W, /* 140-143 */
102_W, _W, _W, _W, /* 144-147 */
103_W, _W, _W, _W, /* 148-151 */
104_W, _W, _W, _W, /* 152-155 */
105_W, _W, _W, _W, /* 156-159 */
106_W|_S|_SP, _W|_P, _W|_P, _W|_P, /* 160-163 */
107_W|_P, _W|_P, _W|_P, _W|_P, /* 164-167 */
108_W|_P, _W|_P, _W|_P, _W|_P, /* 168-171 */
109_W|_P, _W|_P, _W|_P, _W|_P, /* 172-175 */
110_W|_P, _W|_P, _W|_P, _W|_P, /* 176-179 */
111_W|_P, _W|_P, _W|_P, _W|_P, /* 180-183 */
112_W|_P, _W|_P, _W|_P, _W|_P, /* 184-187 */
113_W|_P, _W|_P, _W|_P, _W|_P, /* 188-191 */
114_W|_U, _W|_U, _W|_U, _W|_U, /* 192-195 */
115_W|_U, _W|_U, _W|_U, _W|_U, /* 196-199 */
116_W|_U, _W|_U, _W|_U, _W|_U, /* 200-203 */
117_W|_U, _W|_U, _W|_U, _W|_U, /* 204-207 */
118_W|_U, _W|_U, _W|_U, _W|_U, /* 208-211 */
119_W|_U, _W|_U, _W|_U, _W|_P, /* 212-215 */
120_W|_U, _W|_U, _W|_U, _W|_U, /* 216-219 */
121_W|_U, _W|_U, _W|_U, _W|_L, /* 220-223 */
122_W|_L, _W|_L, _W|_L, _W|_L, /* 224-227 */
123_W|_L, _W|_L, _W|_L, _W|_L, /* 228-231 */
124_W|_L, _W|_L, _W|_L, _W|_L, /* 232-235 */
125_W|_L, _W|_L, _W|_L, _W|_L, /* 236-239 */
126_W|_L, _W|_L, _W|_L, _W|_L, /* 240-243 */
127_W|_L, _W|_L, _W|_L, _W|_P, /* 244-247 */
128_W|_L, _W|_L, _W|_L, _W|_L, /* 248-251 */
129_W|_L, _W|_L, _W|_L, _W|_L}; /* 252-255 */
130
131static inline int match_token(struct ts_fsm_token *t, u8 d)
132{
133 if (t->type)
134 return (token_lookup_tbl[d] & t->type) != 0;
135 else
136 return t->value == d;
137}
138
139static unsigned int fsm_find(struct ts_config *conf, struct ts_state *state)
140{
141 struct ts_fsm *fsm = ts_config_priv(conf);
142 struct ts_fsm_token *cur = NULL, *next;
143 unsigned int match_start, block_idx = 0, tok_idx;
144 unsigned block_len = 0, strict, consumed = state->offset;
145 const u8 *data;
146
147#define GET_NEXT_BLOCK() \
148({ consumed += block_idx; \
149 block_idx = 0; \
150 block_len = conf->get_next_block(consumed, &data, conf, state); })
151
152#define TOKEN_MISMATCH() \
153 do { \
154 if (strict) \
155 goto no_match; \
156 block_idx++; \
157 goto startover; \
158 } while(0)
159
160#define end_of_data() unlikely(block_idx >= block_len && !GET_NEXT_BLOCK())
161
162 if (end_of_data())
163 goto no_match;
164
165 strict = fsm->tokens[0].recur != TS_FSM_HEAD_IGNORE;
166
167startover:
168 match_start = consumed + block_idx;
169
170 for (tok_idx = 0; tok_idx < fsm->ntokens; tok_idx++) {
171 cur = &fsm->tokens[tok_idx];
172
173 if (likely(tok_idx < (fsm->ntokens - 1)))
174 next = &fsm->tokens[tok_idx + 1];
175 else
176 next = NULL;
177
178 switch (cur->recur) {
179 case TS_FSM_SINGLE:
180 if (end_of_data())
181 goto no_match;
182
183 if (!match_token(cur, data[block_idx]))
184 TOKEN_MISMATCH();
185 break;
186
187 case TS_FSM_PERHAPS:
188 if (end_of_data() ||
189 !match_token(cur, data[block_idx]))
190 continue;
191 break;
192
193 case TS_FSM_MULTI:
194 if (end_of_data())
195 goto no_match;
196
197 if (!match_token(cur, data[block_idx]))
198 TOKEN_MISMATCH();
199
200 block_idx++;
201 /* fall through */
202
203 case TS_FSM_ANY:
204 if (next == NULL)
205 goto found_match;
206
207 if (end_of_data())
208 continue;
209
210 while (!match_token(next, data[block_idx])) {
211 if (!match_token(cur, data[block_idx]))
212 TOKEN_MISMATCH();
213 block_idx++;
214 if (end_of_data())
215 goto no_match;
216 }
217 continue;
218
219 /*
220 * Optimization: Prefer small local loop over jumping
221 * back and forth until garbage at head is munched.
222 */
223 case TS_FSM_HEAD_IGNORE:
224 if (end_of_data())
225 continue;
226
227 while (!match_token(next, data[block_idx])) {
228 /*
229 * Special case, don't start over upon
230 * a mismatch, give the user the
231 * chance to specify the type of data
232 * allowed to be ignored.
233 */
234 if (!match_token(cur, data[block_idx]))
235 goto no_match;
236
237 block_idx++;
238 if (end_of_data())
239 goto no_match;
240 }
241
242 match_start = consumed + block_idx;
243 continue;
244 }
245
246 block_idx++;
247 }
248
249 if (end_of_data())
250 goto found_match;
251
252no_match:
253 return UINT_MAX;
254
255found_match:
256 state->offset = consumed + block_idx;
257 return match_start;
258}
259
260static struct ts_config *fsm_init(const void *pattern, unsigned int len,
261 int gfp_mask)
262{
263 int i, err = -EINVAL;
264 struct ts_config *conf;
265 struct ts_fsm *fsm;
266 struct ts_fsm_token *tokens = (struct ts_fsm_token *) pattern;
267 unsigned int ntokens = len / sizeof(*tokens);
268 size_t priv_size = sizeof(*fsm) + len;
269
270 if (len % sizeof(struct ts_fsm_token) || ntokens < 1)
271 goto errout;
272
273 for (i = 0; i < ntokens; i++) {
274 struct ts_fsm_token *t = &tokens[i];
275
276 if (t->type > TS_FSM_TYPE_MAX || t->recur > TS_FSM_RECUR_MAX)
277 goto errout;
278
279 if (t->recur == TS_FSM_HEAD_IGNORE &&
280 (i != 0 || i == (ntokens - 1)))
281 goto errout;
282 }
283
284 conf = alloc_ts_config(priv_size, gfp_mask);
285 if (IS_ERR(conf))
286 return conf;
287
288 fsm = ts_config_priv(conf);
289 fsm->ntokens = ntokens;
290 memcpy(fsm->tokens, pattern, len);
291
292 for (i = 0; i < fsm->ntokens; i++) {
293 struct ts_fsm_token *t = &fsm->tokens[i];
294 t->type = token_map[t->type];
295 }
296
297 return conf;
298
299errout:
300 return ERR_PTR(err);
301}
302
303static void *fsm_get_pattern(struct ts_config *conf)
304{
305 struct ts_fsm *fsm = ts_config_priv(conf);
306 return fsm->tokens;
307}
308
309static unsigned int fsm_get_pattern_len(struct ts_config *conf)
310{
311 struct ts_fsm *fsm = ts_config_priv(conf);
312 return fsm->ntokens * sizeof(struct ts_fsm_token);
313}
314
315static struct ts_ops fsm_ops = {
316 .name = "fsm",
317 .find = fsm_find,
318 .init = fsm_init,
319 .get_pattern = fsm_get_pattern,
320 .get_pattern_len = fsm_get_pattern_len,
321 .owner = THIS_MODULE,
322 .list = LIST_HEAD_INIT(fsm_ops.list)
323};
324
325static int __init init_fsm(void)
326{
327 return textsearch_register(&fsm_ops);
328}
329
330static void __exit exit_fsm(void)
331{
332 textsearch_unregister(&fsm_ops);
333}
334
335MODULE_LICENSE("GPL");
336
337module_init(init_fsm);
338module_exit(exit_fsm);
diff --git a/lib/ts_kmp.c b/lib/ts_kmp.c
new file mode 100644
index 000000000000..73266b975585
--- /dev/null
+++ b/lib/ts_kmp.c
@@ -0,0 +1,145 @@
1/*
2 * lib/ts_kmp.c Knuth-Morris-Pratt text search implementation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Thomas Graf <tgraf@suug.ch>
10 *
11 * ==========================================================================
12 *
13 * Implements a linear-time string-matching algorithm due to Knuth,
14 * Morris, and Pratt [1]. Their algorithm avoids the explicit
15 * computation of the transition function DELTA altogether. Its
16 * matching time is O(n), for n being length(text), using just an
17 * auxiliary function PI[1..m], for m being length(pattern),
18 * precomputed from the pattern in time O(m). The array PI allows
19 * the transition function DELTA to be computed efficiently
20 * "on the fly" as needed. Roughly speaking, for any state
21 * "q" = 0,1,...,m and any character "a" in SIGMA, the value
22 * PI["q"] contains the information that is independent of "a" and
23 * is needed to compute DELTA("q", "a") [2]. Since the array PI
24 * has only m entries, whereas DELTA has O(m|SIGMA|) entries, we
25 * save a factor of |SIGMA| in the preprocessing time by computing
26 * PI rather than DELTA.
27 *
28 * [1] Cormen, Leiserson, Rivest, Stein
29 * Introdcution to Algorithms, 2nd Edition, MIT Press
30 * [2] See finite automation theory
31 */
32
33#include <linux/config.h>
34#include <linux/module.h>
35#include <linux/types.h>
36#include <linux/string.h>
37#include <linux/textsearch.h>
38
39struct ts_kmp
40{
41 u8 * pattern;
42 unsigned int pattern_len;
43 unsigned int prefix_tbl[0];
44};
45
46static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state)
47{
48 struct ts_kmp *kmp = ts_config_priv(conf);
49 unsigned int i, q = 0, text_len, consumed = state->offset;
50 const u8 *text;
51
52 for (;;) {
53 text_len = conf->get_next_block(consumed, &text, conf, state);
54
55 if (unlikely(text_len == 0))
56 break;
57
58 for (i = 0; i < text_len; i++) {
59 while (q > 0 && kmp->pattern[q] != text[i])
60 q = kmp->prefix_tbl[q - 1];
61 if (kmp->pattern[q] == text[i])
62 q++;
63 if (unlikely(q == kmp->pattern_len)) {
64 state->offset = consumed + i + 1;
65 return state->offset - kmp->pattern_len;
66 }
67 }
68
69 consumed += text_len;
70 }
71
72 return UINT_MAX;
73}
74
75static inline void compute_prefix_tbl(const u8 *pattern, unsigned int len,
76 unsigned int *prefix_tbl)
77{
78 unsigned int k, q;
79
80 for (k = 0, q = 1; q < len; q++) {
81 while (k > 0 && pattern[k] != pattern[q])
82 k = prefix_tbl[k-1];
83 if (pattern[k] == pattern[q])
84 k++;
85 prefix_tbl[q] = k;
86 }
87}
88
89static struct ts_config *kmp_init(const void *pattern, unsigned int len,
90 int gfp_mask)
91{
92 struct ts_config *conf;
93 struct ts_kmp *kmp;
94 unsigned int prefix_tbl_len = len * sizeof(unsigned int);
95 size_t priv_size = sizeof(*kmp) + len + prefix_tbl_len;
96
97 conf = alloc_ts_config(priv_size, gfp_mask);
98 if (IS_ERR(conf))
99 return conf;
100
101 kmp = ts_config_priv(conf);
102 kmp->pattern_len = len;
103 compute_prefix_tbl(pattern, len, kmp->prefix_tbl);
104 kmp->pattern = (u8 *) kmp->prefix_tbl + prefix_tbl_len;
105 memcpy(kmp->pattern, pattern, len);
106
107 return conf;
108}
109
110static void *kmp_get_pattern(struct ts_config *conf)
111{
112 struct ts_kmp *kmp = ts_config_priv(conf);
113 return kmp->pattern;
114}
115
116static unsigned int kmp_get_pattern_len(struct ts_config *conf)
117{
118 struct ts_kmp *kmp = ts_config_priv(conf);
119 return kmp->pattern_len;
120}
121
122static struct ts_ops kmp_ops = {
123 .name = "kmp",
124 .find = kmp_find,
125 .init = kmp_init,
126 .get_pattern = kmp_get_pattern,
127 .get_pattern_len = kmp_get_pattern_len,
128 .owner = THIS_MODULE,
129 .list = LIST_HEAD_INIT(kmp_ops.list)
130};
131
132static int __init init_kmp(void)
133{
134 return textsearch_register(&kmp_ops);
135}
136
137static void __exit exit_kmp(void)
138{
139 textsearch_unregister(&kmp_ops);
140}
141
142MODULE_LICENSE("GPL");
143
144module_init(init_kmp);
145module_exit(exit_kmp);
diff --git a/mm/Kconfig b/mm/Kconfig
new file mode 100644
index 000000000000..cd379936cac6
--- /dev/null
+++ b/mm/Kconfig
@@ -0,0 +1,91 @@
1config SELECT_MEMORY_MODEL
2 def_bool y
3 depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL
4
5choice
6 prompt "Memory model"
7 depends on SELECT_MEMORY_MODEL
8 default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT
9 default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT
10 default FLATMEM_MANUAL
11
12config FLATMEM_MANUAL
13 bool "Flat Memory"
14 depends on !ARCH_DISCONTIGMEM_ENABLE || ARCH_FLATMEM_ENABLE
15 help
16 This option allows you to change some of the ways that
17 Linux manages its memory internally. Most users will
18 only have one option here: FLATMEM. This is normal
19 and a correct option.
20
21 Some users of more advanced features like NUMA and
22 memory hotplug may have different options here.
23 DISCONTIGMEM is an more mature, better tested system,
24 but is incompatible with memory hotplug and may suffer
25 decreased performance over SPARSEMEM. If unsure between
26 "Sparse Memory" and "Discontiguous Memory", choose
27 "Discontiguous Memory".
28
29 If unsure, choose this option (Flat Memory) over any other.
30
31config DISCONTIGMEM_MANUAL
32 bool "Discontigious Memory"
33 depends on ARCH_DISCONTIGMEM_ENABLE
34 help
35 This option provides enhanced support for discontiguous
36 memory systems, over FLATMEM. These systems have holes
37 in their physical address spaces, and this option provides
38 more efficient handling of these holes. However, the vast
39 majority of hardware has quite flat address spaces, and
40 can have degraded performance from extra overhead that
41 this option imposes.
42
43 Many NUMA configurations will have this as the only option.
44
45 If unsure, choose "Flat Memory" over this option.
46
47config SPARSEMEM_MANUAL
48 bool "Sparse Memory"
49 depends on ARCH_SPARSEMEM_ENABLE
50 help
51 This will be the only option for some systems, including
52 memory hotplug systems. This is normal.
53
54 For many other systems, this will be an alternative to
55 "Discontigious Memory". This option provides some potential
56 performance benefits, along with decreased code complexity,
57 but it is newer, and more experimental.
58
59 If unsure, choose "Discontiguous Memory" or "Flat Memory"
60 over this option.
61
62endchoice
63
64config DISCONTIGMEM
65 def_bool y
66 depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL
67
68config SPARSEMEM
69 def_bool y
70 depends on SPARSEMEM_MANUAL
71
72config FLATMEM
73 def_bool y
74 depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL
75
76config FLAT_NODE_MEM_MAP
77 def_bool y
78 depends on !SPARSEMEM
79
80#
81# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
82# to represent different areas of memory. This variable allows
83# those dependencies to exist individually.
84#
85config NEED_MULTIPLE_NODES
86 def_bool y
87 depends on DISCONTIGMEM || NUMA
88
89config HAVE_MEMORY_PRESENT
90 def_bool y
91 depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM
diff --git a/mm/Makefile b/mm/Makefile
index 097408064f6a..4cd69e3ce421 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -15,6 +15,8 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
15obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o 15obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o
16obj-$(CONFIG_HUGETLBFS) += hugetlb.o 16obj-$(CONFIG_HUGETLBFS) += hugetlb.o
17obj-$(CONFIG_NUMA) += mempolicy.o 17obj-$(CONFIG_NUMA) += mempolicy.o
18obj-$(CONFIG_SPARSEMEM) += sparse.o
18obj-$(CONFIG_SHMEM) += shmem.o 19obj-$(CONFIG_SHMEM) += shmem.o
19obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o 20obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
20 21
22obj-$(CONFIG_FS_XIP) += filemap_xip.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 260e703850d8..f82f7aebbee3 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -256,6 +256,7 @@ found:
256static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) 256static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
257{ 257{
258 struct page *page; 258 struct page *page;
259 unsigned long pfn;
259 bootmem_data_t *bdata = pgdat->bdata; 260 bootmem_data_t *bdata = pgdat->bdata;
260 unsigned long i, count, total = 0; 261 unsigned long i, count, total = 0;
261 unsigned long idx; 262 unsigned long idx;
@@ -266,7 +267,7 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
266 267
267 count = 0; 268 count = 0;
268 /* first extant page of the node */ 269 /* first extant page of the node */
269 page = virt_to_page(phys_to_virt(bdata->node_boot_start)); 270 pfn = bdata->node_boot_start >> PAGE_SHIFT;
270 idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT); 271 idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
271 map = bdata->node_bootmem_map; 272 map = bdata->node_bootmem_map;
272 /* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */ 273 /* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
@@ -275,9 +276,11 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
275 gofast = 1; 276 gofast = 1;
276 for (i = 0; i < idx; ) { 277 for (i = 0; i < idx; ) {
277 unsigned long v = ~map[i / BITS_PER_LONG]; 278 unsigned long v = ~map[i / BITS_PER_LONG];
279
278 if (gofast && v == ~0UL) { 280 if (gofast && v == ~0UL) {
279 int j, order; 281 int j, order;
280 282
283 page = pfn_to_page(pfn);
281 count += BITS_PER_LONG; 284 count += BITS_PER_LONG;
282 __ClearPageReserved(page); 285 __ClearPageReserved(page);
283 order = ffs(BITS_PER_LONG) - 1; 286 order = ffs(BITS_PER_LONG) - 1;
@@ -292,6 +295,8 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
292 page += BITS_PER_LONG; 295 page += BITS_PER_LONG;
293 } else if (v) { 296 } else if (v) {
294 unsigned long m; 297 unsigned long m;
298
299 page = pfn_to_page(pfn);
295 for (m = 1; m && i < idx; m<<=1, page++, i++) { 300 for (m = 1; m && i < idx; m<<=1, page++, i++) {
296 if (v & m) { 301 if (v & m) {
297 count++; 302 count++;
@@ -302,8 +307,8 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
302 } 307 }
303 } else { 308 } else {
304 i+=BITS_PER_LONG; 309 i+=BITS_PER_LONG;
305 page += BITS_PER_LONG;
306 } 310 }
311 pfn += BITS_PER_LONG;
307 } 312 }
308 total += count; 313 total += count;
309 314
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 57264d74b8bf..5f19e87bc5af 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -43,6 +43,10 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
43 goto out; 43 goto out;
44 } 44 }
45 45
46 if (mapping->a_ops->get_xip_page)
47 /* no bad return value, but ignore advice */
48 goto out;
49
46 /* Careful about overflows. Len == 0 means "as much as possible" */ 50 /* Careful about overflows. Len == 0 means "as much as possible" */
47 endbyte = offset + len; 51 endbyte = offset + len;
48 if (!len || endbyte < len) 52 if (!len || endbyte < len)
diff --git a/mm/filemap.c b/mm/filemap.c
index 4a2fee2cb62b..7332194d7afd 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -28,6 +28,7 @@
28#include <linux/blkdev.h> 28#include <linux/blkdev.h>
29#include <linux/security.h> 29#include <linux/security.h>
30#include <linux/syscalls.h> 30#include <linux/syscalls.h>
31#include "filemap.h"
31/* 32/*
32 * FIXME: remove all knowledge of the buffer layer from the core VM 33 * FIXME: remove all knowledge of the buffer layer from the core VM
33 */ 34 */
@@ -1714,32 +1715,7 @@ int remove_suid(struct dentry *dentry)
1714} 1715}
1715EXPORT_SYMBOL(remove_suid); 1716EXPORT_SYMBOL(remove_suid);
1716 1717
1717/* 1718size_t
1718 * Copy as much as we can into the page and return the number of bytes which
1719 * were sucessfully copied. If a fault is encountered then clear the page
1720 * out to (offset+bytes) and return the number of bytes which were copied.
1721 */
1722static inline size_t
1723filemap_copy_from_user(struct page *page, unsigned long offset,
1724 const char __user *buf, unsigned bytes)
1725{
1726 char *kaddr;
1727 int left;
1728
1729 kaddr = kmap_atomic(page, KM_USER0);
1730 left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
1731 kunmap_atomic(kaddr, KM_USER0);
1732
1733 if (left != 0) {
1734 /* Do it the slow way */
1735 kaddr = kmap(page);
1736 left = __copy_from_user(kaddr + offset, buf, bytes);
1737 kunmap(page);
1738 }
1739 return bytes - left;
1740}
1741
1742static size_t
1743__filemap_copy_from_user_iovec(char *vaddr, 1719__filemap_copy_from_user_iovec(char *vaddr,
1744 const struct iovec *iov, size_t base, size_t bytes) 1720 const struct iovec *iov, size_t base, size_t bytes)
1745{ 1721{
@@ -1767,52 +1743,6 @@ __filemap_copy_from_user_iovec(char *vaddr,
1767} 1743}
1768 1744
1769/* 1745/*
1770 * This has the same sideeffects and return value as filemap_copy_from_user().
1771 * The difference is that on a fault we need to memset the remainder of the
1772 * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
1773 * single-segment behaviour.
1774 */
1775static inline size_t
1776filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
1777 const struct iovec *iov, size_t base, size_t bytes)
1778{
1779 char *kaddr;
1780 size_t copied;
1781
1782 kaddr = kmap_atomic(page, KM_USER0);
1783 copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
1784 base, bytes);
1785 kunmap_atomic(kaddr, KM_USER0);
1786 if (copied != bytes) {
1787 kaddr = kmap(page);
1788 copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
1789 base, bytes);
1790 kunmap(page);
1791 }
1792 return copied;
1793}
1794
1795static inline void
1796filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
1797{
1798 const struct iovec *iov = *iovp;
1799 size_t base = *basep;
1800
1801 while (bytes) {
1802 int copy = min(bytes, iov->iov_len - base);
1803
1804 bytes -= copy;
1805 base += copy;
1806 if (iov->iov_len == base) {
1807 iov++;
1808 base = 0;
1809 }
1810 }
1811 *iovp = iov;
1812 *basep = base;
1813}
1814
1815/*
1816 * Performs necessary checks before doing a write 1746 * Performs necessary checks before doing a write
1817 * 1747 *
1818 * Can adjust writing position aor amount of bytes to write. 1748 * Can adjust writing position aor amount of bytes to write.
@@ -1827,12 +1757,6 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i
1827 if (unlikely(*pos < 0)) 1757 if (unlikely(*pos < 0))
1828 return -EINVAL; 1758 return -EINVAL;
1829 1759
1830 if (unlikely(file->f_error)) {
1831 int err = file->f_error;
1832 file->f_error = 0;
1833 return err;
1834 }
1835
1836 if (!isblk) { 1760 if (!isblk) {
1837 /* FIXME: this is for backwards compatibility with 2.4 */ 1761 /* FIXME: this is for backwards compatibility with 2.4 */
1838 if (file->f_flags & O_APPEND) 1762 if (file->f_flags & O_APPEND)
diff --git a/mm/filemap.h b/mm/filemap.h
new file mode 100644
index 000000000000..13793ba0ce17
--- /dev/null
+++ b/mm/filemap.h
@@ -0,0 +1,94 @@
1/*
2 * linux/mm/filemap.h
3 *
4 * Copyright (C) 1994-1999 Linus Torvalds
5 */
6
7#ifndef __FILEMAP_H
8#define __FILEMAP_H
9
10#include <linux/types.h>
11#include <linux/fs.h>
12#include <linux/mm.h>
13#include <linux/highmem.h>
14#include <linux/uio.h>
15#include <linux/config.h>
16#include <asm/uaccess.h>
17
18size_t
19__filemap_copy_from_user_iovec(char *vaddr,
20 const struct iovec *iov,
21 size_t base,
22 size_t bytes);
23
24/*
25 * Copy as much as we can into the page and return the number of bytes which
26 * were sucessfully copied. If a fault is encountered then clear the page
27 * out to (offset+bytes) and return the number of bytes which were copied.
28 */
29static inline size_t
30filemap_copy_from_user(struct page *page, unsigned long offset,
31 const char __user *buf, unsigned bytes)
32{
33 char *kaddr;
34 int left;
35
36 kaddr = kmap_atomic(page, KM_USER0);
37 left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
38 kunmap_atomic(kaddr, KM_USER0);
39
40 if (left != 0) {
41 /* Do it the slow way */
42 kaddr = kmap(page);
43 left = __copy_from_user(kaddr + offset, buf, bytes);
44 kunmap(page);
45 }
46 return bytes - left;
47}
48
49/*
50 * This has the same sideeffects and return value as filemap_copy_from_user().
51 * The difference is that on a fault we need to memset the remainder of the
52 * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
53 * single-segment behaviour.
54 */
55static inline size_t
56filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
57 const struct iovec *iov, size_t base, size_t bytes)
58{
59 char *kaddr;
60 size_t copied;
61
62 kaddr = kmap_atomic(page, KM_USER0);
63 copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
64 base, bytes);
65 kunmap_atomic(kaddr, KM_USER0);
66 if (copied != bytes) {
67 kaddr = kmap(page);
68 copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
69 base, bytes);
70 kunmap(page);
71 }
72 return copied;
73}
74
75static inline void
76filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
77{
78 const struct iovec *iov = *iovp;
79 size_t base = *basep;
80
81 while (bytes) {
82 int copy = min(bytes, iov->iov_len - base);
83
84 bytes -= copy;
85 base += copy;
86 if (iov->iov_len == base) {
87 iov++;
88 base = 0;
89 }
90 }
91 *iovp = iov;
92 *basep = base;
93}
94#endif
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
new file mode 100644
index 000000000000..3b6e384b98a6
--- /dev/null
+++ b/mm/filemap_xip.c
@@ -0,0 +1,447 @@
1/*
2 * linux/mm/filemap_xip.c
3 *
4 * Copyright (C) 2005 IBM Corporation
5 * Author: Carsten Otte <cotte@de.ibm.com>
6 *
7 * derived from linux/mm/filemap.c - Copyright (C) Linus Torvalds
8 *
9 */
10
11#include <linux/fs.h>
12#include <linux/pagemap.h>
13#include <linux/module.h>
14#include <linux/uio.h>
15#include <linux/rmap.h>
16#include <asm/tlbflush.h>
17#include "filemap.h"
18
19/*
20 * This is a file read routine for execute in place files, and uses
21 * the mapping->a_ops->get_xip_page() function for the actual low-level
22 * stuff.
23 *
24 * Note the struct file* is not used at all. It may be NULL.
25 */
26static void
27do_xip_mapping_read(struct address_space *mapping,
28 struct file_ra_state *_ra,
29 struct file *filp,
30 loff_t *ppos,
31 read_descriptor_t *desc,
32 read_actor_t actor)
33{
34 struct inode *inode = mapping->host;
35 unsigned long index, end_index, offset;
36 loff_t isize;
37
38 BUG_ON(!mapping->a_ops->get_xip_page);
39
40 index = *ppos >> PAGE_CACHE_SHIFT;
41 offset = *ppos & ~PAGE_CACHE_MASK;
42
43 isize = i_size_read(inode);
44 if (!isize)
45 goto out;
46
47 end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
48 for (;;) {
49 struct page *page;
50 unsigned long nr, ret;
51
52 /* nr is the maximum number of bytes to copy from this page */
53 nr = PAGE_CACHE_SIZE;
54 if (index >= end_index) {
55 if (index > end_index)
56 goto out;
57 nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
58 if (nr <= offset) {
59 goto out;
60 }
61 }
62 nr = nr - offset;
63
64 page = mapping->a_ops->get_xip_page(mapping,
65 index*(PAGE_SIZE/512), 0);
66 if (!page)
67 goto no_xip_page;
68 if (unlikely(IS_ERR(page))) {
69 if (PTR_ERR(page) == -ENODATA) {
70 /* sparse */
71 page = virt_to_page(empty_zero_page);
72 } else {
73 desc->error = PTR_ERR(page);
74 goto out;
75 }
76 } else
77 BUG_ON(!PageUptodate(page));
78
79 /* If users can be writing to this page using arbitrary
80 * virtual addresses, take care about potential aliasing
81 * before reading the page on the kernel side.
82 */
83 if (mapping_writably_mapped(mapping))
84 flush_dcache_page(page);
85
86 /*
87 * Ok, we have the page, and it's up-to-date, so
88 * now we can copy it to user space...
89 *
90 * The actor routine returns how many bytes were actually used..
91 * NOTE! This may not be the same as how much of a user buffer
92 * we filled up (we may be padding etc), so we can only update
93 * "pos" here (the actor routine has to update the user buffer
94 * pointers and the remaining count).
95 */
96 ret = actor(desc, page, offset, nr);
97 offset += ret;
98 index += offset >> PAGE_CACHE_SHIFT;
99 offset &= ~PAGE_CACHE_MASK;
100
101 if (ret == nr && desc->count)
102 continue;
103 goto out;
104
105no_xip_page:
106 /* Did not get the page. Report it */
107 desc->error = -EIO;
108 goto out;
109 }
110
111out:
112 *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
113 if (filp)
114 file_accessed(filp);
115}
116
117ssize_t
118xip_file_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
119{
120 read_descriptor_t desc;
121
122 if (!access_ok(VERIFY_WRITE, buf, len))
123 return -EFAULT;
124
125 desc.written = 0;
126 desc.arg.buf = buf;
127 desc.count = len;
128 desc.error = 0;
129
130 do_xip_mapping_read(filp->f_mapping, &filp->f_ra, filp,
131 ppos, &desc, file_read_actor);
132
133 if (desc.written)
134 return desc.written;
135 else
136 return desc.error;
137}
138EXPORT_SYMBOL_GPL(xip_file_read);
139
140ssize_t
141xip_file_sendfile(struct file *in_file, loff_t *ppos,
142 size_t count, read_actor_t actor, void *target)
143{
144 read_descriptor_t desc;
145
146 if (!count)
147 return 0;
148
149 desc.written = 0;
150 desc.count = count;
151 desc.arg.data = target;
152 desc.error = 0;
153
154 do_xip_mapping_read(in_file->f_mapping, &in_file->f_ra, in_file,
155 ppos, &desc, actor);
156 if (desc.written)
157 return desc.written;
158 return desc.error;
159}
160EXPORT_SYMBOL_GPL(xip_file_sendfile);
161
162/*
163 * __xip_unmap is invoked from xip_unmap and
164 * xip_write
165 *
166 * This function walks all vmas of the address_space and unmaps the
167 * empty_zero_page when found at pgoff. Should it go in rmap.c?
168 */
169static void
170__xip_unmap (struct address_space * mapping,
171 unsigned long pgoff)
172{
173 struct vm_area_struct *vma;
174 struct mm_struct *mm;
175 struct prio_tree_iter iter;
176 unsigned long address;
177 pte_t *pte;
178 pte_t pteval;
179
180 spin_lock(&mapping->i_mmap_lock);
181 vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
182 mm = vma->vm_mm;
183 address = vma->vm_start +
184 ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
185 BUG_ON(address < vma->vm_start || address >= vma->vm_end);
186 /*
187 * We need the page_table_lock to protect us from page faults,
188 * munmap, fork, etc...
189 */
190 pte = page_check_address(virt_to_page(empty_zero_page), mm,
191 address);
192 if (!IS_ERR(pte)) {
193 /* Nuke the page table entry. */
194 flush_cache_page(vma, address, pte_pfn(pte));
195 pteval = ptep_clear_flush(vma, address, pte);
196 BUG_ON(pte_dirty(pteval));
197 pte_unmap(pte);
198 spin_unlock(&mm->page_table_lock);
199 }
200 }
201 spin_unlock(&mapping->i_mmap_lock);
202}
203
204/*
205 * xip_nopage() is invoked via the vma operations vector for a
206 * mapped memory region to read in file data during a page fault.
207 *
208 * This function is derived from filemap_nopage, but used for execute in place
209 */
210static struct page *
211xip_file_nopage(struct vm_area_struct * area,
212 unsigned long address,
213 int *type)
214{
215 struct file *file = area->vm_file;
216 struct address_space *mapping = file->f_mapping;
217 struct inode *inode = mapping->host;
218 struct page *page;
219 unsigned long size, pgoff, endoff;
220
221 pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT)
222 + area->vm_pgoff;
223 endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT)
224 + area->vm_pgoff;
225
226 size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
227 if (pgoff >= size) {
228 return NULL;
229 }
230
231 page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
232 if (!IS_ERR(page)) {
233 BUG_ON(!PageUptodate(page));
234 return page;
235 }
236 if (PTR_ERR(page) != -ENODATA)
237 return NULL;
238
239 /* sparse block */
240 if ((area->vm_flags & (VM_WRITE | VM_MAYWRITE)) &&
241 (area->vm_flags & (VM_SHARED| VM_MAYSHARE)) &&
242 (!(mapping->host->i_sb->s_flags & MS_RDONLY))) {
243 /* maybe shared writable, allocate new block */
244 page = mapping->a_ops->get_xip_page (mapping,
245 pgoff*(PAGE_SIZE/512), 1);
246 if (IS_ERR(page))
247 return NULL;
248 BUG_ON(!PageUptodate(page));
249 /* unmap page at pgoff from all other vmas */
250 __xip_unmap(mapping, pgoff);
251 } else {
252 /* not shared and writable, use empty_zero_page */
253 page = virt_to_page(empty_zero_page);
254 }
255
256 return page;
257}
258
259static struct vm_operations_struct xip_file_vm_ops = {
260 .nopage = xip_file_nopage,
261};
262
263int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
264{
265 BUG_ON(!file->f_mapping->a_ops->get_xip_page);
266
267 file_accessed(file);
268 vma->vm_ops = &xip_file_vm_ops;
269 return 0;
270}
271EXPORT_SYMBOL_GPL(xip_file_mmap);
272
273static ssize_t
274__xip_file_write(struct file *filp, const char __user *buf,
275 size_t count, loff_t pos, loff_t *ppos)
276{
277 struct address_space * mapping = filp->f_mapping;
278 struct address_space_operations *a_ops = mapping->a_ops;
279 struct inode *inode = mapping->host;
280 long status = 0;
281 struct page *page;
282 size_t bytes;
283 ssize_t written = 0;
284
285 BUG_ON(!mapping->a_ops->get_xip_page);
286
287 do {
288 unsigned long index;
289 unsigned long offset;
290 size_t copied;
291
292 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
293 index = pos >> PAGE_CACHE_SHIFT;
294 bytes = PAGE_CACHE_SIZE - offset;
295 if (bytes > count)
296 bytes = count;
297
298 /*
299 * Bring in the user page that we will copy from _first_.
300 * Otherwise there's a nasty deadlock on copying from the
301 * same page as we're writing to, without it being marked
302 * up-to-date.
303 */
304 fault_in_pages_readable(buf, bytes);
305
306 page = a_ops->get_xip_page(mapping,
307 index*(PAGE_SIZE/512), 0);
308 if (IS_ERR(page) && (PTR_ERR(page) == -ENODATA)) {
309 /* we allocate a new page unmap it */
310 page = a_ops->get_xip_page(mapping,
311 index*(PAGE_SIZE/512), 1);
312 if (!IS_ERR(page))
313 /* unmap page at pgoff from all other vmas */
314 __xip_unmap(mapping, index);
315 }
316
317 if (IS_ERR(page)) {
318 status = PTR_ERR(page);
319 break;
320 }
321
322 BUG_ON(!PageUptodate(page));
323
324 copied = filemap_copy_from_user(page, offset, buf, bytes);
325 flush_dcache_page(page);
326 if (likely(copied > 0)) {
327 status = copied;
328
329 if (status >= 0) {
330 written += status;
331 count -= status;
332 pos += status;
333 buf += status;
334 }
335 }
336 if (unlikely(copied != bytes))
337 if (status >= 0)
338 status = -EFAULT;
339 if (status < 0)
340 break;
341 } while (count);
342 *ppos = pos;
343 /*
344 * No need to use i_size_read() here, the i_size
345 * cannot change under us because we hold i_sem.
346 */
347 if (pos > inode->i_size) {
348 i_size_write(inode, pos);
349 mark_inode_dirty(inode);
350 }
351
352 return written ? written : status;
353}
354
355ssize_t
356xip_file_write(struct file *filp, const char __user *buf, size_t len,
357 loff_t *ppos)
358{
359 struct address_space *mapping = filp->f_mapping;
360 struct inode *inode = mapping->host;
361 size_t count;
362 loff_t pos;
363 ssize_t ret;
364
365 down(&inode->i_sem);
366
367 if (!access_ok(VERIFY_READ, buf, len)) {
368 ret=-EFAULT;
369 goto out_up;
370 }
371
372 pos = *ppos;
373 count = len;
374
375 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
376
377 /* We can write back this queue in page reclaim */
378 current->backing_dev_info = mapping->backing_dev_info;
379
380 ret = generic_write_checks(filp, &pos, &count, S_ISBLK(inode->i_mode));
381 if (ret)
382 goto out_backing;
383 if (count == 0)
384 goto out_backing;
385
386 ret = remove_suid(filp->f_dentry);
387 if (ret)
388 goto out_backing;
389
390 inode_update_time(inode, 1);
391
392 ret = __xip_file_write (filp, buf, count, pos, ppos);
393
394 out_backing:
395 current->backing_dev_info = NULL;
396 out_up:
397 up(&inode->i_sem);
398 return ret;
399}
400EXPORT_SYMBOL_GPL(xip_file_write);
401
402/*
403 * truncate a page used for execute in place
404 * functionality is analog to block_truncate_page but does use get_xip_page
405 * to get the page instead of page cache
406 */
407int
408xip_truncate_page(struct address_space *mapping, loff_t from)
409{
410 pgoff_t index = from >> PAGE_CACHE_SHIFT;
411 unsigned offset = from & (PAGE_CACHE_SIZE-1);
412 unsigned blocksize;
413 unsigned length;
414 struct page *page;
415 void *kaddr;
416
417 BUG_ON(!mapping->a_ops->get_xip_page);
418
419 blocksize = 1 << mapping->host->i_blkbits;
420 length = offset & (blocksize - 1);
421
422 /* Block boundary? Nothing to do */
423 if (!length)
424 return 0;
425
426 length = blocksize - length;
427
428 page = mapping->a_ops->get_xip_page(mapping,
429 index*(PAGE_SIZE/512), 0);
430 if (!page)
431 return -ENOMEM;
432 if (unlikely(IS_ERR(page))) {
433 if (PTR_ERR(page) == -ENODATA)
434 /* Hole? No need to truncate */
435 return 0;
436 else
437 return PTR_ERR(page);
438 } else
439 BUG_ON(!PageUptodate(page));
440 kaddr = kmap_atomic(page, KM_USER0);
441 memset(kaddr + offset, 0, length);
442 kunmap_atomic(kaddr, KM_USER0);
443
444 flush_dcache_page(page);
445 return 0;
446}
447EXPORT_SYMBOL_GPL(xip_truncate_page);
diff --git a/mm/madvise.c b/mm/madvise.c
index e3108054733c..73180a22877e 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -65,7 +65,6 @@ static long madvise_behavior(struct vm_area_struct * vma,
65 /* 65 /*
66 * vm_flags is protected by the mmap_sem held in write mode. 66 * vm_flags is protected by the mmap_sem held in write mode.
67 */ 67 */
68 VM_ClearReadHint(vma);
69 vma->vm_flags = new_flags; 68 vma->vm_flags = new_flags;
70 69
71out: 70out:
@@ -87,6 +86,11 @@ static long madvise_willneed(struct vm_area_struct * vma,
87 if (!file) 86 if (!file)
88 return -EBADF; 87 return -EBADF;
89 88
89 if (file->f_mapping->a_ops->get_xip_page) {
90 /* no bad return value, but ignore advice */
91 return 0;
92 }
93
90 *prev = vma; 94 *prev = vma;
91 start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; 95 start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
92 if (end > vma->vm_end) 96 if (end > vma->vm_end)
diff --git a/mm/memory.c b/mm/memory.c
index da91b7bf9986..c256175742ac 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -58,7 +58,7 @@
58#include <linux/swapops.h> 58#include <linux/swapops.h>
59#include <linux/elf.h> 59#include <linux/elf.h>
60 60
61#ifndef CONFIG_DISCONTIGMEM 61#ifndef CONFIG_NEED_MULTIPLE_NODES
62/* use the per-pgdat data instead for discontigmem - mbligh */ 62/* use the per-pgdat data instead for discontigmem - mbligh */
63unsigned long max_mapnr; 63unsigned long max_mapnr;
64struct page *mem_map; 64struct page *mem_map;
@@ -1458,7 +1458,7 @@ restart:
1458 * unmap_mapping_range - unmap the portion of all mmaps 1458 * unmap_mapping_range - unmap the portion of all mmaps
1459 * in the specified address_space corresponding to the specified 1459 * in the specified address_space corresponding to the specified
1460 * page range in the underlying file. 1460 * page range in the underlying file.
1461 * @address_space: the address space containing mmaps to be unmapped. 1461 * @mapping: the address space containing mmaps to be unmapped.
1462 * @holebegin: byte in first page to unmap, relative to the start of 1462 * @holebegin: byte in first page to unmap, relative to the start of
1463 * the underlying file. This will be rounded down to a PAGE_SIZE 1463 * the underlying file. This will be rounded down to a PAGE_SIZE
1464 * boundary. Note that this is different from vmtruncate(), which 1464 * boundary. Note that this is different from vmtruncate(), which
diff --git a/mm/mempool.c b/mm/mempool.c
index c9f3d4620428..9a72f7d918fa 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -51,16 +51,23 @@ static void free_pool(mempool_t *pool)
51 * functions might sleep - as long as the mempool_alloc function is not called 51 * functions might sleep - as long as the mempool_alloc function is not called
52 * from IRQ contexts. 52 * from IRQ contexts.
53 */ 53 */
54mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn, 54mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
55 mempool_free_t *free_fn, void *pool_data) 55 mempool_free_t *free_fn, void *pool_data)
56{ 56{
57 mempool_t *pool; 57 return mempool_create_node(min_nr,alloc_fn,free_fn, pool_data,-1);
58}
59EXPORT_SYMBOL(mempool_create);
58 60
59 pool = kmalloc(sizeof(*pool), GFP_KERNEL); 61mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
62 mempool_free_t *free_fn, void *pool_data, int node_id)
63{
64 mempool_t *pool;
65 pool = kmalloc_node(sizeof(*pool), GFP_KERNEL, node_id);
60 if (!pool) 66 if (!pool)
61 return NULL; 67 return NULL;
62 memset(pool, 0, sizeof(*pool)); 68 memset(pool, 0, sizeof(*pool));
63 pool->elements = kmalloc(min_nr * sizeof(void *), GFP_KERNEL); 69 pool->elements = kmalloc_node(min_nr * sizeof(void *),
70 GFP_KERNEL, node_id);
64 if (!pool->elements) { 71 if (!pool->elements) {
65 kfree(pool); 72 kfree(pool);
66 return NULL; 73 return NULL;
@@ -87,7 +94,7 @@ mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
87 } 94 }
88 return pool; 95 return pool;
89} 96}
90EXPORT_SYMBOL(mempool_create); 97EXPORT_SYMBOL(mempool_create_node);
91 98
92/** 99/**
93 * mempool_resize - resize an existing memory pool 100 * mempool_resize - resize an existing memory pool
@@ -197,7 +204,7 @@ void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask)
197{ 204{
198 void *element; 205 void *element;
199 unsigned long flags; 206 unsigned long flags;
200 DEFINE_WAIT(wait); 207 wait_queue_t wait;
201 int gfp_temp; 208 int gfp_temp;
202 209
203 might_sleep_if(gfp_mask & __GFP_WAIT); 210 might_sleep_if(gfp_mask & __GFP_WAIT);
@@ -228,6 +235,7 @@ repeat_alloc:
228 235
229 /* Now start performing page reclaim */ 236 /* Now start performing page reclaim */
230 gfp_temp = gfp_mask; 237 gfp_temp = gfp_mask;
238 init_wait(&wait);
231 prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE); 239 prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
232 smp_mb(); 240 smp_mb();
233 if (!pool->curr_nr) 241 if (!pool->curr_nr)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 559336de9687..7ee675ad101e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(nr_swap_pages);
68 * Used by page_zone() to look up the address of the struct zone whose 68 * Used by page_zone() to look up the address of the struct zone whose
69 * id is encoded in the upper bits of page->flags 69 * id is encoded in the upper bits of page->flags
70 */ 70 */
71struct zone *zone_table[1 << (ZONES_SHIFT + NODES_SHIFT)]; 71struct zone *zone_table[1 << ZONETABLE_SHIFT];
72EXPORT_SYMBOL(zone_table); 72EXPORT_SYMBOL(zone_table);
73 73
74static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" }; 74static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
@@ -1649,11 +1649,17 @@ static void __init calculate_zone_totalpages(struct pglist_data *pgdat,
1649void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone, 1649void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
1650 unsigned long start_pfn) 1650 unsigned long start_pfn)
1651{ 1651{
1652 struct page *start = pfn_to_page(start_pfn);
1653 struct page *page; 1652 struct page *page;
1653 unsigned long end_pfn = start_pfn + size;
1654 unsigned long pfn;
1654 1655
1655 for (page = start; page < (start + size); page++) { 1656 for (pfn = start_pfn; pfn < end_pfn; pfn++, page++) {
1656 set_page_zone(page, NODEZONE(nid, zone)); 1657 if (!early_pfn_valid(pfn))
1658 continue;
1659 if (!early_pfn_in_nid(pfn, nid))
1660 continue;
1661 page = pfn_to_page(pfn);
1662 set_page_links(page, zone, nid, pfn);
1657 set_page_count(page, 0); 1663 set_page_count(page, 0);
1658 reset_page_mapcount(page); 1664 reset_page_mapcount(page);
1659 SetPageReserved(page); 1665 SetPageReserved(page);
@@ -1677,6 +1683,20 @@ void zone_init_free_lists(struct pglist_data *pgdat, struct zone *zone,
1677 } 1683 }
1678} 1684}
1679 1685
1686#define ZONETABLE_INDEX(x, zone_nr) ((x << ZONES_SHIFT) | zone_nr)
1687void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
1688 unsigned long size)
1689{
1690 unsigned long snum = pfn_to_section_nr(pfn);
1691 unsigned long end = pfn_to_section_nr(pfn + size);
1692
1693 if (FLAGS_HAS_NODE)
1694 zone_table[ZONETABLE_INDEX(nid, zid)] = zone;
1695 else
1696 for (; snum <= end; snum++)
1697 zone_table[ZONETABLE_INDEX(snum, zid)] = zone;
1698}
1699
1680#ifndef __HAVE_ARCH_MEMMAP_INIT 1700#ifndef __HAVE_ARCH_MEMMAP_INIT
1681#define memmap_init(size, nid, zone, start_pfn) \ 1701#define memmap_init(size, nid, zone, start_pfn) \
1682 memmap_init_zone((size), (nid), (zone), (start_pfn)) 1702 memmap_init_zone((size), (nid), (zone), (start_pfn))
@@ -1861,7 +1881,6 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
1861 unsigned long size, realsize; 1881 unsigned long size, realsize;
1862 unsigned long batch; 1882 unsigned long batch;
1863 1883
1864 zone_table[NODEZONE(nid, j)] = zone;
1865 realsize = size = zones_size[j]; 1884 realsize = size = zones_size[j];
1866 if (zholes_size) 1885 if (zholes_size)
1867 realsize -= zholes_size[j]; 1886 realsize -= zholes_size[j];
@@ -1927,6 +1946,8 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
1927 1946
1928 memmap_init(size, nid, j, zone_start_pfn); 1947 memmap_init(size, nid, j, zone_start_pfn);
1929 1948
1949 zonetable_add(zone, nid, j, zone_start_pfn, size);
1950
1930 zone_start_pfn += size; 1951 zone_start_pfn += size;
1931 1952
1932 zone_init_free_lists(pgdat, zone, zone->spanned_pages); 1953 zone_init_free_lists(pgdat, zone, zone->spanned_pages);
@@ -1935,24 +1956,30 @@ static void __init free_area_init_core(struct pglist_data *pgdat,
1935 1956
1936static void __init alloc_node_mem_map(struct pglist_data *pgdat) 1957static void __init alloc_node_mem_map(struct pglist_data *pgdat)
1937{ 1958{
1938 unsigned long size;
1939
1940 /* Skip empty nodes */ 1959 /* Skip empty nodes */
1941 if (!pgdat->node_spanned_pages) 1960 if (!pgdat->node_spanned_pages)
1942 return; 1961 return;
1943 1962
1963#ifdef CONFIG_FLAT_NODE_MEM_MAP
1944 /* ia64 gets its own node_mem_map, before this, without bootmem */ 1964 /* ia64 gets its own node_mem_map, before this, without bootmem */
1945 if (!pgdat->node_mem_map) { 1965 if (!pgdat->node_mem_map) {
1966 unsigned long size;
1967 struct page *map;
1968
1946 size = (pgdat->node_spanned_pages + 1) * sizeof(struct page); 1969 size = (pgdat->node_spanned_pages + 1) * sizeof(struct page);
1947 pgdat->node_mem_map = alloc_bootmem_node(pgdat, size); 1970 map = alloc_remap(pgdat->node_id, size);
1971 if (!map)
1972 map = alloc_bootmem_node(pgdat, size);
1973 pgdat->node_mem_map = map;
1948 } 1974 }
1949#ifndef CONFIG_DISCONTIGMEM 1975#ifdef CONFIG_FLATMEM
1950 /* 1976 /*
1951 * With no DISCONTIG, the global mem_map is just set as node 0's 1977 * With no DISCONTIG, the global mem_map is just set as node 0's
1952 */ 1978 */
1953 if (pgdat == NODE_DATA(0)) 1979 if (pgdat == NODE_DATA(0))
1954 mem_map = NODE_DATA(0)->node_mem_map; 1980 mem_map = NODE_DATA(0)->node_mem_map;
1955#endif 1981#endif
1982#endif /* CONFIG_FLAT_NODE_MEM_MAP */
1956} 1983}
1957 1984
1958void __init free_area_init_node(int nid, struct pglist_data *pgdat, 1985void __init free_area_init_node(int nid, struct pglist_data *pgdat,
@@ -1968,18 +1995,18 @@ void __init free_area_init_node(int nid, struct pglist_data *pgdat,
1968 free_area_init_core(pgdat, zones_size, zholes_size); 1995 free_area_init_core(pgdat, zones_size, zholes_size);
1969} 1996}
1970 1997
1971#ifndef CONFIG_DISCONTIGMEM 1998#ifndef CONFIG_NEED_MULTIPLE_NODES
1972static bootmem_data_t contig_bootmem_data; 1999static bootmem_data_t contig_bootmem_data;
1973struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data }; 2000struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data };
1974 2001
1975EXPORT_SYMBOL(contig_page_data); 2002EXPORT_SYMBOL(contig_page_data);
2003#endif
1976 2004
1977void __init free_area_init(unsigned long *zones_size) 2005void __init free_area_init(unsigned long *zones_size)
1978{ 2006{
1979 free_area_init_node(0, &contig_page_data, zones_size, 2007 free_area_init_node(0, NODE_DATA(0), zones_size,
1980 __pa(PAGE_OFFSET) >> PAGE_SHIFT, NULL); 2008 __pa(PAGE_OFFSET) >> PAGE_SHIFT, NULL);
1981} 2009}
1982#endif
1983 2010
1984#ifdef CONFIG_PROC_FS 2011#ifdef CONFIG_PROC_FS
1985 2012
diff --git a/mm/rmap.c b/mm/rmap.c
index 89770bd25f31..08ac5c7fa91f 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -247,8 +247,8 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
247 * 247 *
248 * On success returns with mapped pte and locked mm->page_table_lock. 248 * On success returns with mapped pte and locked mm->page_table_lock.
249 */ 249 */
250static pte_t *page_check_address(struct page *page, struct mm_struct *mm, 250pte_t *page_check_address(struct page *page, struct mm_struct *mm,
251 unsigned long address) 251 unsigned long address)
252{ 252{
253 pgd_t *pgd; 253 pgd_t *pgd;
254 pud_t *pud; 254 pud_t *pud;
diff --git a/mm/slab.c b/mm/slab.c
index 93cbbbb39f42..122d031baab2 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -92,6 +92,7 @@
92#include <linux/sysctl.h> 92#include <linux/sysctl.h>
93#include <linux/module.h> 93#include <linux/module.h>
94#include <linux/rcupdate.h> 94#include <linux/rcupdate.h>
95#include <linux/string.h>
95 96
96#include <asm/uaccess.h> 97#include <asm/uaccess.h>
97#include <asm/cacheflush.h> 98#include <asm/cacheflush.h>
@@ -3082,3 +3083,26 @@ unsigned int ksize(const void *objp)
3082 3083
3083 return size; 3084 return size;
3084} 3085}
3086
3087
3088/*
3089 * kstrdup - allocate space for and copy an existing string
3090 *
3091 * @s: the string to duplicate
3092 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
3093 */
3094char *kstrdup(const char *s, int gfp)
3095{
3096 size_t len;
3097 char *buf;
3098
3099 if (!s)
3100 return NULL;
3101
3102 len = strlen(s) + 1;
3103 buf = kmalloc(len, gfp);
3104 if (buf)
3105 memcpy(buf, s, len);
3106 return buf;
3107}
3108EXPORT_SYMBOL(kstrdup);
diff --git a/mm/sparse.c b/mm/sparse.c
new file mode 100644
index 000000000000..b54e304df4a7
--- /dev/null
+++ b/mm/sparse.c
@@ -0,0 +1,137 @@
1/*
2 * sparse memory mappings.
3 */
4#include <linux/config.h>
5#include <linux/mm.h>
6#include <linux/mmzone.h>
7#include <linux/bootmem.h>
8#include <linux/module.h>
9#include <asm/dma.h>
10
11/*
12 * Permanent SPARSEMEM data:
13 *
14 * 1) mem_section - memory sections, mem_map's for valid memory
15 */
16struct mem_section mem_section[NR_MEM_SECTIONS];
17EXPORT_SYMBOL(mem_section);
18
19/* Record a memory area against a node. */
20void memory_present(int nid, unsigned long start, unsigned long end)
21{
22 unsigned long pfn;
23
24 start &= PAGE_SECTION_MASK;
25 for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
26 unsigned long section = pfn_to_section_nr(pfn);
27 if (!mem_section[section].section_mem_map)
28 mem_section[section].section_mem_map = SECTION_MARKED_PRESENT;
29 }
30}
31
32/*
33 * Only used by the i386 NUMA architecures, but relatively
34 * generic code.
35 */
36unsigned long __init node_memmap_size_bytes(int nid, unsigned long start_pfn,
37 unsigned long end_pfn)
38{
39 unsigned long pfn;
40 unsigned long nr_pages = 0;
41
42 for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
43 if (nid != early_pfn_to_nid(pfn))
44 continue;
45
46 if (pfn_valid(pfn))
47 nr_pages += PAGES_PER_SECTION;
48 }
49
50 return nr_pages * sizeof(struct page);
51}
52
53/*
54 * Subtle, we encode the real pfn into the mem_map such that
55 * the identity pfn - section_mem_map will return the actual
56 * physical page frame number.
57 */
58static unsigned long sparse_encode_mem_map(struct page *mem_map, unsigned long pnum)
59{
60 return (unsigned long)(mem_map - (section_nr_to_pfn(pnum)));
61}
62
63/*
64 * We need this if we ever free the mem_maps. While not implemented yet,
65 * this function is included for parity with its sibling.
66 */
67static __attribute((unused))
68struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pnum)
69{
70 return ((struct page *)coded_mem_map) + section_nr_to_pfn(pnum);
71}
72
73static int sparse_init_one_section(struct mem_section *ms,
74 unsigned long pnum, struct page *mem_map)
75{
76 if (!valid_section(ms))
77 return -EINVAL;
78
79 ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum);
80
81 return 1;
82}
83
84static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
85{
86 struct page *map;
87 int nid = early_pfn_to_nid(section_nr_to_pfn(pnum));
88
89 map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION);
90 if (map)
91 return map;
92
93 map = alloc_bootmem_node(NODE_DATA(nid),
94 sizeof(struct page) * PAGES_PER_SECTION);
95 if (map)
96 return map;
97
98 printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__);
99 mem_section[pnum].section_mem_map = 0;
100 return NULL;
101}
102
103/*
104 * Allocate the accumulated non-linear sections, allocate a mem_map
105 * for each and record the physical to section mapping.
106 */
107void sparse_init(void)
108{
109 unsigned long pnum;
110 struct page *map;
111
112 for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
113 if (!valid_section_nr(pnum))
114 continue;
115
116 map = sparse_early_mem_map_alloc(pnum);
117 if (map)
118 sparse_init_one_section(&mem_section[pnum], pnum, map);
119 }
120}
121
122/*
123 * returns the number of sections whose mem_maps were properly
124 * set. If this is <=0, then that means that the passed-in
125 * map was not consumed and must be freed.
126 */
127int sparse_add_one_section(unsigned long start_pfn, int nr_pages, struct page *map)
128{
129 struct mem_section *ms = __pfn_to_section(start_pfn);
130
131 if (ms->section_mem_map & SECTION_MARKED_PRESENT)
132 return -EEXIST;
133
134 ms->section_mem_map |= SECTION_MARKED_PRESENT;
135
136 return sparse_init_one_section(ms, pfn_to_section_nr(start_pfn), map);
137}
diff --git a/net/core/dev.c b/net/core/dev.c
index ab935778ce81..7016e0c36b3d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -115,18 +115,6 @@
115#endif /* CONFIG_NET_RADIO */ 115#endif /* CONFIG_NET_RADIO */
116#include <asm/current.h> 116#include <asm/current.h>
117 117
118/* This define, if set, will randomly drop a packet when congestion
119 * is more than moderate. It helps fairness in the multi-interface
120 * case when one of them is a hog, but it kills performance for the
121 * single interface case so it is off now by default.
122 */
123#undef RAND_LIE
124
125/* Setting this will sample the queue lengths and thus congestion
126 * via a timer instead of as each packet is received.
127 */
128#undef OFFLINE_SAMPLE
129
130/* 118/*
131 * The list of packet types we will receive (as opposed to discard) 119 * The list of packet types we will receive (as opposed to discard)
132 * and the routines to invoke. 120 * and the routines to invoke.
@@ -159,11 +147,6 @@ static DEFINE_SPINLOCK(ptype_lock);
159static struct list_head ptype_base[16]; /* 16 way hashed list */ 147static struct list_head ptype_base[16]; /* 16 way hashed list */
160static struct list_head ptype_all; /* Taps */ 148static struct list_head ptype_all; /* Taps */
161 149
162#ifdef OFFLINE_SAMPLE
163static void sample_queue(unsigned long dummy);
164static struct timer_list samp_timer = TIMER_INITIALIZER(sample_queue, 0, 0);
165#endif
166
167/* 150/*
168 * The @dev_base list is protected by @dev_base_lock and the rtln 151 * The @dev_base list is protected by @dev_base_lock and the rtln
169 * semaphore. 152 * semaphore.
@@ -215,7 +198,7 @@ static struct notifier_block *netdev_chain;
215 * Device drivers call our routines to queue packets here. We empty the 198 * Device drivers call our routines to queue packets here. We empty the
216 * queue in the local softnet handler. 199 * queue in the local softnet handler.
217 */ 200 */
218DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, }; 201DEFINE_PER_CPU(struct softnet_data, softnet_data) = { NULL };
219 202
220#ifdef CONFIG_SYSFS 203#ifdef CONFIG_SYSFS
221extern int netdev_sysfs_init(void); 204extern int netdev_sysfs_init(void);
@@ -1363,71 +1346,13 @@ out:
1363 Receiver routines 1346 Receiver routines
1364 =======================================================================*/ 1347 =======================================================================*/
1365 1348
1366int netdev_max_backlog = 300; 1349int netdev_max_backlog = 1000;
1350int netdev_budget = 300;
1367int weight_p = 64; /* old backlog weight */ 1351int weight_p = 64; /* old backlog weight */
1368/* These numbers are selected based on intuition and some
1369 * experimentatiom, if you have more scientific way of doing this
1370 * please go ahead and fix things.
1371 */
1372int no_cong_thresh = 10;
1373int no_cong = 20;
1374int lo_cong = 100;
1375int mod_cong = 290;
1376 1352
1377DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; 1353DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
1378 1354
1379 1355
1380static void get_sample_stats(int cpu)
1381{
1382#ifdef RAND_LIE
1383 unsigned long rd;
1384 int rq;
1385#endif
1386 struct softnet_data *sd = &per_cpu(softnet_data, cpu);
1387 int blog = sd->input_pkt_queue.qlen;
1388 int avg_blog = sd->avg_blog;
1389
1390 avg_blog = (avg_blog >> 1) + (blog >> 1);
1391
1392 if (avg_blog > mod_cong) {
1393 /* Above moderate congestion levels. */
1394 sd->cng_level = NET_RX_CN_HIGH;
1395#ifdef RAND_LIE
1396 rd = net_random();
1397 rq = rd % netdev_max_backlog;
1398 if (rq < avg_blog) /* unlucky bastard */
1399 sd->cng_level = NET_RX_DROP;
1400#endif
1401 } else if (avg_blog > lo_cong) {
1402 sd->cng_level = NET_RX_CN_MOD;
1403#ifdef RAND_LIE
1404 rd = net_random();
1405 rq = rd % netdev_max_backlog;
1406 if (rq < avg_blog) /* unlucky bastard */
1407 sd->cng_level = NET_RX_CN_HIGH;
1408#endif
1409 } else if (avg_blog > no_cong)
1410 sd->cng_level = NET_RX_CN_LOW;
1411 else /* no congestion */
1412 sd->cng_level = NET_RX_SUCCESS;
1413
1414 sd->avg_blog = avg_blog;
1415}
1416
1417#ifdef OFFLINE_SAMPLE
1418static void sample_queue(unsigned long dummy)
1419{
1420/* 10 ms 0r 1ms -- i don't care -- JHS */
1421 int next_tick = 1;
1422 int cpu = smp_processor_id();
1423
1424 get_sample_stats(cpu);
1425 next_tick += jiffies;
1426 mod_timer(&samp_timer, next_tick);
1427}
1428#endif
1429
1430
1431/** 1356/**
1432 * netif_rx - post buffer to the network code 1357 * netif_rx - post buffer to the network code
1433 * @skb: buffer to post 1358 * @skb: buffer to post
@@ -1448,7 +1373,6 @@ static void sample_queue(unsigned long dummy)
1448 1373
1449int netif_rx(struct sk_buff *skb) 1374int netif_rx(struct sk_buff *skb)
1450{ 1375{
1451 int this_cpu;
1452 struct softnet_data *queue; 1376 struct softnet_data *queue;
1453 unsigned long flags; 1377 unsigned long flags;
1454 1378
@@ -1464,38 +1388,22 @@ int netif_rx(struct sk_buff *skb)
1464 * short when CPU is congested, but is still operating. 1388 * short when CPU is congested, but is still operating.
1465 */ 1389 */
1466 local_irq_save(flags); 1390 local_irq_save(flags);
1467 this_cpu = smp_processor_id();
1468 queue = &__get_cpu_var(softnet_data); 1391 queue = &__get_cpu_var(softnet_data);
1469 1392
1470 __get_cpu_var(netdev_rx_stat).total++; 1393 __get_cpu_var(netdev_rx_stat).total++;
1471 if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { 1394 if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
1472 if (queue->input_pkt_queue.qlen) { 1395 if (queue->input_pkt_queue.qlen) {
1473 if (queue->throttle)
1474 goto drop;
1475
1476enqueue: 1396enqueue:
1477 dev_hold(skb->dev); 1397 dev_hold(skb->dev);
1478 __skb_queue_tail(&queue->input_pkt_queue, skb); 1398 __skb_queue_tail(&queue->input_pkt_queue, skb);
1479#ifndef OFFLINE_SAMPLE
1480 get_sample_stats(this_cpu);
1481#endif
1482 local_irq_restore(flags); 1399 local_irq_restore(flags);
1483 return queue->cng_level; 1400 return NET_RX_SUCCESS;
1484 } 1401 }
1485 1402
1486 if (queue->throttle)
1487 queue->throttle = 0;
1488
1489 netif_rx_schedule(&queue->backlog_dev); 1403 netif_rx_schedule(&queue->backlog_dev);
1490 goto enqueue; 1404 goto enqueue;
1491 } 1405 }
1492 1406
1493 if (!queue->throttle) {
1494 queue->throttle = 1;
1495 __get_cpu_var(netdev_rx_stat).throttled++;
1496 }
1497
1498drop:
1499 __get_cpu_var(netdev_rx_stat).dropped++; 1407 __get_cpu_var(netdev_rx_stat).dropped++;
1500 local_irq_restore(flags); 1408 local_irq_restore(flags);
1501 1409
@@ -1780,8 +1688,6 @@ job_done:
1780 smp_mb__before_clear_bit(); 1688 smp_mb__before_clear_bit();
1781 netif_poll_enable(backlog_dev); 1689 netif_poll_enable(backlog_dev);
1782 1690
1783 if (queue->throttle)
1784 queue->throttle = 0;
1785 local_irq_enable(); 1691 local_irq_enable();
1786 return 0; 1692 return 0;
1787} 1693}
@@ -1790,8 +1696,7 @@ static void net_rx_action(struct softirq_action *h)
1790{ 1696{
1791 struct softnet_data *queue = &__get_cpu_var(softnet_data); 1697 struct softnet_data *queue = &__get_cpu_var(softnet_data);
1792 unsigned long start_time = jiffies; 1698 unsigned long start_time = jiffies;
1793 int budget = netdev_max_backlog; 1699 int budget = netdev_budget;
1794
1795 1700
1796 local_irq_disable(); 1701 local_irq_disable();
1797 1702
@@ -2055,15 +1960,9 @@ static int softnet_seq_show(struct seq_file *seq, void *v)
2055 struct netif_rx_stats *s = v; 1960 struct netif_rx_stats *s = v;
2056 1961
2057 seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", 1962 seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
2058 s->total, s->dropped, s->time_squeeze, s->throttled, 1963 s->total, s->dropped, s->time_squeeze, 0,
2059 s->fastroute_hit, s->fastroute_success, s->fastroute_defer, 1964 0, 0, 0, 0, /* was fastroute */
2060 s->fastroute_deferred_out, 1965 s->cpu_collision );
2061#if 0
2062 s->fastroute_latency_reduction
2063#else
2064 s->cpu_collision
2065#endif
2066 );
2067 return 0; 1966 return 0;
2068} 1967}
2069 1968
@@ -3305,9 +3204,6 @@ static int __init net_dev_init(void)
3305 3204
3306 queue = &per_cpu(softnet_data, i); 3205 queue = &per_cpu(softnet_data, i);
3307 skb_queue_head_init(&queue->input_pkt_queue); 3206 skb_queue_head_init(&queue->input_pkt_queue);
3308 queue->throttle = 0;
3309 queue->cng_level = 0;
3310 queue->avg_blog = 10; /* arbitrary non-zero */
3311 queue->completion_queue = NULL; 3207 queue->completion_queue = NULL;
3312 INIT_LIST_HEAD(&queue->poll_list); 3208 INIT_LIST_HEAD(&queue->poll_list);
3313 set_bit(__LINK_STATE_START, &queue->backlog_dev.state); 3209 set_bit(__LINK_STATE_START, &queue->backlog_dev.state);
@@ -3316,11 +3212,6 @@ static int __init net_dev_init(void)
3316 atomic_set(&queue->backlog_dev.refcnt, 1); 3212 atomic_set(&queue->backlog_dev.refcnt, 1);
3317 } 3213 }
3318 3214
3319#ifdef OFFLINE_SAMPLE
3320 samp_timer.expires = jiffies + (10 * HZ);
3321 add_timer(&samp_timer);
3322#endif
3323
3324 dev_boot_phase = 0; 3215 dev_boot_phase = 0;
3325 3216
3326 open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); 3217 open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index f6bdcad47da6..851eb927ed97 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -32,6 +32,7 @@
32#include <net/sock.h> 32#include <net/sock.h>
33#include <linux/rtnetlink.h> 33#include <linux/rtnetlink.h>
34#include <linux/random.h> 34#include <linux/random.h>
35#include <linux/string.h>
35 36
36#define NEIGH_DEBUG 1 37#define NEIGH_DEBUG 1
37 38
@@ -2592,7 +2593,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2592 t->neigh_vars[17].extra1 = dev; 2593 t->neigh_vars[17].extra1 = dev;
2593 } 2594 }
2594 2595
2595 dev_name = net_sysctl_strdup(dev_name_source); 2596 dev_name = kstrdup(dev_name_source, GFP_KERNEL);
2596 if (!dev_name) { 2597 if (!dev_name) {
2597 err = -ENOBUFS; 2598 err = -ENOBUFS;
2598 goto free; 2599 goto free;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 6d68c03bc051..bb73b2190ec7 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1500,6 +1500,159 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len)
1500 skb_split_no_header(skb, skb1, len, pos); 1500 skb_split_no_header(skb, skb1, len, pos);
1501} 1501}
1502 1502
1503/**
1504 * skb_prepare_seq_read - Prepare a sequential read of skb data
1505 * @skb: the buffer to read
1506 * @from: lower offset of data to be read
1507 * @to: upper offset of data to be read
1508 * @st: state variable
1509 *
1510 * Initializes the specified state variable. Must be called before
1511 * invoking skb_seq_read() for the first time.
1512 */
1513void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from,
1514 unsigned int to, struct skb_seq_state *st)
1515{
1516 st->lower_offset = from;
1517 st->upper_offset = to;
1518 st->root_skb = st->cur_skb = skb;
1519 st->frag_idx = st->stepped_offset = 0;
1520 st->frag_data = NULL;
1521}
1522
1523/**
1524 * skb_seq_read - Sequentially read skb data
1525 * @consumed: number of bytes consumed by the caller so far
1526 * @data: destination pointer for data to be returned
1527 * @st: state variable
1528 *
1529 * Reads a block of skb data at &consumed relative to the
1530 * lower offset specified to skb_prepare_seq_read(). Assigns
1531 * the head of the data block to &data and returns the length
1532 * of the block or 0 if the end of the skb data or the upper
1533 * offset has been reached.
1534 *
1535 * The caller is not required to consume all of the data
1536 * returned, i.e. &consumed is typically set to the number
1537 * of bytes already consumed and the next call to
1538 * skb_seq_read() will return the remaining part of the block.
1539 *
1540 * Note: The size of each block of data returned can be arbitary,
1541 * this limitation is the cost for zerocopy seqeuental
1542 * reads of potentially non linear data.
1543 *
1544 * Note: Fragment lists within fragments are not implemented
1545 * at the moment, state->root_skb could be replaced with
1546 * a stack for this purpose.
1547 */
1548unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
1549 struct skb_seq_state *st)
1550{
1551 unsigned int block_limit, abs_offset = consumed + st->lower_offset;
1552 skb_frag_t *frag;
1553
1554 if (unlikely(abs_offset >= st->upper_offset))
1555 return 0;
1556
1557next_skb:
1558 block_limit = skb_headlen(st->cur_skb);
1559
1560 if (abs_offset < block_limit) {
1561 *data = st->cur_skb->data + abs_offset;
1562 return block_limit - abs_offset;
1563 }
1564
1565 if (st->frag_idx == 0 && !st->frag_data)
1566 st->stepped_offset += skb_headlen(st->cur_skb);
1567
1568 while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) {
1569 frag = &skb_shinfo(st->cur_skb)->frags[st->frag_idx];
1570 block_limit = frag->size + st->stepped_offset;
1571
1572 if (abs_offset < block_limit) {
1573 if (!st->frag_data)
1574 st->frag_data = kmap_skb_frag(frag);
1575
1576 *data = (u8 *) st->frag_data + frag->page_offset +
1577 (abs_offset - st->stepped_offset);
1578
1579 return block_limit - abs_offset;
1580 }
1581
1582 if (st->frag_data) {
1583 kunmap_skb_frag(st->frag_data);
1584 st->frag_data = NULL;
1585 }
1586
1587 st->frag_idx++;
1588 st->stepped_offset += frag->size;
1589 }
1590
1591 if (st->cur_skb->next) {
1592 st->cur_skb = st->cur_skb->next;
1593 st->frag_idx = 0;
1594 goto next_skb;
1595 } else if (st->root_skb == st->cur_skb &&
1596 skb_shinfo(st->root_skb)->frag_list) {
1597 st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
1598 goto next_skb;
1599 }
1600
1601 return 0;
1602}
1603
1604/**
1605 * skb_abort_seq_read - Abort a sequential read of skb data
1606 * @st: state variable
1607 *
1608 * Must be called if skb_seq_read() was not called until it
1609 * returned 0.
1610 */
1611void skb_abort_seq_read(struct skb_seq_state *st)
1612{
1613 if (st->frag_data)
1614 kunmap_skb_frag(st->frag_data);
1615}
1616
1617#define TS_SKB_CB(state) ((struct skb_seq_state *) &((state)->cb))
1618
1619static unsigned int skb_ts_get_next_block(unsigned int offset, const u8 **text,
1620 struct ts_config *conf,
1621 struct ts_state *state)
1622{
1623 return skb_seq_read(offset, text, TS_SKB_CB(state));
1624}
1625
1626static void skb_ts_finish(struct ts_config *conf, struct ts_state *state)
1627{
1628 skb_abort_seq_read(TS_SKB_CB(state));
1629}
1630
1631/**
1632 * skb_find_text - Find a text pattern in skb data
1633 * @skb: the buffer to look in
1634 * @from: search offset
1635 * @to: search limit
1636 * @config: textsearch configuration
1637 * @state: uninitialized textsearch state variable
1638 *
1639 * Finds a pattern in the skb data according to the specified
1640 * textsearch configuration. Use textsearch_next() to retrieve
1641 * subsequent occurrences of the pattern. Returns the offset
1642 * to the first occurrence or UINT_MAX if no match was found.
1643 */
1644unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
1645 unsigned int to, struct ts_config *config,
1646 struct ts_state *state)
1647{
1648 config->get_next_block = skb_ts_get_next_block;
1649 config->finish = skb_ts_finish;
1650
1651 skb_prepare_seq_read(skb, from, to, TS_SKB_CB(state));
1652
1653 return textsearch_find(config, state);
1654}
1655
1503void __init skb_init(void) 1656void __init skb_init(void)
1504{ 1657{
1505 skbuff_head_cache = kmem_cache_create("skbuff_head_cache", 1658 skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
@@ -1538,3 +1691,7 @@ EXPORT_SYMBOL(skb_queue_tail);
1538EXPORT_SYMBOL(skb_unlink); 1691EXPORT_SYMBOL(skb_unlink);
1539EXPORT_SYMBOL(skb_append); 1692EXPORT_SYMBOL(skb_append);
1540EXPORT_SYMBOL(skb_split); 1693EXPORT_SYMBOL(skb_split);
1694EXPORT_SYMBOL(skb_prepare_seq_read);
1695EXPORT_SYMBOL(skb_seq_read);
1696EXPORT_SYMBOL(skb_abort_seq_read);
1697EXPORT_SYMBOL(skb_find_text);
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index c8be646cb191..8f817ad9f546 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -13,12 +13,8 @@
13#ifdef CONFIG_SYSCTL 13#ifdef CONFIG_SYSCTL
14 14
15extern int netdev_max_backlog; 15extern int netdev_max_backlog;
16extern int netdev_budget;
16extern int weight_p; 17extern int weight_p;
17extern int no_cong_thresh;
18extern int no_cong;
19extern int lo_cong;
20extern int mod_cong;
21extern int netdev_fastroute;
22extern int net_msg_cost; 18extern int net_msg_cost;
23extern int net_msg_burst; 19extern int net_msg_burst;
24 20
@@ -35,19 +31,6 @@ extern int sysctl_somaxconn;
35extern char sysctl_divert_version[]; 31extern char sysctl_divert_version[];
36#endif /* CONFIG_NET_DIVERT */ 32#endif /* CONFIG_NET_DIVERT */
37 33
38/*
39 * This strdup() is used for creating copies of network
40 * device names to be handed over to sysctl.
41 */
42
43char *net_sysctl_strdup(const char *s)
44{
45 char *rv = kmalloc(strlen(s)+1, GFP_KERNEL);
46 if (rv)
47 strcpy(rv, s);
48 return rv;
49}
50
51ctl_table core_table[] = { 34ctl_table core_table[] = {
52#ifdef CONFIG_NET 35#ifdef CONFIG_NET
53 { 36 {
@@ -99,38 +82,6 @@ ctl_table core_table[] = {
99 .proc_handler = &proc_dointvec 82 .proc_handler = &proc_dointvec
100 }, 83 },
101 { 84 {
102 .ctl_name = NET_CORE_NO_CONG_THRESH,
103 .procname = "no_cong_thresh",
104 .data = &no_cong_thresh,
105 .maxlen = sizeof(int),
106 .mode = 0644,
107 .proc_handler = &proc_dointvec
108 },
109 {
110 .ctl_name = NET_CORE_NO_CONG,
111 .procname = "no_cong",
112 .data = &no_cong,
113 .maxlen = sizeof(int),
114 .mode = 0644,
115 .proc_handler = &proc_dointvec
116 },
117 {
118 .ctl_name = NET_CORE_LO_CONG,
119 .procname = "lo_cong",
120 .data = &lo_cong,
121 .maxlen = sizeof(int),
122 .mode = 0644,
123 .proc_handler = &proc_dointvec
124 },
125 {
126 .ctl_name = NET_CORE_MOD_CONG,
127 .procname = "mod_cong",
128 .data = &mod_cong,
129 .maxlen = sizeof(int),
130 .mode = 0644,
131 .proc_handler = &proc_dointvec
132 },
133 {
134 .ctl_name = NET_CORE_MSG_COST, 85 .ctl_name = NET_CORE_MSG_COST,
135 .procname = "message_cost", 86 .procname = "message_cost",
136 .data = &net_msg_cost, 87 .data = &net_msg_cost,
@@ -174,9 +125,15 @@ ctl_table core_table[] = {
174 .mode = 0644, 125 .mode = 0644,
175 .proc_handler = &proc_dointvec 126 .proc_handler = &proc_dointvec
176 }, 127 },
128 {
129 .ctl_name = NET_CORE_BUDGET,
130 .procname = "netdev_budget",
131 .data = &netdev_budget,
132 .maxlen = sizeof(int),
133 .mode = 0644,
134 .proc_handler = &proc_dointvec
135 },
177 { .ctl_name = 0 } 136 { .ctl_name = 0 }
178}; 137};
179 138
180EXPORT_SYMBOL(net_sysctl_strdup);
181
182#endif 139#endif
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 567b03b1c349..690e88ba2484 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -433,5 +433,95 @@ config IP_TCPDIAG
433config IP_TCPDIAG_IPV6 433config IP_TCPDIAG_IPV6
434 def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6) 434 def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6)
435 435
436# TCP Reno is builtin (required as fallback)
437menu "TCP congestion control"
438 depends on INET
439
440config TCP_CONG_BIC
441 tristate "Binary Increase Congestion (BIC) control"
442 depends on INET
443 default y
444 ---help---
445 BIC-TCP is a sender-side only change that ensures a linear RTT
446 fairness under large windows while offering both scalability and
447 bounded TCP-friendliness. The protocol combines two schemes
448 called additive increase and binary search increase. When the
449 congestion window is large, additive increase with a large
450 increment ensures linear RTT fairness as well as good
451 scalability. Under small congestion windows, binary search
452 increase provides TCP friendliness.
453 See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/
454
455config TCP_CONG_WESTWOOD
456 tristate "TCP Westwood+"
457 depends on INET
458 default m
459 ---help---
460 TCP Westwood+ is a sender-side only modification of the TCP Reno
461 protocol stack that optimizes the performance of TCP congestion
462 control. It is based on end-to-end bandwidth estimation to set
463 congestion window and slow start threshold after a congestion
464 episode. Using this estimation, TCP Westwood+ adaptively sets a
465 slow start threshold and a congestion window which takes into
466 account the bandwidth used at the time congestion is experienced.
467 TCP Westwood+ significantly increases fairness wrt TCP Reno in
468 wired networks and throughput over wireless links.
469
470config TCP_CONG_HTCP
471 tristate "H-TCP"
472 depends on INET
473 default m
474 ---help---
475 H-TCP is a send-side only modifications of the TCP Reno
476 protocol stack that optimizes the performance of TCP
477 congestion control for high speed network links. It uses a
478 modeswitch to change the alpha and beta parameters of TCP Reno
479 based on network conditions and in a way so as to be fair with
480 other Reno and H-TCP flows.
481
482config TCP_CONG_HSTCP
483 tristate "High Speed TCP"
484 depends on INET && EXPERIMENTAL
485 default n
486 ---help---
487 Sally Floyd's High Speed TCP (RFC 3649) congestion control.
488 A modification to TCP's congestion control mechanism for use
489 with large congestion windows. A table indicates how much to
490 increase the congestion window by when an ACK is received.
491 For more detail see http://www.icir.org/floyd/hstcp.html
492
493config TCP_CONG_HYBLA
494 tristate "TCP-Hybla congestion control algorithm"
495 depends on INET && EXPERIMENTAL
496 default n
497 ---help---
498 TCP-Hybla is a sender-side only change that eliminates penalization of
499 long-RTT, large-bandwidth connections, like when satellite legs are
500 involved, expecially when sharing a common bottleneck with normal
501 terrestrial connections.
502
503config TCP_CONG_VEGAS
504 tristate "TCP Vegas"
505 depends on INET && EXPERIMENTAL
506 default n
507 ---help---
508 TCP Vegas is a sender-side only change to TCP that anticipates
509 the onset of congestion by estimating the bandwidth. TCP Vegas
510 adjusts the sending rate by modifying the congestion
511 window. TCP Vegas should provide less packet loss, but it is
512 not as aggressive as TCP Reno.
513
514config TCP_CONG_SCALABLE
515 tristate "Scalable TCP"
516 depends on INET && EXPERIMENTAL
517 default n
518 ---help---
519 Scalable TCP is a sender-side only change to TCP which uses a
520 MIMD congestion control algorithm which has some nice scaling
521 properties, though is known to have fairness issues.
522 See http://www-lce.eng.cam.ac.uk/~ctk21/scalable/
523
524endmenu
525
436source "net/ipv4/ipvs/Kconfig" 526source "net/ipv4/ipvs/Kconfig"
437 527
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 65d57d8e1add..5718cdb3a61e 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -5,7 +5,8 @@
5obj-y := utils.o route.o inetpeer.o protocol.o \ 5obj-y := utils.o route.o inetpeer.o protocol.o \
6 ip_input.o ip_fragment.o ip_forward.o ip_options.o \ 6 ip_input.o ip_fragment.o ip_forward.o ip_options.o \
7 ip_output.o ip_sockglue.o \ 7 ip_output.o ip_sockglue.o \
8 tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \ 8 tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
9 tcp_minisocks.o tcp_cong.o \
9 datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \ 10 datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \
10 sysctl_net_ipv4.o fib_frontend.o fib_semantics.o 11 sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
11 12
@@ -30,6 +31,13 @@ obj-$(CONFIG_NETFILTER) += netfilter/
30obj-$(CONFIG_IP_VS) += ipvs/ 31obj-$(CONFIG_IP_VS) += ipvs/
31obj-$(CONFIG_IP_TCPDIAG) += tcp_diag.o 32obj-$(CONFIG_IP_TCPDIAG) += tcp_diag.o
32obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o 33obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
34obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
35obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o
36obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o
37obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o
38obj-$(CONFIG_TCP_CONG_HTCP) += tcp_htcp.o
39obj-$(CONFIG_TCP_CONG_VEGAS) += tcp_vegas.o
40obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
33 41
34obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \ 42obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
35 xfrm4_output.o 43 xfrm4_output.o
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 650dcb12d9a1..d8a10e3dd77d 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1471,7 +1471,7 @@ static void devinet_sysctl_register(struct in_device *in_dev,
1471 * by sysctl and we wouldn't want anyone to change it under our feet 1471 * by sysctl and we wouldn't want anyone to change it under our feet
1472 * (see SIOCSIFNAME). 1472 * (see SIOCSIFNAME).
1473 */ 1473 */
1474 dev_name = net_sysctl_strdup(dev_name); 1474 dev_name = kstrdup(dev_name, GFP_KERNEL);
1475 if (!dev_name) 1475 if (!dev_name)
1476 goto free; 1476 goto free;
1477 1477
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 23068bddbf0b..e32894532416 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -118,6 +118,45 @@ static int ipv4_sysctl_forward_strategy(ctl_table *table,
118 return 1; 118 return 1;
119} 119}
120 120
121static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * filp,
122 void __user *buffer, size_t *lenp, loff_t *ppos)
123{
124 char val[TCP_CA_NAME_MAX];
125 ctl_table tbl = {
126 .data = val,
127 .maxlen = TCP_CA_NAME_MAX,
128 };
129 int ret;
130
131 tcp_get_default_congestion_control(val);
132
133 ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos);
134 if (write && ret == 0)
135 ret = tcp_set_default_congestion_control(val);
136 return ret;
137}
138
139int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, int nlen,
140 void __user *oldval, size_t __user *oldlenp,
141 void __user *newval, size_t newlen,
142 void **context)
143{
144 char val[TCP_CA_NAME_MAX];
145 ctl_table tbl = {
146 .data = val,
147 .maxlen = TCP_CA_NAME_MAX,
148 };
149 int ret;
150
151 tcp_get_default_congestion_control(val);
152 ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen,
153 context);
154 if (ret == 0 && newval && newlen)
155 ret = tcp_set_default_congestion_control(val);
156 return ret;
157}
158
159
121ctl_table ipv4_table[] = { 160ctl_table ipv4_table[] = {
122 { 161 {
123 .ctl_name = NET_IPV4_TCP_TIMESTAMPS, 162 .ctl_name = NET_IPV4_TCP_TIMESTAMPS,
@@ -612,70 +651,6 @@ ctl_table ipv4_table[] = {
612 .proc_handler = &proc_dointvec, 651 .proc_handler = &proc_dointvec,
613 }, 652 },
614 { 653 {
615 .ctl_name = NET_TCP_WESTWOOD,
616 .procname = "tcp_westwood",
617 .data = &sysctl_tcp_westwood,
618 .maxlen = sizeof(int),
619 .mode = 0644,
620 .proc_handler = &proc_dointvec,
621 },
622 {
623 .ctl_name = NET_TCP_VEGAS,
624 .procname = "tcp_vegas_cong_avoid",
625 .data = &sysctl_tcp_vegas_cong_avoid,
626 .maxlen = sizeof(int),
627 .mode = 0644,
628 .proc_handler = &proc_dointvec,
629 },
630 {
631 .ctl_name = NET_TCP_VEGAS_ALPHA,
632 .procname = "tcp_vegas_alpha",
633 .data = &sysctl_tcp_vegas_alpha,
634 .maxlen = sizeof(int),
635 .mode = 0644,
636 .proc_handler = &proc_dointvec,
637 },
638 {
639 .ctl_name = NET_TCP_VEGAS_BETA,
640 .procname = "tcp_vegas_beta",
641 .data = &sysctl_tcp_vegas_beta,
642 .maxlen = sizeof(int),
643 .mode = 0644,
644 .proc_handler = &proc_dointvec,
645 },
646 {
647 .ctl_name = NET_TCP_VEGAS_GAMMA,
648 .procname = "tcp_vegas_gamma",
649 .data = &sysctl_tcp_vegas_gamma,
650 .maxlen = sizeof(int),
651 .mode = 0644,
652 .proc_handler = &proc_dointvec,
653 },
654 {
655 .ctl_name = NET_TCP_BIC,
656 .procname = "tcp_bic",
657 .data = &sysctl_tcp_bic,
658 .maxlen = sizeof(int),
659 .mode = 0644,
660 .proc_handler = &proc_dointvec,
661 },
662 {
663 .ctl_name = NET_TCP_BIC_FAST_CONVERGENCE,
664 .procname = "tcp_bic_fast_convergence",
665 .data = &sysctl_tcp_bic_fast_convergence,
666 .maxlen = sizeof(int),
667 .mode = 0644,
668 .proc_handler = &proc_dointvec,
669 },
670 {
671 .ctl_name = NET_TCP_BIC_LOW_WINDOW,
672 .procname = "tcp_bic_low_window",
673 .data = &sysctl_tcp_bic_low_window,
674 .maxlen = sizeof(int),
675 .mode = 0644,
676 .proc_handler = &proc_dointvec,
677 },
678 {
679 .ctl_name = NET_TCP_MODERATE_RCVBUF, 654 .ctl_name = NET_TCP_MODERATE_RCVBUF,
680 .procname = "tcp_moderate_rcvbuf", 655 .procname = "tcp_moderate_rcvbuf",
681 .data = &sysctl_tcp_moderate_rcvbuf, 656 .data = &sysctl_tcp_moderate_rcvbuf,
@@ -692,13 +667,14 @@ ctl_table ipv4_table[] = {
692 .proc_handler = &proc_dointvec, 667 .proc_handler = &proc_dointvec,
693 }, 668 },
694 { 669 {
695 .ctl_name = NET_TCP_BIC_BETA, 670 .ctl_name = NET_TCP_CONG_CONTROL,
696 .procname = "tcp_bic_beta", 671 .procname = "tcp_congestion_control",
697 .data = &sysctl_tcp_bic_beta,
698 .maxlen = sizeof(int),
699 .mode = 0644, 672 .mode = 0644,
700 .proc_handler = &proc_dointvec, 673 .maxlen = TCP_CA_NAME_MAX,
674 .proc_handler = &proc_tcp_congestion_control,
675 .strategy = &sysctl_tcp_congestion_control,
701 }, 676 },
677
702 { .ctl_name = 0 } 678 { .ctl_name = 0 }
703}; 679};
704 680
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 674bbd8cfd36..882436da9a3a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1927,6 +1927,25 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
1927 return tp->af_specific->setsockopt(sk, level, optname, 1927 return tp->af_specific->setsockopt(sk, level, optname,
1928 optval, optlen); 1928 optval, optlen);
1929 1929
1930 /* This is a string value all the others are int's */
1931 if (optname == TCP_CONGESTION) {
1932 char name[TCP_CA_NAME_MAX];
1933
1934 if (optlen < 1)
1935 return -EINVAL;
1936
1937 val = strncpy_from_user(name, optval,
1938 min(TCP_CA_NAME_MAX-1, optlen));
1939 if (val < 0)
1940 return -EFAULT;
1941 name[val] = 0;
1942
1943 lock_sock(sk);
1944 err = tcp_set_congestion_control(tp, name);
1945 release_sock(sk);
1946 return err;
1947 }
1948
1930 if (optlen < sizeof(int)) 1949 if (optlen < sizeof(int))
1931 return -EINVAL; 1950 return -EINVAL;
1932 1951
@@ -2211,6 +2230,16 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
2211 case TCP_QUICKACK: 2230 case TCP_QUICKACK:
2212 val = !tp->ack.pingpong; 2231 val = !tp->ack.pingpong;
2213 break; 2232 break;
2233
2234 case TCP_CONGESTION:
2235 if (get_user(len, optlen))
2236 return -EFAULT;
2237 len = min_t(unsigned int, len, TCP_CA_NAME_MAX);
2238 if (put_user(len, optlen))
2239 return -EFAULT;
2240 if (copy_to_user(optval, tp->ca_ops->name, len))
2241 return -EFAULT;
2242 return 0;
2214 default: 2243 default:
2215 return -ENOPROTOOPT; 2244 return -ENOPROTOOPT;
2216 }; 2245 };
@@ -2224,7 +2253,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
2224 2253
2225 2254
2226extern void __skb_cb_too_small_for_tcp(int, int); 2255extern void __skb_cb_too_small_for_tcp(int, int);
2227extern void tcpdiag_init(void); 2256extern struct tcp_congestion_ops tcp_reno;
2228 2257
2229static __initdata unsigned long thash_entries; 2258static __initdata unsigned long thash_entries;
2230static int __init set_thash_entries(char *str) 2259static int __init set_thash_entries(char *str)
@@ -2333,6 +2362,8 @@ void __init tcp_init(void)
2333 printk(KERN_INFO "TCP: Hash tables configured " 2362 printk(KERN_INFO "TCP: Hash tables configured "
2334 "(established %d bind %d)\n", 2363 "(established %d bind %d)\n",
2335 tcp_ehash_size << 1, tcp_bhash_size); 2364 tcp_ehash_size << 1, tcp_bhash_size);
2365
2366 tcp_register_congestion_control(&tcp_reno);
2336} 2367}
2337 2368
2338EXPORT_SYMBOL(tcp_accept); 2369EXPORT_SYMBOL(tcp_accept);
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
new file mode 100644
index 000000000000..ec38d45d6649
--- /dev/null
+++ b/net/ipv4/tcp_bic.c
@@ -0,0 +1,331 @@
1/*
2 * Binary Increase Congestion control for TCP
3 *
4 * This is from the implementation of BICTCP in
5 * Lison-Xu, Kahaled Harfoush, and Injong Rhee.
6 * "Binary Increase Congestion Control for Fast, Long Distance
7 * Networks" in InfoComm 2004
8 * Available from:
9 * http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf
10 *
11 * Unless BIC is enabled and congestion window is large
12 * this behaves the same as the original Reno.
13 */
14
15#include <linux/config.h>
16#include <linux/mm.h>
17#include <linux/module.h>
18#include <net/tcp.h>
19
20
21#define BICTCP_BETA_SCALE 1024 /* Scale factor beta calculation
22 * max_cwnd = snd_cwnd * beta
23 */
24#define BICTCP_B 4 /*
25 * In binary search,
26 * go to point (max+min)/N
27 */
28
29static int fast_convergence = 1;
30static int max_increment = 32;
31static int low_window = 14;
32static int beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */
33static int low_utilization_threshold = 153;
34static int low_utilization_period = 2;
35static int initial_ssthresh = 100;
36static int smooth_part = 20;
37
38module_param(fast_convergence, int, 0644);
39MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
40module_param(max_increment, int, 0644);
41MODULE_PARM_DESC(max_increment, "Limit on increment allowed during binary search");
42module_param(low_window, int, 0644);
43MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)");
44module_param(beta, int, 0644);
45MODULE_PARM_DESC(beta, "beta for multiplicative increase");
46module_param(low_utilization_threshold, int, 0644);
47MODULE_PARM_DESC(low_utilization_threshold, "percent (scaled by 1024) for low utilization mode");
48module_param(low_utilization_period, int, 0644);
49MODULE_PARM_DESC(low_utilization_period, "if average delay exceeds then goto to low utilization mode (seconds)");
50module_param(initial_ssthresh, int, 0644);
51MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
52module_param(smooth_part, int, 0644);
53MODULE_PARM_DESC(smooth_part, "log(B/(B*Smin))/log(B/(B-1))+B, # of RTT from Wmax-B to Wmax");
54
55
56/* BIC TCP Parameters */
57struct bictcp {
58 u32 cnt; /* increase cwnd by 1 after ACKs */
59 u32 last_max_cwnd; /* last maximum snd_cwnd */
60 u32 loss_cwnd; /* congestion window at last loss */
61 u32 last_cwnd; /* the last snd_cwnd */
62 u32 last_time; /* time when updated last_cwnd */
63 u32 delay_min; /* min delay */
64 u32 delay_max; /* max delay */
65 u32 last_delay;
66 u8 low_utilization;/* 0: high; 1: low */
67 u32 low_utilization_start; /* starting time of low utilization detection*/
68 u32 epoch_start; /* beginning of an epoch */
69#define ACK_RATIO_SHIFT 4
70 u32 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */
71};
72
73static inline void bictcp_reset(struct bictcp *ca)
74{
75 ca->cnt = 0;
76 ca->last_max_cwnd = 0;
77 ca->loss_cwnd = 0;
78 ca->last_cwnd = 0;
79 ca->last_time = 0;
80 ca->delay_min = 0;
81 ca->delay_max = 0;
82 ca->last_delay = 0;
83 ca->low_utilization = 0;
84 ca->low_utilization_start = 0;
85 ca->epoch_start = 0;
86 ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
87}
88
89static void bictcp_init(struct tcp_sock *tp)
90{
91 bictcp_reset(tcp_ca(tp));
92 if (initial_ssthresh)
93 tp->snd_ssthresh = initial_ssthresh;
94}
95
96/*
97 * Compute congestion window to use.
98 */
99static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
100{
101 if (ca->last_cwnd == cwnd &&
102 (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
103 return;
104
105 ca->last_cwnd = cwnd;
106 ca->last_time = tcp_time_stamp;
107
108 if (ca->epoch_start == 0) /* record the beginning of an epoch */
109 ca->epoch_start = tcp_time_stamp;
110
111 /* start off normal */
112 if (cwnd <= low_window) {
113 ca->cnt = cwnd;
114 return;
115 }
116
117 /* binary increase */
118 if (cwnd < ca->last_max_cwnd) {
119 __u32 dist = (ca->last_max_cwnd - cwnd)
120 / BICTCP_B;
121
122 if (dist > max_increment)
123 /* linear increase */
124 ca->cnt = cwnd / max_increment;
125 else if (dist <= 1U)
126 /* binary search increase */
127 ca->cnt = (cwnd * smooth_part) / BICTCP_B;
128 else
129 /* binary search increase */
130 ca->cnt = cwnd / dist;
131 } else {
132 /* slow start AMD linear increase */
133 if (cwnd < ca->last_max_cwnd + BICTCP_B)
134 /* slow start */
135 ca->cnt = (cwnd * smooth_part) / BICTCP_B;
136 else if (cwnd < ca->last_max_cwnd + max_increment*(BICTCP_B-1))
137 /* slow start */
138 ca->cnt = (cwnd * (BICTCP_B-1))
139 / cwnd-ca->last_max_cwnd;
140 else
141 /* linear increase */
142 ca->cnt = cwnd / max_increment;
143 }
144
145 /* if in slow start or link utilization is very low */
146 if ( ca->loss_cwnd == 0 ||
147 (cwnd > ca->loss_cwnd && ca->low_utilization)) {
148 if (ca->cnt > 20) /* increase cwnd 5% per RTT */
149 ca->cnt = 20;
150 }
151
152 ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
153 if (ca->cnt == 0) /* cannot be zero */
154 ca->cnt = 1;
155}
156
157
158/* Detect low utilization in congestion avoidance */
159static inline void bictcp_low_utilization(struct tcp_sock *tp, int flag)
160{
161 struct bictcp *ca = tcp_ca(tp);
162 u32 dist, delay;
163
164 /* No time stamp */
165 if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
166 /* Discard delay samples right after fast recovery */
167 tcp_time_stamp < ca->epoch_start + HZ ||
168 /* this delay samples may not be accurate */
169 flag == 0) {
170 ca->last_delay = 0;
171 goto notlow;
172 }
173
174 delay = ca->last_delay<<3; /* use the same scale as tp->srtt*/
175 ca->last_delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
176 if (delay == 0) /* no previous delay sample */
177 goto notlow;
178
179 /* first time call or link delay decreases */
180 if (ca->delay_min == 0 || ca->delay_min > delay) {
181 ca->delay_min = ca->delay_max = delay;
182 goto notlow;
183 }
184
185 if (ca->delay_max < delay)
186 ca->delay_max = delay;
187
188 /* utilization is low, if avg delay < dist*threshold
189 for checking_period time */
190 dist = ca->delay_max - ca->delay_min;
191 if (dist <= ca->delay_min>>6 ||
192 tp->srtt - ca->delay_min >= (dist*low_utilization_threshold)>>10)
193 goto notlow;
194
195 if (ca->low_utilization_start == 0) {
196 ca->low_utilization = 0;
197 ca->low_utilization_start = tcp_time_stamp;
198 } else if ((s32)(tcp_time_stamp - ca->low_utilization_start)
199 > low_utilization_period*HZ) {
200 ca->low_utilization = 1;
201 }
202
203 return;
204
205 notlow:
206 ca->low_utilization = 0;
207 ca->low_utilization_start = 0;
208
209}
210
211static void bictcp_cong_avoid(struct tcp_sock *tp, u32 ack,
212 u32 seq_rtt, u32 in_flight, int data_acked)
213{
214 struct bictcp *ca = tcp_ca(tp);
215
216 bictcp_low_utilization(tp, data_acked);
217
218 if (in_flight < tp->snd_cwnd)
219 return;
220
221 if (tp->snd_cwnd <= tp->snd_ssthresh) {
222 /* In "safe" area, increase. */
223 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
224 tp->snd_cwnd++;
225 } else {
226 bictcp_update(ca, tp->snd_cwnd);
227
228 /* In dangerous area, increase slowly.
229 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
230 */
231 if (tp->snd_cwnd_cnt >= ca->cnt) {
232 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
233 tp->snd_cwnd++;
234 tp->snd_cwnd_cnt = 0;
235 } else
236 tp->snd_cwnd_cnt++;
237 }
238
239}
240
241/*
242 * behave like Reno until low_window is reached,
243 * then increase congestion window slowly
244 */
245static u32 bictcp_recalc_ssthresh(struct tcp_sock *tp)
246{
247 struct bictcp *ca = tcp_ca(tp);
248
249 ca->epoch_start = 0; /* end of epoch */
250
251 /* in case of wrong delay_max*/
252 if (ca->delay_min > 0 && ca->delay_max > ca->delay_min)
253 ca->delay_max = ca->delay_min
254 + ((ca->delay_max - ca->delay_min)* 90) / 100;
255
256 /* Wmax and fast convergence */
257 if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
258 ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
259 / (2 * BICTCP_BETA_SCALE);
260 else
261 ca->last_max_cwnd = tp->snd_cwnd;
262
263 ca->loss_cwnd = tp->snd_cwnd;
264
265
266 if (tp->snd_cwnd <= low_window)
267 return max(tp->snd_cwnd >> 1U, 2U);
268 else
269 return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
270}
271
272static u32 bictcp_undo_cwnd(struct tcp_sock *tp)
273{
274 struct bictcp *ca = tcp_ca(tp);
275
276 return max(tp->snd_cwnd, ca->last_max_cwnd);
277}
278
279static u32 bictcp_min_cwnd(struct tcp_sock *tp)
280{
281 return tp->snd_ssthresh;
282}
283
284static void bictcp_state(struct tcp_sock *tp, u8 new_state)
285{
286 if (new_state == TCP_CA_Loss)
287 bictcp_reset(tcp_ca(tp));
288}
289
290/* Track delayed acknowledgement ratio using sliding window
291 * ratio = (15*ratio + sample) / 16
292 */
293static void bictcp_acked(struct tcp_sock *tp, u32 cnt)
294{
295 if (cnt > 0 && tp->ca_state == TCP_CA_Open) {
296 struct bictcp *ca = tcp_ca(tp);
297 cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
298 ca->delayed_ack += cnt;
299 }
300}
301
302
303static struct tcp_congestion_ops bictcp = {
304 .init = bictcp_init,
305 .ssthresh = bictcp_recalc_ssthresh,
306 .cong_avoid = bictcp_cong_avoid,
307 .set_state = bictcp_state,
308 .undo_cwnd = bictcp_undo_cwnd,
309 .min_cwnd = bictcp_min_cwnd,
310 .pkts_acked = bictcp_acked,
311 .owner = THIS_MODULE,
312 .name = "bic",
313};
314
315static int __init bictcp_register(void)
316{
317 BUG_ON(sizeof(struct bictcp) > TCP_CA_PRIV_SIZE);
318 return tcp_register_congestion_control(&bictcp);
319}
320
321static void __exit bictcp_unregister(void)
322{
323 tcp_unregister_congestion_control(&bictcp);
324}
325
326module_init(bictcp_register);
327module_exit(bictcp_unregister);
328
329MODULE_AUTHOR("Stephen Hemminger");
330MODULE_LICENSE("GPL");
331MODULE_DESCRIPTION("BIC TCP");
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
new file mode 100644
index 000000000000..4970d10a7785
--- /dev/null
+++ b/net/ipv4/tcp_cong.c
@@ -0,0 +1,237 @@
1/*
2 * Plugable TCP congestion control support and newReno
3 * congestion control.
4 * Based on ideas from I/O scheduler suport and Web100.
5 *
6 * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
7 */
8
9#include <linux/config.h>
10#include <linux/module.h>
11#include <linux/mm.h>
12#include <linux/types.h>
13#include <linux/list.h>
14#include <net/tcp.h>
15
16static DEFINE_SPINLOCK(tcp_cong_list_lock);
17static LIST_HEAD(tcp_cong_list);
18
19/* Simple linear search, don't expect many entries! */
20static struct tcp_congestion_ops *tcp_ca_find(const char *name)
21{
22 struct tcp_congestion_ops *e;
23
24 list_for_each_entry_rcu(e, &tcp_cong_list, list) {
25 if (strcmp(e->name, name) == 0)
26 return e;
27 }
28
29 return NULL;
30}
31
32/*
33 * Attach new congestion control algorthim to the list
34 * of available options.
35 */
36int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
37{
38 int ret = 0;
39
40 /* all algorithms must implement ssthresh and cong_avoid ops */
41 if (!ca->ssthresh || !ca->cong_avoid || !ca->min_cwnd) {
42 printk(KERN_ERR "TCP %s does not implement required ops\n",
43 ca->name);
44 return -EINVAL;
45 }
46
47 spin_lock(&tcp_cong_list_lock);
48 if (tcp_ca_find(ca->name)) {
49 printk(KERN_NOTICE "TCP %s already registered\n", ca->name);
50 ret = -EEXIST;
51 } else {
52 list_add_rcu(&ca->list, &tcp_cong_list);
53 printk(KERN_INFO "TCP %s registered\n", ca->name);
54 }
55 spin_unlock(&tcp_cong_list_lock);
56
57 return ret;
58}
59EXPORT_SYMBOL_GPL(tcp_register_congestion_control);
60
61/*
62 * Remove congestion control algorithm, called from
63 * the module's remove function. Module ref counts are used
64 * to ensure that this can't be done till all sockets using
65 * that method are closed.
66 */
67void tcp_unregister_congestion_control(struct tcp_congestion_ops *ca)
68{
69 spin_lock(&tcp_cong_list_lock);
70 list_del_rcu(&ca->list);
71 spin_unlock(&tcp_cong_list_lock);
72}
73EXPORT_SYMBOL_GPL(tcp_unregister_congestion_control);
74
75/* Assign choice of congestion control. */
76void tcp_init_congestion_control(struct tcp_sock *tp)
77{
78 struct tcp_congestion_ops *ca;
79
80 if (tp->ca_ops != &tcp_init_congestion_ops)
81 return;
82
83 rcu_read_lock();
84 list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
85 if (try_module_get(ca->owner)) {
86 tp->ca_ops = ca;
87 break;
88 }
89
90 }
91 rcu_read_unlock();
92
93 if (tp->ca_ops->init)
94 tp->ca_ops->init(tp);
95}
96
97/* Manage refcounts on socket close. */
98void tcp_cleanup_congestion_control(struct tcp_sock *tp)
99{
100 if (tp->ca_ops->release)
101 tp->ca_ops->release(tp);
102 module_put(tp->ca_ops->owner);
103}
104
105/* Used by sysctl to change default congestion control */
106int tcp_set_default_congestion_control(const char *name)
107{
108 struct tcp_congestion_ops *ca;
109 int ret = -ENOENT;
110
111 spin_lock(&tcp_cong_list_lock);
112 ca = tcp_ca_find(name);
113#ifdef CONFIG_KMOD
114 if (!ca) {
115 spin_unlock(&tcp_cong_list_lock);
116
117 request_module("tcp_%s", name);
118 spin_lock(&tcp_cong_list_lock);
119 ca = tcp_ca_find(name);
120 }
121#endif
122
123 if (ca) {
124 list_move(&ca->list, &tcp_cong_list);
125 ret = 0;
126 }
127 spin_unlock(&tcp_cong_list_lock);
128
129 return ret;
130}
131
132/* Get current default congestion control */
133void tcp_get_default_congestion_control(char *name)
134{
135 struct tcp_congestion_ops *ca;
136 /* We will always have reno... */
137 BUG_ON(list_empty(&tcp_cong_list));
138
139 rcu_read_lock();
140 ca = list_entry(tcp_cong_list.next, struct tcp_congestion_ops, list);
141 strncpy(name, ca->name, TCP_CA_NAME_MAX);
142 rcu_read_unlock();
143}
144
145/* Change congestion control for socket */
146int tcp_set_congestion_control(struct tcp_sock *tp, const char *name)
147{
148 struct tcp_congestion_ops *ca;
149 int err = 0;
150
151 rcu_read_lock();
152 ca = tcp_ca_find(name);
153 if (ca == tp->ca_ops)
154 goto out;
155
156 if (!ca)
157 err = -ENOENT;
158
159 else if (!try_module_get(ca->owner))
160 err = -EBUSY;
161
162 else {
163 tcp_cleanup_congestion_control(tp);
164 tp->ca_ops = ca;
165 if (tp->ca_ops->init)
166 tp->ca_ops->init(tp);
167 }
168 out:
169 rcu_read_unlock();
170 return err;
171}
172
173/*
174 * TCP Reno congestion control
175 * This is special case used for fallback as well.
176 */
177/* This is Jacobson's slow start and congestion avoidance.
178 * SIGCOMM '88, p. 328.
179 */
180void tcp_reno_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt, u32 in_flight,
181 int flag)
182{
183 if (in_flight < tp->snd_cwnd)
184 return;
185
186 if (tp->snd_cwnd <= tp->snd_ssthresh) {
187 /* In "safe" area, increase. */
188 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
189 tp->snd_cwnd++;
190 } else {
191 /* In dangerous area, increase slowly.
192 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
193 */
194 if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
195 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
196 tp->snd_cwnd++;
197 tp->snd_cwnd_cnt = 0;
198 } else
199 tp->snd_cwnd_cnt++;
200 }
201}
202EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
203
204/* Slow start threshold is half the congestion window (min 2) */
205u32 tcp_reno_ssthresh(struct tcp_sock *tp)
206{
207 return max(tp->snd_cwnd >> 1U, 2U);
208}
209EXPORT_SYMBOL_GPL(tcp_reno_ssthresh);
210
211/* Lower bound on congestion window. */
212u32 tcp_reno_min_cwnd(struct tcp_sock *tp)
213{
214 return tp->snd_ssthresh/2;
215}
216EXPORT_SYMBOL_GPL(tcp_reno_min_cwnd);
217
218struct tcp_congestion_ops tcp_reno = {
219 .name = "reno",
220 .owner = THIS_MODULE,
221 .ssthresh = tcp_reno_ssthresh,
222 .cong_avoid = tcp_reno_cong_avoid,
223 .min_cwnd = tcp_reno_min_cwnd,
224};
225
226/* Initial congestion control used (until SYN)
227 * really reno under another name so we can tell difference
228 * during tcp_set_default_congestion_control
229 */
230struct tcp_congestion_ops tcp_init_congestion_ops = {
231 .name = "",
232 .owner = THIS_MODULE,
233 .ssthresh = tcp_reno_ssthresh,
234 .cong_avoid = tcp_reno_cong_avoid,
235 .min_cwnd = tcp_reno_min_cwnd,
236};
237EXPORT_SYMBOL_GPL(tcp_init_congestion_ops);
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 634befc07921..f66945cb158f 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -42,15 +42,8 @@ struct tcpdiag_entry
42 42
43static struct sock *tcpnl; 43static struct sock *tcpnl;
44 44
45
46#define TCPDIAG_PUT(skb, attrtype, attrlen) \ 45#define TCPDIAG_PUT(skb, attrtype, attrlen) \
47({ int rtalen = RTA_LENGTH(attrlen); \ 46 RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
48 struct rtattr *rta; \
49 if (skb_tailroom(skb) < RTA_ALIGN(rtalen)) goto nlmsg_failure; \
50 rta = (void*)__skb_put(skb, RTA_ALIGN(rtalen)); \
51 rta->rta_type = attrtype; \
52 rta->rta_len = rtalen; \
53 RTA_DATA(rta); })
54 47
55static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk, 48static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
56 int ext, u32 pid, u32 seq, u16 nlmsg_flags) 49 int ext, u32 pid, u32 seq, u16 nlmsg_flags)
@@ -61,7 +54,6 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
61 struct nlmsghdr *nlh; 54 struct nlmsghdr *nlh;
62 struct tcp_info *info = NULL; 55 struct tcp_info *info = NULL;
63 struct tcpdiag_meminfo *minfo = NULL; 56 struct tcpdiag_meminfo *minfo = NULL;
64 struct tcpvegas_info *vinfo = NULL;
65 unsigned char *b = skb->tail; 57 unsigned char *b = skb->tail;
66 58
67 nlh = NLMSG_PUT(skb, pid, seq, TCPDIAG_GETSOCK, sizeof(*r)); 59 nlh = NLMSG_PUT(skb, pid, seq, TCPDIAG_GETSOCK, sizeof(*r));
@@ -73,9 +65,11 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
73 if (ext & (1<<(TCPDIAG_INFO-1))) 65 if (ext & (1<<(TCPDIAG_INFO-1)))
74 info = TCPDIAG_PUT(skb, TCPDIAG_INFO, sizeof(*info)); 66 info = TCPDIAG_PUT(skb, TCPDIAG_INFO, sizeof(*info));
75 67
76 if ((tcp_is_westwood(tp) || tcp_is_vegas(tp)) 68 if (ext & (1<<(TCPDIAG_CONG-1))) {
77 && (ext & (1<<(TCPDIAG_VEGASINFO-1)))) 69 size_t len = strlen(tp->ca_ops->name);
78 vinfo = TCPDIAG_PUT(skb, TCPDIAG_VEGASINFO, sizeof(*vinfo)); 70 strcpy(TCPDIAG_PUT(skb, TCPDIAG_CONG, len+1),
71 tp->ca_ops->name);
72 }
79 } 73 }
80 r->tcpdiag_family = sk->sk_family; 74 r->tcpdiag_family = sk->sk_family;
81 r->tcpdiag_state = sk->sk_state; 75 r->tcpdiag_state = sk->sk_state;
@@ -166,23 +160,13 @@ static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
166 if (info) 160 if (info)
167 tcp_get_info(sk, info); 161 tcp_get_info(sk, info);
168 162
169 if (vinfo) { 163 if (sk->sk_state < TCP_TIME_WAIT && tp->ca_ops->get_info)
170 if (tcp_is_vegas(tp)) { 164 tp->ca_ops->get_info(tp, ext, skb);
171 vinfo->tcpv_enabled = tp->vegas.doing_vegas_now;
172 vinfo->tcpv_rttcnt = tp->vegas.cntRTT;
173 vinfo->tcpv_rtt = jiffies_to_usecs(tp->vegas.baseRTT);
174 vinfo->tcpv_minrtt = jiffies_to_usecs(tp->vegas.minRTT);
175 } else {
176 vinfo->tcpv_enabled = 0;
177 vinfo->tcpv_rttcnt = 0;
178 vinfo->tcpv_rtt = jiffies_to_usecs(tp->westwood.rtt);
179 vinfo->tcpv_minrtt = jiffies_to_usecs(tp->westwood.rtt_min);
180 }
181 }
182 165
183 nlh->nlmsg_len = skb->tail - b; 166 nlh->nlmsg_len = skb->tail - b;
184 return skb->len; 167 return skb->len;
185 168
169rtattr_failure:
186nlmsg_failure: 170nlmsg_failure:
187 skb_trim(skb, b - skb->data); 171 skb_trim(skb, b - skb->data);
188 return -1; 172 return -1;
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
new file mode 100644
index 000000000000..36c51f8136bf
--- /dev/null
+++ b/net/ipv4/tcp_highspeed.c
@@ -0,0 +1,181 @@
1/*
2 * Sally Floyd's High Speed TCP (RFC 3649) congestion control
3 *
4 * See http://www.icir.org/floyd/hstcp.html
5 *
6 * John Heffner <jheffner@psc.edu>
7 */
8
9#include <linux/config.h>
10#include <linux/module.h>
11#include <net/tcp.h>
12
13
14/* From AIMD tables from RFC 3649 appendix B,
15 * with fixed-point MD scaled <<8.
16 */
17static const struct hstcp_aimd_val {
18 unsigned int cwnd;
19 unsigned int md;
20} hstcp_aimd_vals[] = {
21 { 38, 128, /* 0.50 */ },
22 { 118, 112, /* 0.44 */ },
23 { 221, 104, /* 0.41 */ },
24 { 347, 98, /* 0.38 */ },
25 { 495, 93, /* 0.37 */ },
26 { 663, 89, /* 0.35 */ },
27 { 851, 86, /* 0.34 */ },
28 { 1058, 83, /* 0.33 */ },
29 { 1284, 81, /* 0.32 */ },
30 { 1529, 78, /* 0.31 */ },
31 { 1793, 76, /* 0.30 */ },
32 { 2076, 74, /* 0.29 */ },
33 { 2378, 72, /* 0.28 */ },
34 { 2699, 71, /* 0.28 */ },
35 { 3039, 69, /* 0.27 */ },
36 { 3399, 68, /* 0.27 */ },
37 { 3778, 66, /* 0.26 */ },
38 { 4177, 65, /* 0.26 */ },
39 { 4596, 64, /* 0.25 */ },
40 { 5036, 62, /* 0.25 */ },
41 { 5497, 61, /* 0.24 */ },
42 { 5979, 60, /* 0.24 */ },
43 { 6483, 59, /* 0.23 */ },
44 { 7009, 58, /* 0.23 */ },
45 { 7558, 57, /* 0.22 */ },
46 { 8130, 56, /* 0.22 */ },
47 { 8726, 55, /* 0.22 */ },
48 { 9346, 54, /* 0.21 */ },
49 { 9991, 53, /* 0.21 */ },
50 { 10661, 52, /* 0.21 */ },
51 { 11358, 52, /* 0.20 */ },
52 { 12082, 51, /* 0.20 */ },
53 { 12834, 50, /* 0.20 */ },
54 { 13614, 49, /* 0.19 */ },
55 { 14424, 48, /* 0.19 */ },
56 { 15265, 48, /* 0.19 */ },
57 { 16137, 47, /* 0.19 */ },
58 { 17042, 46, /* 0.18 */ },
59 { 17981, 45, /* 0.18 */ },
60 { 18955, 45, /* 0.18 */ },
61 { 19965, 44, /* 0.17 */ },
62 { 21013, 43, /* 0.17 */ },
63 { 22101, 43, /* 0.17 */ },
64 { 23230, 42, /* 0.17 */ },
65 { 24402, 41, /* 0.16 */ },
66 { 25618, 41, /* 0.16 */ },
67 { 26881, 40, /* 0.16 */ },
68 { 28193, 39, /* 0.16 */ },
69 { 29557, 39, /* 0.15 */ },
70 { 30975, 38, /* 0.15 */ },
71 { 32450, 38, /* 0.15 */ },
72 { 33986, 37, /* 0.15 */ },
73 { 35586, 36, /* 0.14 */ },
74 { 37253, 36, /* 0.14 */ },
75 { 38992, 35, /* 0.14 */ },
76 { 40808, 35, /* 0.14 */ },
77 { 42707, 34, /* 0.13 */ },
78 { 44694, 33, /* 0.13 */ },
79 { 46776, 33, /* 0.13 */ },
80 { 48961, 32, /* 0.13 */ },
81 { 51258, 32, /* 0.13 */ },
82 { 53677, 31, /* 0.12 */ },
83 { 56230, 30, /* 0.12 */ },
84 { 58932, 30, /* 0.12 */ },
85 { 61799, 29, /* 0.12 */ },
86 { 64851, 28, /* 0.11 */ },
87 { 68113, 28, /* 0.11 */ },
88 { 71617, 27, /* 0.11 */ },
89 { 75401, 26, /* 0.10 */ },
90 { 79517, 26, /* 0.10 */ },
91 { 84035, 25, /* 0.10 */ },
92 { 89053, 24, /* 0.10 */ },
93};
94
95#define HSTCP_AIMD_MAX ARRAY_SIZE(hstcp_aimd_vals)
96
97struct hstcp {
98 u32 ai;
99};
100
101static void hstcp_init(struct tcp_sock *tp)
102{
103 struct hstcp *ca = tcp_ca(tp);
104
105 ca->ai = 0;
106
107 /* Ensure the MD arithmetic works. This is somewhat pedantic,
108 * since I don't think we will see a cwnd this large. :) */
109 tp->snd_cwnd_clamp = min_t(u32, tp->snd_cwnd_clamp, 0xffffffff/128);
110}
111
112static void hstcp_cong_avoid(struct tcp_sock *tp, u32 adk, u32 rtt,
113 u32 in_flight, int good)
114{
115 struct hstcp *ca = tcp_ca(tp);
116
117 if (in_flight < tp->snd_cwnd)
118 return;
119
120 if (tp->snd_cwnd <= tp->snd_ssthresh) {
121 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
122 tp->snd_cwnd++;
123 } else {
124 /* Update AIMD parameters */
125 if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
126 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
127 ca->ai < HSTCP_AIMD_MAX)
128 ca->ai++;
129 } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) {
130 while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
131 ca->ai > 0)
132 ca->ai--;
133 }
134
135 /* Do additive increase */
136 if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
137 tp->snd_cwnd_cnt += ca->ai;
138 if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
139 tp->snd_cwnd++;
140 tp->snd_cwnd_cnt -= tp->snd_cwnd;
141 }
142 }
143 }
144}
145
146static u32 hstcp_ssthresh(struct tcp_sock *tp)
147{
148 struct hstcp *ca = tcp_ca(tp);
149
150 /* Do multiplicative decrease */
151 return max(tp->snd_cwnd - ((tp->snd_cwnd * hstcp_aimd_vals[ca->ai].md) >> 8), 2U);
152}
153
154
155static struct tcp_congestion_ops tcp_highspeed = {
156 .init = hstcp_init,
157 .ssthresh = hstcp_ssthresh,
158 .cong_avoid = hstcp_cong_avoid,
159 .min_cwnd = tcp_reno_min_cwnd,
160
161 .owner = THIS_MODULE,
162 .name = "highspeed"
163};
164
165static int __init hstcp_register(void)
166{
167 BUG_ON(sizeof(struct hstcp) > TCP_CA_PRIV_SIZE);
168 return tcp_register_congestion_control(&tcp_highspeed);
169}
170
171static void __exit hstcp_unregister(void)
172{
173 tcp_unregister_congestion_control(&tcp_highspeed);
174}
175
176module_init(hstcp_register);
177module_exit(hstcp_unregister);
178
179MODULE_AUTHOR("John Heffner");
180MODULE_LICENSE("GPL");
181MODULE_DESCRIPTION("High Speed TCP");
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
new file mode 100644
index 000000000000..40168275acf9
--- /dev/null
+++ b/net/ipv4/tcp_htcp.c
@@ -0,0 +1,289 @@
1/*
2 * H-TCP congestion control. The algorithm is detailed in:
3 * R.N.Shorten, D.J.Leith:
4 * "H-TCP: TCP for high-speed and long-distance networks"
5 * Proc. PFLDnet, Argonne, 2004.
6 * http://www.hamilton.ie/net/htcp3.pdf
7 */
8
9#include <linux/config.h>
10#include <linux/mm.h>
11#include <linux/module.h>
12#include <net/tcp.h>
13
14#define ALPHA_BASE (1<<7) /* 1.0 with shift << 7 */
15#define BETA_MIN (1<<6) /* 0.5 with shift << 7 */
16#define BETA_MAX 102 /* 0.8 with shift << 7 */
17
18static int use_rtt_scaling = 1;
19module_param(use_rtt_scaling, int, 0644);
20MODULE_PARM_DESC(use_rtt_scaling, "turn on/off RTT scaling");
21
22static int use_bandwidth_switch = 1;
23module_param(use_bandwidth_switch, int, 0644);
24MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher");
25
26struct htcp {
27 u16 alpha; /* Fixed point arith, << 7 */
28 u8 beta; /* Fixed point arith, << 7 */
29 u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */
30 u8 ccount; /* Number of RTTs since last congestion event */
31 u8 undo_ccount;
32 u16 packetcount;
33 u32 minRTT;
34 u32 maxRTT;
35 u32 snd_cwnd_cnt2;
36
37 u32 undo_maxRTT;
38 u32 undo_old_maxB;
39
40 /* Bandwidth estimation */
41 u32 minB;
42 u32 maxB;
43 u32 old_maxB;
44 u32 Bi;
45 u32 lasttime;
46};
47
48static inline void htcp_reset(struct htcp *ca)
49{
50 ca->undo_ccount = ca->ccount;
51 ca->undo_maxRTT = ca->maxRTT;
52 ca->undo_old_maxB = ca->old_maxB;
53
54 ca->ccount = 0;
55 ca->snd_cwnd_cnt2 = 0;
56}
57
58static u32 htcp_cwnd_undo(struct tcp_sock *tp)
59{
60 struct htcp *ca = tcp_ca(tp);
61 ca->ccount = ca->undo_ccount;
62 ca->maxRTT = ca->undo_maxRTT;
63 ca->old_maxB = ca->undo_old_maxB;
64 return max(tp->snd_cwnd, (tp->snd_ssthresh<<7)/ca->beta);
65}
66
67static inline void measure_rtt(struct tcp_sock *tp)
68{
69 struct htcp *ca = tcp_ca(tp);
70 u32 srtt = tp->srtt>>3;
71
72 /* keep track of minimum RTT seen so far, minRTT is zero at first */
73 if (ca->minRTT > srtt || !ca->minRTT)
74 ca->minRTT = srtt;
75
76 /* max RTT */
77 if (tp->ca_state == TCP_CA_Open && tp->snd_ssthresh < 0xFFFF && ca->ccount > 3) {
78 if (ca->maxRTT < ca->minRTT)
79 ca->maxRTT = ca->minRTT;
80 if (ca->maxRTT < srtt && srtt <= ca->maxRTT+HZ/50)
81 ca->maxRTT = srtt;
82 }
83}
84
85static void measure_achieved_throughput(struct tcp_sock *tp, u32 pkts_acked)
86{
87 struct htcp *ca = tcp_ca(tp);
88 u32 now = tcp_time_stamp;
89
90 /* achieved throughput calculations */
91 if (tp->ca_state != TCP_CA_Open && tp->ca_state != TCP_CA_Disorder) {
92 ca->packetcount = 0;
93 ca->lasttime = now;
94 return;
95 }
96
97 ca->packetcount += pkts_acked;
98
99 if (ca->packetcount >= tp->snd_cwnd - (ca->alpha>>7? : 1)
100 && now - ca->lasttime >= ca->minRTT
101 && ca->minRTT > 0) {
102 __u32 cur_Bi = ca->packetcount*HZ/(now - ca->lasttime);
103 if (ca->ccount <= 3) {
104 /* just after backoff */
105 ca->minB = ca->maxB = ca->Bi = cur_Bi;
106 } else {
107 ca->Bi = (3*ca->Bi + cur_Bi)/4;
108 if (ca->Bi > ca->maxB)
109 ca->maxB = ca->Bi;
110 if (ca->minB > ca->maxB)
111 ca->minB = ca->maxB;
112 }
113 ca->packetcount = 0;
114 ca->lasttime = now;
115 }
116}
117
118static inline void htcp_beta_update(struct htcp *ca, u32 minRTT, u32 maxRTT)
119{
120 if (use_bandwidth_switch) {
121 u32 maxB = ca->maxB;
122 u32 old_maxB = ca->old_maxB;
123 ca->old_maxB = ca->maxB;
124
125 if (!between(5*maxB, 4*old_maxB, 6*old_maxB)) {
126 ca->beta = BETA_MIN;
127 ca->modeswitch = 0;
128 return;
129 }
130 }
131
132 if (ca->modeswitch && minRTT > max(HZ/100, 1) && maxRTT) {
133 ca->beta = (minRTT<<7)/maxRTT;
134 if (ca->beta < BETA_MIN)
135 ca->beta = BETA_MIN;
136 else if (ca->beta > BETA_MAX)
137 ca->beta = BETA_MAX;
138 } else {
139 ca->beta = BETA_MIN;
140 ca->modeswitch = 1;
141 }
142}
143
144static inline void htcp_alpha_update(struct htcp *ca)
145{
146 u32 minRTT = ca->minRTT;
147 u32 factor = 1;
148 u32 diff = ca->ccount * minRTT; /* time since last backoff */
149
150 if (diff > HZ) {
151 diff -= HZ;
152 factor = 1+ ( 10*diff + ((diff/2)*(diff/2)/HZ) )/HZ;
153 }
154
155 if (use_rtt_scaling && minRTT) {
156 u32 scale = (HZ<<3)/(10*minRTT);
157 scale = min(max(scale, 1U<<2), 10U<<3); /* clamping ratio to interval [0.5,10]<<3 */
158 factor = (factor<<3)/scale;
159 if (!factor)
160 factor = 1;
161 }
162
163 ca->alpha = 2*factor*((1<<7)-ca->beta);
164 if (!ca->alpha)
165 ca->alpha = ALPHA_BASE;
166}
167
168/* After we have the rtt data to calculate beta, we'd still prefer to wait one
169 * rtt before we adjust our beta to ensure we are working from a consistent
170 * data.
171 *
172 * This function should be called when we hit a congestion event since only at
173 * that point do we really have a real sense of maxRTT (the queues en route
174 * were getting just too full now).
175 */
176static void htcp_param_update(struct tcp_sock *tp)
177{
178 struct htcp *ca = tcp_ca(tp);
179 u32 minRTT = ca->minRTT;
180 u32 maxRTT = ca->maxRTT;
181
182 htcp_beta_update(ca, minRTT, maxRTT);
183 htcp_alpha_update(ca);
184
185 /* add slowly fading memory for maxRTT to accommodate routing changes etc */
186 if (minRTT > 0 && maxRTT > minRTT)
187 ca->maxRTT = minRTT + ((maxRTT-minRTT)*95)/100;
188}
189
190static u32 htcp_recalc_ssthresh(struct tcp_sock *tp)
191{
192 struct htcp *ca = tcp_ca(tp);
193 htcp_param_update(tp);
194 return max((tp->snd_cwnd * ca->beta) >> 7, 2U);
195}
196
197static void htcp_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
198 u32 in_flight, int data_acked)
199{
200 struct htcp *ca = tcp_ca(tp);
201
202 if (in_flight < tp->snd_cwnd)
203 return;
204
205 if (tp->snd_cwnd <= tp->snd_ssthresh) {
206 /* In "safe" area, increase. */
207 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
208 tp->snd_cwnd++;
209 } else {
210 measure_rtt(tp);
211
212 /* keep track of number of round-trip times since last backoff event */
213 if (ca->snd_cwnd_cnt2++ > tp->snd_cwnd) {
214 ca->ccount++;
215 ca->snd_cwnd_cnt2 = 0;
216 htcp_alpha_update(ca);
217 }
218
219 /* In dangerous area, increase slowly.
220 * In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd
221 */
222 if ((tp->snd_cwnd_cnt++ * ca->alpha)>>7 >= tp->snd_cwnd) {
223 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
224 tp->snd_cwnd++;
225 tp->snd_cwnd_cnt = 0;
226 ca->ccount++;
227 }
228 }
229}
230
231/* Lower bound on congestion window. */
232static u32 htcp_min_cwnd(struct tcp_sock *tp)
233{
234 return tp->snd_ssthresh;
235}
236
237
238static void htcp_init(struct tcp_sock *tp)
239{
240 struct htcp *ca = tcp_ca(tp);
241
242 memset(ca, 0, sizeof(struct htcp));
243 ca->alpha = ALPHA_BASE;
244 ca->beta = BETA_MIN;
245}
246
247static void htcp_state(struct tcp_sock *tp, u8 new_state)
248{
249 switch (new_state) {
250 case TCP_CA_CWR:
251 case TCP_CA_Recovery:
252 case TCP_CA_Loss:
253 htcp_reset(tcp_ca(tp));
254 break;
255 }
256}
257
258static struct tcp_congestion_ops htcp = {
259 .init = htcp_init,
260 .ssthresh = htcp_recalc_ssthresh,
261 .min_cwnd = htcp_min_cwnd,
262 .cong_avoid = htcp_cong_avoid,
263 .set_state = htcp_state,
264 .undo_cwnd = htcp_cwnd_undo,
265 .pkts_acked = measure_achieved_throughput,
266 .owner = THIS_MODULE,
267 .name = "htcp",
268};
269
270static int __init htcp_register(void)
271{
272 BUG_ON(sizeof(struct htcp) > TCP_CA_PRIV_SIZE);
273 BUILD_BUG_ON(BETA_MIN >= BETA_MAX);
274 if (!use_bandwidth_switch)
275 htcp.pkts_acked = NULL;
276 return tcp_register_congestion_control(&htcp);
277}
278
279static void __exit htcp_unregister(void)
280{
281 tcp_unregister_congestion_control(&htcp);
282}
283
284module_init(htcp_register);
285module_exit(htcp_unregister);
286
287MODULE_AUTHOR("Baruch Even");
288MODULE_LICENSE("GPL");
289MODULE_DESCRIPTION("H-TCP");
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
new file mode 100644
index 000000000000..13a66342c304
--- /dev/null
+++ b/net/ipv4/tcp_hybla.c
@@ -0,0 +1,187 @@
1/*
2 * TCP HYBLA
3 *
4 * TCP-HYBLA Congestion control algorithm, based on:
5 * C.Caini, R.Firrincieli, "TCP-Hybla: A TCP Enhancement
6 * for Heterogeneous Networks",
7 * International Journal on satellite Communications,
8 * September 2004
9 * Daniele Lacamera
10 * root at danielinux.net
11 */
12
13#include <linux/config.h>
14#include <linux/module.h>
15#include <net/tcp.h>
16
17/* Tcp Hybla structure. */
18struct hybla {
19 u8 hybla_en;
20 u32 snd_cwnd_cents; /* Keeps increment values when it is <1, <<7 */
21 u32 rho; /* Rho parameter, integer part */
22 u32 rho2; /* Rho * Rho, integer part */
23 u32 rho_3ls; /* Rho parameter, <<3 */
24 u32 rho2_7ls; /* Rho^2, <<7 */
25 u32 minrtt; /* Minimum smoothed round trip time value seen */
26};
27
28/* Hybla reference round trip time (default= 1/40 sec = 25 ms),
29 expressed in jiffies */
30static int rtt0 = 25;
31module_param(rtt0, int, 0644);
32MODULE_PARM_DESC(rtt0, "reference rout trip time (ms)");
33
34
35/* This is called to refresh values for hybla parameters */
36static inline void hybla_recalc_param (struct tcp_sock *tp)
37{
38 struct hybla *ca = tcp_ca(tp);
39
40 ca->rho_3ls = max_t(u32, tp->srtt / msecs_to_jiffies(rtt0), 8);
41 ca->rho = ca->rho_3ls >> 3;
42 ca->rho2_7ls = (ca->rho_3ls * ca->rho_3ls) << 1;
43 ca->rho2 = ca->rho2_7ls >>7;
44}
45
46static void hybla_init(struct tcp_sock *tp)
47{
48 struct hybla *ca = tcp_ca(tp);
49
50 ca->rho = 0;
51 ca->rho2 = 0;
52 ca->rho_3ls = 0;
53 ca->rho2_7ls = 0;
54 ca->snd_cwnd_cents = 0;
55 ca->hybla_en = 1;
56 tp->snd_cwnd = 2;
57 tp->snd_cwnd_clamp = 65535;
58
59 /* 1st Rho measurement based on initial srtt */
60 hybla_recalc_param(tp);
61
62 /* set minimum rtt as this is the 1st ever seen */
63 ca->minrtt = tp->srtt;
64 tp->snd_cwnd = ca->rho;
65}
66
67static void hybla_state(struct tcp_sock *tp, u8 ca_state)
68{
69 struct hybla *ca = tcp_ca(tp);
70
71 ca->hybla_en = (ca_state == TCP_CA_Open);
72}
73
74static inline u32 hybla_fraction(u32 odds)
75{
76 static const u32 fractions[] = {
77 128, 139, 152, 165, 181, 197, 215, 234,
78 };
79
80 return (odds < ARRAY_SIZE(fractions)) ? fractions[odds] : 128;
81}
82
83/* TCP Hybla main routine.
84 * This is the algorithm behavior:
85 * o Recalc Hybla parameters if min_rtt has changed
86 * o Give cwnd a new value based on the model proposed
87 * o remember increments <1
88 */
89static void hybla_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
90 u32 in_flight, int flag)
91{
92 struct hybla *ca = tcp_ca(tp);
93 u32 increment, odd, rho_fractions;
94 int is_slowstart = 0;
95
96 /* Recalculate rho only if this srtt is the lowest */
97 if (tp->srtt < ca->minrtt){
98 hybla_recalc_param(tp);
99 ca->minrtt = tp->srtt;
100 }
101
102 if (!ca->hybla_en)
103 return tcp_reno_cong_avoid(tp, ack, rtt, in_flight, flag);
104
105 if (in_flight < tp->snd_cwnd)
106 return;
107
108 if (ca->rho == 0)
109 hybla_recalc_param(tp);
110
111 rho_fractions = ca->rho_3ls - (ca->rho << 3);
112
113 if (tp->snd_cwnd < tp->snd_ssthresh) {
114 /*
115 * slow start
116 * INC = 2^RHO - 1
117 * This is done by splitting the rho parameter
118 * into 2 parts: an integer part and a fraction part.
119 * Inrement<<7 is estimated by doing:
120 * [2^(int+fract)]<<7
121 * that is equal to:
122 * (2^int) * [(2^fract) <<7]
123 * 2^int is straightly computed as 1<<int,
124 * while we will use hybla_slowstart_fraction_increment() to
125 * calculate 2^fract in a <<7 value.
126 */
127 is_slowstart = 1;
128 increment = ((1 << ca->rho) * hybla_fraction(rho_fractions))
129 - 128;
130 } else {
131 /*
132 * congestion avoidance
133 * INC = RHO^2 / W
134 * as long as increment is estimated as (rho<<7)/window
135 * it already is <<7 and we can easily count its fractions.
136 */
137 increment = ca->rho2_7ls / tp->snd_cwnd;
138 if (increment < 128)
139 tp->snd_cwnd_cnt++;
140 }
141
142 odd = increment % 128;
143 tp->snd_cwnd += increment >> 7;
144 ca->snd_cwnd_cents += odd;
145
146 /* check when fractions goes >=128 and increase cwnd by 1. */
147 while(ca->snd_cwnd_cents >= 128) {
148 tp->snd_cwnd++;
149 ca->snd_cwnd_cents -= 128;
150 tp->snd_cwnd_cnt = 0;
151 }
152
153 /* clamp down slowstart cwnd to ssthresh value. */
154 if (is_slowstart)
155 tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
156
157 tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
158}
159
160static struct tcp_congestion_ops tcp_hybla = {
161 .init = hybla_init,
162 .ssthresh = tcp_reno_ssthresh,
163 .min_cwnd = tcp_reno_min_cwnd,
164 .cong_avoid = hybla_cong_avoid,
165 .set_state = hybla_state,
166
167 .owner = THIS_MODULE,
168 .name = "hybla"
169};
170
171static int __init hybla_register(void)
172{
173 BUG_ON(sizeof(struct hybla) > TCP_CA_PRIV_SIZE);
174 return tcp_register_congestion_control(&tcp_hybla);
175}
176
177static void __exit hybla_unregister(void)
178{
179 tcp_unregister_congestion_control(&tcp_hybla);
180}
181
182module_init(hybla_register);
183module_exit(hybla_unregister);
184
185MODULE_AUTHOR("Daniele Lacamera");
186MODULE_LICENSE("GPL");
187MODULE_DESCRIPTION("TCP Hybla");
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 5bad504630a3..7bbbbc33eb4b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -61,7 +61,6 @@
61 * Panu Kuhlberg: Experimental audit of TCP (re)transmission 61 * Panu Kuhlberg: Experimental audit of TCP (re)transmission
62 * engine. Lots of bugs are found. 62 * engine. Lots of bugs are found.
63 * Pasi Sarolahti: F-RTO for dealing with spurious RTOs 63 * Pasi Sarolahti: F-RTO for dealing with spurious RTOs
64 * Angelo Dell'Aera: TCP Westwood+ support
65 */ 64 */
66 65
67#include <linux/config.h> 66#include <linux/config.h>
@@ -88,23 +87,9 @@ int sysctl_tcp_rfc1337;
88int sysctl_tcp_max_orphans = NR_FILE; 87int sysctl_tcp_max_orphans = NR_FILE;
89int sysctl_tcp_frto; 88int sysctl_tcp_frto;
90int sysctl_tcp_nometrics_save; 89int sysctl_tcp_nometrics_save;
91int sysctl_tcp_westwood;
92int sysctl_tcp_vegas_cong_avoid;
93 90
94int sysctl_tcp_moderate_rcvbuf = 1; 91int sysctl_tcp_moderate_rcvbuf = 1;
95 92
96/* Default values of the Vegas variables, in fixed-point representation
97 * with V_PARAM_SHIFT bits to the right of the binary point.
98 */
99#define V_PARAM_SHIFT 1
100int sysctl_tcp_vegas_alpha = 1<<V_PARAM_SHIFT;
101int sysctl_tcp_vegas_beta = 3<<V_PARAM_SHIFT;
102int sysctl_tcp_vegas_gamma = 1<<V_PARAM_SHIFT;
103int sysctl_tcp_bic = 1;
104int sysctl_tcp_bic_fast_convergence = 1;
105int sysctl_tcp_bic_low_window = 14;
106int sysctl_tcp_bic_beta = 819; /* = 819/1024 (BICTCP_BETA_SCALE) */
107
108#define FLAG_DATA 0x01 /* Incoming frame contained data. */ 93#define FLAG_DATA 0x01 /* Incoming frame contained data. */
109#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ 94#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
110#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ 95#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */
@@ -333,15 +318,6 @@ static void tcp_init_buffer_space(struct sock *sk)
333 tp->snd_cwnd_stamp = tcp_time_stamp; 318 tp->snd_cwnd_stamp = tcp_time_stamp;
334} 319}
335 320
336static void init_bictcp(struct tcp_sock *tp)
337{
338 tp->bictcp.cnt = 0;
339
340 tp->bictcp.last_max_cwnd = 0;
341 tp->bictcp.last_cwnd = 0;
342 tp->bictcp.last_stamp = 0;
343}
344
345/* 5. Recalculate window clamp after socket hit its memory bounds. */ 321/* 5. Recalculate window clamp after socket hit its memory bounds. */
346static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp) 322static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
347{ 323{
@@ -558,45 +534,6 @@ static void tcp_event_data_recv(struct sock *sk, struct tcp_sock *tp, struct sk_
558 tcp_grow_window(sk, tp, skb); 534 tcp_grow_window(sk, tp, skb);
559} 535}
560 536
561/* When starting a new connection, pin down the current choice of
562 * congestion algorithm.
563 */
564void tcp_ca_init(struct tcp_sock *tp)
565{
566 if (sysctl_tcp_westwood)
567 tp->adv_cong = TCP_WESTWOOD;
568 else if (sysctl_tcp_bic)
569 tp->adv_cong = TCP_BIC;
570 else if (sysctl_tcp_vegas_cong_avoid) {
571 tp->adv_cong = TCP_VEGAS;
572 tp->vegas.baseRTT = 0x7fffffff;
573 tcp_vegas_enable(tp);
574 }
575}
576
577/* Do RTT sampling needed for Vegas.
578 * Basically we:
579 * o min-filter RTT samples from within an RTT to get the current
580 * propagation delay + queuing delay (we are min-filtering to try to
581 * avoid the effects of delayed ACKs)
582 * o min-filter RTT samples from a much longer window (forever for now)
583 * to find the propagation delay (baseRTT)
584 */
585static inline void vegas_rtt_calc(struct tcp_sock *tp, __u32 rtt)
586{
587 __u32 vrtt = rtt + 1; /* Never allow zero rtt or baseRTT */
588
589 /* Filter to find propagation delay: */
590 if (vrtt < tp->vegas.baseRTT)
591 tp->vegas.baseRTT = vrtt;
592
593 /* Find the min RTT during the last RTT to find
594 * the current prop. delay + queuing delay:
595 */
596 tp->vegas.minRTT = min(tp->vegas.minRTT, vrtt);
597 tp->vegas.cntRTT++;
598}
599
600/* Called to compute a smoothed rtt estimate. The data fed to this 537/* Called to compute a smoothed rtt estimate. The data fed to this
601 * routine either comes from timestamps, or from segments that were 538 * routine either comes from timestamps, or from segments that were
602 * known _not_ to have been retransmitted [see Karn/Partridge 539 * known _not_ to have been retransmitted [see Karn/Partridge
@@ -606,13 +543,10 @@ static inline void vegas_rtt_calc(struct tcp_sock *tp, __u32 rtt)
606 * To save cycles in the RFC 1323 implementation it was better to break 543 * To save cycles in the RFC 1323 implementation it was better to break
607 * it up into three procedures. -- erics 544 * it up into three procedures. -- erics
608 */ 545 */
609static void tcp_rtt_estimator(struct tcp_sock *tp, __u32 mrtt) 546static void tcp_rtt_estimator(struct tcp_sock *tp, __u32 mrtt, u32 *usrtt)
610{ 547{
611 long m = mrtt; /* RTT */ 548 long m = mrtt; /* RTT */
612 549
613 if (tcp_vegas_enabled(tp))
614 vegas_rtt_calc(tp, mrtt);
615
616 /* The following amusing code comes from Jacobson's 550 /* The following amusing code comes from Jacobson's
617 * article in SIGCOMM '88. Note that rtt and mdev 551 * article in SIGCOMM '88. Note that rtt and mdev
618 * are scaled versions of rtt and mean deviation. 552 * are scaled versions of rtt and mean deviation.
@@ -670,7 +604,8 @@ static void tcp_rtt_estimator(struct tcp_sock *tp, __u32 mrtt)
670 tp->rtt_seq = tp->snd_nxt; 604 tp->rtt_seq = tp->snd_nxt;
671 } 605 }
672 606
673 tcp_westwood_update_rtt(tp, tp->srtt >> 3); 607 if (tp->ca_ops->rtt_sample)
608 tp->ca_ops->rtt_sample(tp, *usrtt);
674} 609}
675 610
676/* Calculate rto without backoff. This is the second half of Van Jacobson's 611/* Calculate rto without backoff. This is the second half of Van Jacobson's
@@ -1185,8 +1120,8 @@ void tcp_enter_frto(struct sock *sk)
1185 tp->snd_una == tp->high_seq || 1120 tp->snd_una == tp->high_seq ||
1186 (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) { 1121 (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) {
1187 tp->prior_ssthresh = tcp_current_ssthresh(tp); 1122 tp->prior_ssthresh = tcp_current_ssthresh(tp);
1188 if (!tcp_westwood_ssthresh(tp)) 1123 tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
1189 tp->snd_ssthresh = tcp_recalc_ssthresh(tp); 1124 tcp_ca_event(tp, CA_EVENT_FRTO);
1190 } 1125 }
1191 1126
1192 /* Have to clear retransmission markers here to keep the bookkeeping 1127 /* Have to clear retransmission markers here to keep the bookkeeping
@@ -1252,8 +1187,6 @@ static void tcp_enter_frto_loss(struct sock *sk)
1252 tcp_set_ca_state(tp, TCP_CA_Loss); 1187 tcp_set_ca_state(tp, TCP_CA_Loss);
1253 tp->high_seq = tp->frto_highmark; 1188 tp->high_seq = tp->frto_highmark;
1254 TCP_ECN_queue_cwr(tp); 1189 TCP_ECN_queue_cwr(tp);
1255
1256 init_bictcp(tp);
1257} 1190}
1258 1191
1259void tcp_clear_retrans(struct tcp_sock *tp) 1192void tcp_clear_retrans(struct tcp_sock *tp)
@@ -1283,7 +1216,8 @@ void tcp_enter_loss(struct sock *sk, int how)
1283 if (tp->ca_state <= TCP_CA_Disorder || tp->snd_una == tp->high_seq || 1216 if (tp->ca_state <= TCP_CA_Disorder || tp->snd_una == tp->high_seq ||
1284 (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) { 1217 (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) {
1285 tp->prior_ssthresh = tcp_current_ssthresh(tp); 1218 tp->prior_ssthresh = tcp_current_ssthresh(tp);
1286 tp->snd_ssthresh = tcp_recalc_ssthresh(tp); 1219 tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
1220 tcp_ca_event(tp, CA_EVENT_LOSS);
1287 } 1221 }
1288 tp->snd_cwnd = 1; 1222 tp->snd_cwnd = 1;
1289 tp->snd_cwnd_cnt = 0; 1223 tp->snd_cwnd_cnt = 0;
@@ -1596,28 +1530,14 @@ static inline void tcp_moderate_cwnd(struct tcp_sock *tp)
1596} 1530}
1597 1531
1598/* Decrease cwnd each second ack. */ 1532/* Decrease cwnd each second ack. */
1599
1600static void tcp_cwnd_down(struct tcp_sock *tp) 1533static void tcp_cwnd_down(struct tcp_sock *tp)
1601{ 1534{
1602 int decr = tp->snd_cwnd_cnt + 1; 1535 int decr = tp->snd_cwnd_cnt + 1;
1603 __u32 limit;
1604
1605 /*
1606 * TCP Westwood
1607 * Here limit is evaluated as BWestimation*RTTmin (for obtaining it
1608 * in packets we use mss_cache). If sysctl_tcp_westwood is off
1609 * tcp_westwood_bw_rttmin() returns 0. In such case snd_ssthresh is
1610 * still used as usual. It prevents other strange cases in which
1611 * BWE*RTTmin could assume value 0. It should not happen but...
1612 */
1613
1614 if (!(limit = tcp_westwood_bw_rttmin(tp)))
1615 limit = tp->snd_ssthresh/2;
1616 1536
1617 tp->snd_cwnd_cnt = decr&1; 1537 tp->snd_cwnd_cnt = decr&1;
1618 decr >>= 1; 1538 decr >>= 1;
1619 1539
1620 if (decr && tp->snd_cwnd > limit) 1540 if (decr && tp->snd_cwnd > tp->ca_ops->min_cwnd(tp))
1621 tp->snd_cwnd -= decr; 1541 tp->snd_cwnd -= decr;
1622 1542
1623 tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1); 1543 tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1);
@@ -1654,8 +1574,8 @@ static void DBGUNDO(struct sock *sk, struct tcp_sock *tp, const char *msg)
1654static void tcp_undo_cwr(struct tcp_sock *tp, int undo) 1574static void tcp_undo_cwr(struct tcp_sock *tp, int undo)
1655{ 1575{
1656 if (tp->prior_ssthresh) { 1576 if (tp->prior_ssthresh) {
1657 if (tcp_is_bic(tp)) 1577 if (tp->ca_ops->undo_cwnd)
1658 tp->snd_cwnd = max(tp->snd_cwnd, tp->bictcp.last_max_cwnd); 1578 tp->snd_cwnd = tp->ca_ops->undo_cwnd(tp);
1659 else 1579 else
1660 tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1); 1580 tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
1661 1581
@@ -1767,11 +1687,9 @@ static int tcp_try_undo_loss(struct sock *sk, struct tcp_sock *tp)
1767 1687
1768static inline void tcp_complete_cwr(struct tcp_sock *tp) 1688static inline void tcp_complete_cwr(struct tcp_sock *tp)
1769{ 1689{
1770 if (tcp_westwood_cwnd(tp)) 1690 tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
1771 tp->snd_ssthresh = tp->snd_cwnd;
1772 else
1773 tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
1774 tp->snd_cwnd_stamp = tcp_time_stamp; 1691 tp->snd_cwnd_stamp = tcp_time_stamp;
1692 tcp_ca_event(tp, CA_EVENT_COMPLETE_CWR);
1775} 1693}
1776 1694
1777static void tcp_try_to_open(struct sock *sk, struct tcp_sock *tp, int flag) 1695static void tcp_try_to_open(struct sock *sk, struct tcp_sock *tp, int flag)
@@ -1946,7 +1864,7 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
1946 if (tp->ca_state < TCP_CA_CWR) { 1864 if (tp->ca_state < TCP_CA_CWR) {
1947 if (!(flag&FLAG_ECE)) 1865 if (!(flag&FLAG_ECE))
1948 tp->prior_ssthresh = tcp_current_ssthresh(tp); 1866 tp->prior_ssthresh = tcp_current_ssthresh(tp);
1949 tp->snd_ssthresh = tcp_recalc_ssthresh(tp); 1867 tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
1950 TCP_ECN_queue_cwr(tp); 1868 TCP_ECN_queue_cwr(tp);
1951 } 1869 }
1952 1870
@@ -1963,7 +1881,7 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
1963/* Read draft-ietf-tcplw-high-performance before mucking 1881/* Read draft-ietf-tcplw-high-performance before mucking
1964 * with this code. (Superceeds RFC1323) 1882 * with this code. (Superceeds RFC1323)
1965 */ 1883 */
1966static void tcp_ack_saw_tstamp(struct tcp_sock *tp, int flag) 1884static void tcp_ack_saw_tstamp(struct tcp_sock *tp, u32 *usrtt, int flag)
1967{ 1885{
1968 __u32 seq_rtt; 1886 __u32 seq_rtt;
1969 1887
@@ -1983,13 +1901,13 @@ static void tcp_ack_saw_tstamp(struct tcp_sock *tp, int flag)
1983 * in window is lost... Voila. --ANK (010210) 1901 * in window is lost... Voila. --ANK (010210)
1984 */ 1902 */
1985 seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr; 1903 seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
1986 tcp_rtt_estimator(tp, seq_rtt); 1904 tcp_rtt_estimator(tp, seq_rtt, usrtt);
1987 tcp_set_rto(tp); 1905 tcp_set_rto(tp);
1988 tp->backoff = 0; 1906 tp->backoff = 0;
1989 tcp_bound_rto(tp); 1907 tcp_bound_rto(tp);
1990} 1908}
1991 1909
1992static void tcp_ack_no_tstamp(struct tcp_sock *tp, u32 seq_rtt, int flag) 1910static void tcp_ack_no_tstamp(struct tcp_sock *tp, u32 seq_rtt, u32 *usrtt, int flag)
1993{ 1911{
1994 /* We don't have a timestamp. Can only use 1912 /* We don't have a timestamp. Can only use
1995 * packets that are not retransmitted to determine 1913 * packets that are not retransmitted to determine
@@ -2003,338 +1921,29 @@ static void tcp_ack_no_tstamp(struct tcp_sock *tp, u32 seq_rtt, int flag)
2003 if (flag & FLAG_RETRANS_DATA_ACKED) 1921 if (flag & FLAG_RETRANS_DATA_ACKED)
2004 return; 1922 return;
2005 1923
2006 tcp_rtt_estimator(tp, seq_rtt); 1924 tcp_rtt_estimator(tp, seq_rtt, usrtt);
2007 tcp_set_rto(tp); 1925 tcp_set_rto(tp);
2008 tp->backoff = 0; 1926 tp->backoff = 0;
2009 tcp_bound_rto(tp); 1927 tcp_bound_rto(tp);
2010} 1928}
2011 1929
2012static inline void tcp_ack_update_rtt(struct tcp_sock *tp, 1930static inline void tcp_ack_update_rtt(struct tcp_sock *tp,
2013 int flag, s32 seq_rtt) 1931 int flag, s32 seq_rtt, u32 *usrtt)
2014{ 1932{
2015 /* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */ 1933 /* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */
2016 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) 1934 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
2017 tcp_ack_saw_tstamp(tp, flag); 1935 tcp_ack_saw_tstamp(tp, usrtt, flag);
2018 else if (seq_rtt >= 0) 1936 else if (seq_rtt >= 0)
2019 tcp_ack_no_tstamp(tp, seq_rtt, flag); 1937 tcp_ack_no_tstamp(tp, seq_rtt, usrtt, flag);
2020} 1938}
2021 1939
2022/* 1940static inline void tcp_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
2023 * Compute congestion window to use. 1941 u32 in_flight, int good)
2024 *
2025 * This is from the implementation of BICTCP in
2026 * Lison-Xu, Kahaled Harfoush, and Injog Rhee.
2027 * "Binary Increase Congestion Control for Fast, Long Distance
2028 * Networks" in InfoComm 2004
2029 * Available from:
2030 * http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf
2031 *
2032 * Unless BIC is enabled and congestion window is large
2033 * this behaves the same as the original Reno.
2034 */
2035static inline __u32 bictcp_cwnd(struct tcp_sock *tp)
2036{
2037 /* orignal Reno behaviour */
2038 if (!tcp_is_bic(tp))
2039 return tp->snd_cwnd;
2040
2041 if (tp->bictcp.last_cwnd == tp->snd_cwnd &&
2042 (s32)(tcp_time_stamp - tp->bictcp.last_stamp) <= (HZ>>5))
2043 return tp->bictcp.cnt;
2044
2045 tp->bictcp.last_cwnd = tp->snd_cwnd;
2046 tp->bictcp.last_stamp = tcp_time_stamp;
2047
2048 /* start off normal */
2049 if (tp->snd_cwnd <= sysctl_tcp_bic_low_window)
2050 tp->bictcp.cnt = tp->snd_cwnd;
2051
2052 /* binary increase */
2053 else if (tp->snd_cwnd < tp->bictcp.last_max_cwnd) {
2054 __u32 dist = (tp->bictcp.last_max_cwnd - tp->snd_cwnd)
2055 / BICTCP_B;
2056
2057 if (dist > BICTCP_MAX_INCREMENT)
2058 /* linear increase */
2059 tp->bictcp.cnt = tp->snd_cwnd / BICTCP_MAX_INCREMENT;
2060 else if (dist <= 1U)
2061 /* binary search increase */
2062 tp->bictcp.cnt = tp->snd_cwnd * BICTCP_FUNC_OF_MIN_INCR
2063 / BICTCP_B;
2064 else
2065 /* binary search increase */
2066 tp->bictcp.cnt = tp->snd_cwnd / dist;
2067 } else {
2068 /* slow start amd linear increase */
2069 if (tp->snd_cwnd < tp->bictcp.last_max_cwnd + BICTCP_B)
2070 /* slow start */
2071 tp->bictcp.cnt = tp->snd_cwnd * BICTCP_FUNC_OF_MIN_INCR
2072 / BICTCP_B;
2073 else if (tp->snd_cwnd < tp->bictcp.last_max_cwnd
2074 + BICTCP_MAX_INCREMENT*(BICTCP_B-1))
2075 /* slow start */
2076 tp->bictcp.cnt = tp->snd_cwnd * (BICTCP_B-1)
2077 / (tp->snd_cwnd-tp->bictcp.last_max_cwnd);
2078 else
2079 /* linear increase */
2080 tp->bictcp.cnt = tp->snd_cwnd / BICTCP_MAX_INCREMENT;
2081 }
2082 return tp->bictcp.cnt;
2083}
2084
2085/* This is Jacobson's slow start and congestion avoidance.
2086 * SIGCOMM '88, p. 328.
2087 */
2088static inline void reno_cong_avoid(struct tcp_sock *tp)
2089{ 1942{
2090 if (tp->snd_cwnd <= tp->snd_ssthresh) { 1943 tp->ca_ops->cong_avoid(tp, ack, rtt, in_flight, good);
2091 /* In "safe" area, increase. */
2092 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
2093 tp->snd_cwnd++;
2094 } else {
2095 /* In dangerous area, increase slowly.
2096 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
2097 */
2098 if (tp->snd_cwnd_cnt >= bictcp_cwnd(tp)) {
2099 if (tp->snd_cwnd < tp->snd_cwnd_clamp)
2100 tp->snd_cwnd++;
2101 tp->snd_cwnd_cnt=0;
2102 } else
2103 tp->snd_cwnd_cnt++;
2104 }
2105 tp->snd_cwnd_stamp = tcp_time_stamp; 1944 tp->snd_cwnd_stamp = tcp_time_stamp;
2106} 1945}
2107 1946
2108/* This is based on the congestion detection/avoidance scheme described in
2109 * Lawrence S. Brakmo and Larry L. Peterson.
2110 * "TCP Vegas: End to end congestion avoidance on a global internet."
2111 * IEEE Journal on Selected Areas in Communication, 13(8):1465--1480,
2112 * October 1995. Available from:
2113 * ftp://ftp.cs.arizona.edu/xkernel/Papers/jsac.ps
2114 *
2115 * See http://www.cs.arizona.edu/xkernel/ for their implementation.
2116 * The main aspects that distinguish this implementation from the
2117 * Arizona Vegas implementation are:
2118 * o We do not change the loss detection or recovery mechanisms of
2119 * Linux in any way. Linux already recovers from losses quite well,
2120 * using fine-grained timers, NewReno, and FACK.
2121 * o To avoid the performance penalty imposed by increasing cwnd
2122 * only every-other RTT during slow start, we increase during
2123 * every RTT during slow start, just like Reno.
2124 * o Largely to allow continuous cwnd growth during slow start,
2125 * we use the rate at which ACKs come back as the "actual"
2126 * rate, rather than the rate at which data is sent.
2127 * o To speed convergence to the right rate, we set the cwnd
2128 * to achieve the right ("actual") rate when we exit slow start.
2129 * o To filter out the noise caused by delayed ACKs, we use the
2130 * minimum RTT sample observed during the last RTT to calculate
2131 * the actual rate.
2132 * o When the sender re-starts from idle, it waits until it has
2133 * received ACKs for an entire flight of new data before making
2134 * a cwnd adjustment decision. The original Vegas implementation
2135 * assumed senders never went idle.
2136 */
2137static void vegas_cong_avoid(struct tcp_sock *tp, u32 ack, u32 seq_rtt)
2138{
2139 /* The key players are v_beg_snd_una and v_beg_snd_nxt.
2140 *
2141 * These are so named because they represent the approximate values
2142 * of snd_una and snd_nxt at the beginning of the current RTT. More
2143 * precisely, they represent the amount of data sent during the RTT.
2144 * At the end of the RTT, when we receive an ACK for v_beg_snd_nxt,
2145 * we will calculate that (v_beg_snd_nxt - v_beg_snd_una) outstanding
2146 * bytes of data have been ACKed during the course of the RTT, giving
2147 * an "actual" rate of:
2148 *
2149 * (v_beg_snd_nxt - v_beg_snd_una) / (rtt duration)
2150 *
2151 * Unfortunately, v_beg_snd_una is not exactly equal to snd_una,
2152 * because delayed ACKs can cover more than one segment, so they
2153 * don't line up nicely with the boundaries of RTTs.
2154 *
2155 * Another unfortunate fact of life is that delayed ACKs delay the
2156 * advance of the left edge of our send window, so that the number
2157 * of bytes we send in an RTT is often less than our cwnd will allow.
2158 * So we keep track of our cwnd separately, in v_beg_snd_cwnd.
2159 */
2160
2161 if (after(ack, tp->vegas.beg_snd_nxt)) {
2162 /* Do the Vegas once-per-RTT cwnd adjustment. */
2163 u32 old_wnd, old_snd_cwnd;
2164
2165
2166 /* Here old_wnd is essentially the window of data that was
2167 * sent during the previous RTT, and has all
2168 * been acknowledged in the course of the RTT that ended
2169 * with the ACK we just received. Likewise, old_snd_cwnd
2170 * is the cwnd during the previous RTT.
2171 */
2172 old_wnd = (tp->vegas.beg_snd_nxt - tp->vegas.beg_snd_una) /
2173 tp->mss_cache_std;
2174 old_snd_cwnd = tp->vegas.beg_snd_cwnd;
2175
2176 /* Save the extent of the current window so we can use this
2177 * at the end of the next RTT.
2178 */
2179 tp->vegas.beg_snd_una = tp->vegas.beg_snd_nxt;
2180 tp->vegas.beg_snd_nxt = tp->snd_nxt;
2181 tp->vegas.beg_snd_cwnd = tp->snd_cwnd;
2182
2183 /* Take into account the current RTT sample too, to
2184 * decrease the impact of delayed acks. This double counts
2185 * this sample since we count it for the next window as well,
2186 * but that's not too awful, since we're taking the min,
2187 * rather than averaging.
2188 */
2189 vegas_rtt_calc(tp, seq_rtt);
2190
2191 /* We do the Vegas calculations only if we got enough RTT
2192 * samples that we can be reasonably sure that we got
2193 * at least one RTT sample that wasn't from a delayed ACK.
2194 * If we only had 2 samples total,
2195 * then that means we're getting only 1 ACK per RTT, which
2196 * means they're almost certainly delayed ACKs.
2197 * If we have 3 samples, we should be OK.
2198 */
2199
2200 if (tp->vegas.cntRTT <= 2) {
2201 /* We don't have enough RTT samples to do the Vegas
2202 * calculation, so we'll behave like Reno.
2203 */
2204 if (tp->snd_cwnd > tp->snd_ssthresh)
2205 tp->snd_cwnd++;
2206 } else {
2207 u32 rtt, target_cwnd, diff;
2208
2209 /* We have enough RTT samples, so, using the Vegas
2210 * algorithm, we determine if we should increase or
2211 * decrease cwnd, and by how much.
2212 */
2213
2214 /* Pluck out the RTT we are using for the Vegas
2215 * calculations. This is the min RTT seen during the
2216 * last RTT. Taking the min filters out the effects
2217 * of delayed ACKs, at the cost of noticing congestion
2218 * a bit later.
2219 */
2220 rtt = tp->vegas.minRTT;
2221
2222 /* Calculate the cwnd we should have, if we weren't
2223 * going too fast.
2224 *
2225 * This is:
2226 * (actual rate in segments) * baseRTT
2227 * We keep it as a fixed point number with
2228 * V_PARAM_SHIFT bits to the right of the binary point.
2229 */
2230 target_cwnd = ((old_wnd * tp->vegas.baseRTT)
2231 << V_PARAM_SHIFT) / rtt;
2232
2233 /* Calculate the difference between the window we had,
2234 * and the window we would like to have. This quantity
2235 * is the "Diff" from the Arizona Vegas papers.
2236 *
2237 * Again, this is a fixed point number with
2238 * V_PARAM_SHIFT bits to the right of the binary
2239 * point.
2240 */
2241 diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
2242
2243 if (tp->snd_cwnd < tp->snd_ssthresh) {
2244 /* Slow start. */
2245 if (diff > sysctl_tcp_vegas_gamma) {
2246 /* Going too fast. Time to slow down
2247 * and switch to congestion avoidance.
2248 */
2249 tp->snd_ssthresh = 2;
2250
2251 /* Set cwnd to match the actual rate
2252 * exactly:
2253 * cwnd = (actual rate) * baseRTT
2254 * Then we add 1 because the integer
2255 * truncation robs us of full link
2256 * utilization.
2257 */
2258 tp->snd_cwnd = min(tp->snd_cwnd,
2259 (target_cwnd >>
2260 V_PARAM_SHIFT)+1);
2261
2262 }
2263 } else {
2264 /* Congestion avoidance. */
2265 u32 next_snd_cwnd;
2266
2267 /* Figure out where we would like cwnd
2268 * to be.
2269 */
2270 if (diff > sysctl_tcp_vegas_beta) {
2271 /* The old window was too fast, so
2272 * we slow down.
2273 */
2274 next_snd_cwnd = old_snd_cwnd - 1;
2275 } else if (diff < sysctl_tcp_vegas_alpha) {
2276 /* We don't have enough extra packets
2277 * in the network, so speed up.
2278 */
2279 next_snd_cwnd = old_snd_cwnd + 1;
2280 } else {
2281 /* Sending just as fast as we
2282 * should be.
2283 */
2284 next_snd_cwnd = old_snd_cwnd;
2285 }
2286
2287 /* Adjust cwnd upward or downward, toward the
2288 * desired value.
2289 */
2290 if (next_snd_cwnd > tp->snd_cwnd)
2291 tp->snd_cwnd++;
2292 else if (next_snd_cwnd < tp->snd_cwnd)
2293 tp->snd_cwnd--;
2294 }
2295 }
2296
2297 /* Wipe the slate clean for the next RTT. */
2298 tp->vegas.cntRTT = 0;
2299 tp->vegas.minRTT = 0x7fffffff;
2300 }
2301
2302 /* The following code is executed for every ack we receive,
2303 * except for conditions checked in should_advance_cwnd()
2304 * before the call to tcp_cong_avoid(). Mainly this means that
2305 * we only execute this code if the ack actually acked some
2306 * data.
2307 */
2308
2309 /* If we are in slow start, increase our cwnd in response to this ACK.
2310 * (If we are not in slow start then we are in congestion avoidance,
2311 * and adjust our congestion window only once per RTT. See the code
2312 * above.)
2313 */
2314 if (tp->snd_cwnd <= tp->snd_ssthresh)
2315 tp->snd_cwnd++;
2316
2317 /* to keep cwnd from growing without bound */
2318 tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
2319
2320 /* Make sure that we are never so timid as to reduce our cwnd below
2321 * 2 MSS.
2322 *
2323 * Going below 2 MSS would risk huge delayed ACKs from our receiver.
2324 */
2325 tp->snd_cwnd = max(tp->snd_cwnd, 2U);
2326
2327 tp->snd_cwnd_stamp = tcp_time_stamp;
2328}
2329
2330static inline void tcp_cong_avoid(struct tcp_sock *tp, u32 ack, u32 seq_rtt)
2331{
2332 if (tcp_vegas_enabled(tp))
2333 vegas_cong_avoid(tp, ack, seq_rtt);
2334 else
2335 reno_cong_avoid(tp);
2336}
2337
2338/* Restart timer after forward progress on connection. 1947/* Restart timer after forward progress on connection.
2339 * RFC2988 recommends to restart timer to now+rto. 1948 * RFC2988 recommends to restart timer to now+rto.
2340 */ 1949 */
@@ -2415,13 +2024,18 @@ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
2415 2024
2416 2025
2417/* Remove acknowledged frames from the retransmission queue. */ 2026/* Remove acknowledged frames from the retransmission queue. */
2418static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p) 2027static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt)
2419{ 2028{
2420 struct tcp_sock *tp = tcp_sk(sk); 2029 struct tcp_sock *tp = tcp_sk(sk);
2421 struct sk_buff *skb; 2030 struct sk_buff *skb;
2422 __u32 now = tcp_time_stamp; 2031 __u32 now = tcp_time_stamp;
2423 int acked = 0; 2032 int acked = 0;
2424 __s32 seq_rtt = -1; 2033 __s32 seq_rtt = -1;
2034 struct timeval usnow;
2035 u32 pkts_acked = 0;
2036
2037 if (seq_usrtt)
2038 do_gettimeofday(&usnow);
2425 2039
2426 while ((skb = skb_peek(&sk->sk_write_queue)) && 2040 while ((skb = skb_peek(&sk->sk_write_queue)) &&
2427 skb != sk->sk_send_head) { 2041 skb != sk->sk_send_head) {
@@ -2448,6 +2062,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2448 */ 2062 */
2449 if (!(scb->flags & TCPCB_FLAG_SYN)) { 2063 if (!(scb->flags & TCPCB_FLAG_SYN)) {
2450 acked |= FLAG_DATA_ACKED; 2064 acked |= FLAG_DATA_ACKED;
2065 ++pkts_acked;
2451 } else { 2066 } else {
2452 acked |= FLAG_SYN_ACKED; 2067 acked |= FLAG_SYN_ACKED;
2453 tp->retrans_stamp = 0; 2068 tp->retrans_stamp = 0;
@@ -2461,6 +2076,10 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2461 seq_rtt = -1; 2076 seq_rtt = -1;
2462 } else if (seq_rtt < 0) 2077 } else if (seq_rtt < 0)
2463 seq_rtt = now - scb->when; 2078 seq_rtt = now - scb->when;
2079 if (seq_usrtt)
2080 *seq_usrtt = (usnow.tv_sec - skb->stamp.tv_sec) * 1000000
2081 + (usnow.tv_usec - skb->stamp.tv_usec);
2082
2464 if (sacked & TCPCB_SACKED_ACKED) 2083 if (sacked & TCPCB_SACKED_ACKED)
2465 tp->sacked_out -= tcp_skb_pcount(skb); 2084 tp->sacked_out -= tcp_skb_pcount(skb);
2466 if (sacked & TCPCB_LOST) 2085 if (sacked & TCPCB_LOST)
@@ -2479,8 +2098,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2479 } 2098 }
2480 2099
2481 if (acked&FLAG_ACKED) { 2100 if (acked&FLAG_ACKED) {
2482 tcp_ack_update_rtt(tp, acked, seq_rtt); 2101 tcp_ack_update_rtt(tp, acked, seq_rtt, seq_usrtt);
2483 tcp_ack_packets_out(sk, tp); 2102 tcp_ack_packets_out(sk, tp);
2103
2104 if (tp->ca_ops->pkts_acked)
2105 tp->ca_ops->pkts_acked(tp, pkts_acked);
2484 } 2106 }
2485 2107
2486#if FASTRETRANS_DEBUG > 0 2108#if FASTRETRANS_DEBUG > 0
@@ -2624,257 +2246,6 @@ static void tcp_process_frto(struct sock *sk, u32 prior_snd_una)
2624 tp->frto_counter = (tp->frto_counter + 1) % 3; 2246 tp->frto_counter = (tp->frto_counter + 1) % 3;
2625} 2247}
2626 2248
2627/*
2628 * TCP Westwood+
2629 */
2630
2631/*
2632 * @init_westwood
2633 * This function initializes fields used in TCP Westwood+. We can't
2634 * get no information about RTTmin at this time so we simply set it to
2635 * TCP_WESTWOOD_INIT_RTT. This value was chosen to be too conservative
2636 * since in this way we're sure it will be updated in a consistent
2637 * way as soon as possible. It will reasonably happen within the first
2638 * RTT period of the connection lifetime.
2639 */
2640
2641static void init_westwood(struct sock *sk)
2642{
2643 struct tcp_sock *tp = tcp_sk(sk);
2644
2645 tp->westwood.bw_ns_est = 0;
2646 tp->westwood.bw_est = 0;
2647 tp->westwood.accounted = 0;
2648 tp->westwood.cumul_ack = 0;
2649 tp->westwood.rtt_win_sx = tcp_time_stamp;
2650 tp->westwood.rtt = TCP_WESTWOOD_INIT_RTT;
2651 tp->westwood.rtt_min = TCP_WESTWOOD_INIT_RTT;
2652 tp->westwood.snd_una = tp->snd_una;
2653}
2654
2655/*
2656 * @westwood_do_filter
2657 * Low-pass filter. Implemented using constant coeffients.
2658 */
2659
2660static inline __u32 westwood_do_filter(__u32 a, __u32 b)
2661{
2662 return (((7 * a) + b) >> 3);
2663}
2664
2665static void westwood_filter(struct sock *sk, __u32 delta)
2666{
2667 struct tcp_sock *tp = tcp_sk(sk);
2668
2669 tp->westwood.bw_ns_est =
2670 westwood_do_filter(tp->westwood.bw_ns_est,
2671 tp->westwood.bk / delta);
2672 tp->westwood.bw_est =
2673 westwood_do_filter(tp->westwood.bw_est,
2674 tp->westwood.bw_ns_est);
2675}
2676
2677/*
2678 * @westwood_update_rttmin
2679 * It is used to update RTTmin. In this case we MUST NOT use
2680 * WESTWOOD_RTT_MIN minimum bound since we could be on a LAN!
2681 */
2682
2683static inline __u32 westwood_update_rttmin(const struct sock *sk)
2684{
2685 const struct tcp_sock *tp = tcp_sk(sk);
2686 __u32 rttmin = tp->westwood.rtt_min;
2687
2688 if (tp->westwood.rtt != 0 &&
2689 (tp->westwood.rtt < tp->westwood.rtt_min || !rttmin))
2690 rttmin = tp->westwood.rtt;
2691
2692 return rttmin;
2693}
2694
2695/*
2696 * @westwood_acked
2697 * Evaluate increases for dk.
2698 */
2699
2700static inline __u32 westwood_acked(const struct sock *sk)
2701{
2702 const struct tcp_sock *tp = tcp_sk(sk);
2703
2704 return tp->snd_una - tp->westwood.snd_una;
2705}
2706
2707/*
2708 * @westwood_new_window
2709 * It evaluates if we are receiving data inside the same RTT window as
2710 * when we started.
2711 * Return value:
2712 * It returns 0 if we are still evaluating samples in the same RTT
2713 * window, 1 if the sample has to be considered in the next window.
2714 */
2715
2716static int westwood_new_window(const struct sock *sk)
2717{
2718 const struct tcp_sock *tp = tcp_sk(sk);
2719 __u32 left_bound;
2720 __u32 rtt;
2721 int ret = 0;
2722
2723 left_bound = tp->westwood.rtt_win_sx;
2724 rtt = max(tp->westwood.rtt, (u32) TCP_WESTWOOD_RTT_MIN);
2725
2726 /*
2727 * A RTT-window has passed. Be careful since if RTT is less than
2728 * 50ms we don't filter but we continue 'building the sample'.
2729 * This minimum limit was choosen since an estimation on small
2730 * time intervals is better to avoid...
2731 * Obvioulsy on a LAN we reasonably will always have
2732 * right_bound = left_bound + WESTWOOD_RTT_MIN
2733 */
2734
2735 if ((left_bound + rtt) < tcp_time_stamp)
2736 ret = 1;
2737
2738 return ret;
2739}
2740
2741/*
2742 * @westwood_update_window
2743 * It updates RTT evaluation window if it is the right moment to do
2744 * it. If so it calls filter for evaluating bandwidth.
2745 */
2746
2747static void __westwood_update_window(struct sock *sk, __u32 now)
2748{
2749 struct tcp_sock *tp = tcp_sk(sk);
2750 __u32 delta = now - tp->westwood.rtt_win_sx;
2751
2752 if (delta) {
2753 if (tp->westwood.rtt)
2754 westwood_filter(sk, delta);
2755
2756 tp->westwood.bk = 0;
2757 tp->westwood.rtt_win_sx = tcp_time_stamp;
2758 }
2759}
2760
2761
2762static void westwood_update_window(struct sock *sk, __u32 now)
2763{
2764 if (westwood_new_window(sk))
2765 __westwood_update_window(sk, now);
2766}
2767
2768/*
2769 * @__tcp_westwood_fast_bw
2770 * It is called when we are in fast path. In particular it is called when
2771 * header prediction is successfull. In such case infact update is
2772 * straight forward and doesn't need any particular care.
2773 */
2774
2775static void __tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
2776{
2777 struct tcp_sock *tp = tcp_sk(sk);
2778
2779 westwood_update_window(sk, tcp_time_stamp);
2780
2781 tp->westwood.bk += westwood_acked(sk);
2782 tp->westwood.snd_una = tp->snd_una;
2783 tp->westwood.rtt_min = westwood_update_rttmin(sk);
2784}
2785
2786static inline void tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
2787{
2788 if (tcp_is_westwood(tcp_sk(sk)))
2789 __tcp_westwood_fast_bw(sk, skb);
2790}
2791
2792
2793/*
2794 * @westwood_dupack_update
2795 * It updates accounted and cumul_ack when receiving a dupack.
2796 */
2797
2798static void westwood_dupack_update(struct sock *sk)
2799{
2800 struct tcp_sock *tp = tcp_sk(sk);
2801
2802 tp->westwood.accounted += tp->mss_cache_std;
2803 tp->westwood.cumul_ack = tp->mss_cache_std;
2804}
2805
2806static inline int westwood_may_change_cumul(struct tcp_sock *tp)
2807{
2808 return (tp->westwood.cumul_ack > tp->mss_cache_std);
2809}
2810
2811static inline void westwood_partial_update(struct tcp_sock *tp)
2812{
2813 tp->westwood.accounted -= tp->westwood.cumul_ack;
2814 tp->westwood.cumul_ack = tp->mss_cache_std;
2815}
2816
2817static inline void westwood_complete_update(struct tcp_sock *tp)
2818{
2819 tp->westwood.cumul_ack -= tp->westwood.accounted;
2820 tp->westwood.accounted = 0;
2821}
2822
2823/*
2824 * @westwood_acked_count
2825 * This function evaluates cumul_ack for evaluating dk in case of
2826 * delayed or partial acks.
2827 */
2828
2829static inline __u32 westwood_acked_count(struct sock *sk)
2830{
2831 struct tcp_sock *tp = tcp_sk(sk);
2832
2833 tp->westwood.cumul_ack = westwood_acked(sk);
2834
2835 /* If cumul_ack is 0 this is a dupack since it's not moving
2836 * tp->snd_una.
2837 */
2838 if (!(tp->westwood.cumul_ack))
2839 westwood_dupack_update(sk);
2840
2841 if (westwood_may_change_cumul(tp)) {
2842 /* Partial or delayed ack */
2843 if (tp->westwood.accounted >= tp->westwood.cumul_ack)
2844 westwood_partial_update(tp);
2845 else
2846 westwood_complete_update(tp);
2847 }
2848
2849 tp->westwood.snd_una = tp->snd_una;
2850
2851 return tp->westwood.cumul_ack;
2852}
2853
2854
2855/*
2856 * @__tcp_westwood_slow_bw
2857 * It is called when something is going wrong..even if there could
2858 * be no problems! Infact a simple delayed packet may trigger a
2859 * dupack. But we need to be careful in such case.
2860 */
2861
2862static void __tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
2863{
2864 struct tcp_sock *tp = tcp_sk(sk);
2865
2866 westwood_update_window(sk, tcp_time_stamp);
2867
2868 tp->westwood.bk += westwood_acked_count(sk);
2869 tp->westwood.rtt_min = westwood_update_rttmin(sk);
2870}
2871
2872static inline void tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
2873{
2874 if (tcp_is_westwood(tcp_sk(sk)))
2875 __tcp_westwood_slow_bw(sk, skb);
2876}
2877
2878/* This routine deals with incoming acks, but not outgoing ones. */ 2249/* This routine deals with incoming acks, but not outgoing ones. */
2879static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) 2250static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2880{ 2251{
@@ -2884,6 +2255,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2884 u32 ack = TCP_SKB_CB(skb)->ack_seq; 2255 u32 ack = TCP_SKB_CB(skb)->ack_seq;
2885 u32 prior_in_flight; 2256 u32 prior_in_flight;
2886 s32 seq_rtt; 2257 s32 seq_rtt;
2258 s32 seq_usrtt = 0;
2887 int prior_packets; 2259 int prior_packets;
2888 2260
2889 /* If the ack is newer than sent or older than previous acks 2261 /* If the ack is newer than sent or older than previous acks
@@ -2902,9 +2274,10 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2902 */ 2274 */
2903 tcp_update_wl(tp, ack, ack_seq); 2275 tcp_update_wl(tp, ack, ack_seq);
2904 tp->snd_una = ack; 2276 tp->snd_una = ack;
2905 tcp_westwood_fast_bw(sk, skb);
2906 flag |= FLAG_WIN_UPDATE; 2277 flag |= FLAG_WIN_UPDATE;
2907 2278
2279 tcp_ca_event(tp, CA_EVENT_FAST_ACK);
2280
2908 NET_INC_STATS_BH(LINUX_MIB_TCPHPACKS); 2281 NET_INC_STATS_BH(LINUX_MIB_TCPHPACKS);
2909 } else { 2282 } else {
2910 if (ack_seq != TCP_SKB_CB(skb)->end_seq) 2283 if (ack_seq != TCP_SKB_CB(skb)->end_seq)
@@ -2920,7 +2293,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2920 if (TCP_ECN_rcv_ecn_echo(tp, skb->h.th)) 2293 if (TCP_ECN_rcv_ecn_echo(tp, skb->h.th))
2921 flag |= FLAG_ECE; 2294 flag |= FLAG_ECE;
2922 2295
2923 tcp_westwood_slow_bw(sk,skb); 2296 tcp_ca_event(tp, CA_EVENT_SLOW_ACK);
2924 } 2297 }
2925 2298
2926 /* We passed data and got it acked, remove any soft error 2299 /* We passed data and got it acked, remove any soft error
@@ -2935,22 +2308,20 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
2935 prior_in_flight = tcp_packets_in_flight(tp); 2308 prior_in_flight = tcp_packets_in_flight(tp);
2936 2309
2937 /* See if we can take anything off of the retransmit queue. */ 2310 /* See if we can take anything off of the retransmit queue. */
2938 flag |= tcp_clean_rtx_queue(sk, &seq_rtt); 2311 flag |= tcp_clean_rtx_queue(sk, &seq_rtt,
2312 tp->ca_ops->rtt_sample ? &seq_usrtt : NULL);
2939 2313
2940 if (tp->frto_counter) 2314 if (tp->frto_counter)
2941 tcp_process_frto(sk, prior_snd_una); 2315 tcp_process_frto(sk, prior_snd_una);
2942 2316
2943 if (tcp_ack_is_dubious(tp, flag)) { 2317 if (tcp_ack_is_dubious(tp, flag)) {
2944 /* Advanve CWND, if state allows this. */ 2318 /* Advanve CWND, if state allows this. */
2945 if ((flag & FLAG_DATA_ACKED) && 2319 if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(tp, flag))
2946 (tcp_vegas_enabled(tp) || prior_in_flight >= tp->snd_cwnd) && 2320 tcp_cong_avoid(tp, ack, seq_rtt, prior_in_flight, 0);
2947 tcp_may_raise_cwnd(tp, flag))
2948 tcp_cong_avoid(tp, ack, seq_rtt);
2949 tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag); 2321 tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag);
2950 } else { 2322 } else {
2951 if ((flag & FLAG_DATA_ACKED) && 2323 if ((flag & FLAG_DATA_ACKED))
2952 (tcp_vegas_enabled(tp) || prior_in_flight >= tp->snd_cwnd)) 2324 tcp_cong_avoid(tp, ack, seq_rtt, prior_in_flight, 1);
2953 tcp_cong_avoid(tp, ack, seq_rtt);
2954 } 2325 }
2955 2326
2956 if ((flag & FLAG_FORWARD_PROGRESS) || !(flag&FLAG_NOT_DUP)) 2327 if ((flag & FLAG_FORWARD_PROGRESS) || !(flag&FLAG_NOT_DUP))
@@ -4552,6 +3923,8 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
4552 3923
4553 tcp_init_metrics(sk); 3924 tcp_init_metrics(sk);
4554 3925
3926 tcp_init_congestion_control(tp);
3927
4555 /* Prevent spurious tcp_cwnd_restart() on first data 3928 /* Prevent spurious tcp_cwnd_restart() on first data
4556 * packet. 3929 * packet.
4557 */ 3930 */
@@ -4708,9 +4081,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
4708 if(tp->af_specific->conn_request(sk, skb) < 0) 4081 if(tp->af_specific->conn_request(sk, skb) < 0)
4709 return 1; 4082 return 1;
4710 4083
4711 init_westwood(sk);
4712 init_bictcp(tp);
4713
4714 /* Now we have several options: In theory there is 4084 /* Now we have several options: In theory there is
4715 * nothing else in the frame. KA9Q has an option to 4085 * nothing else in the frame. KA9Q has an option to
4716 * send data with the syn, BSD accepts data with the 4086 * send data with the syn, BSD accepts data with the
@@ -4732,9 +4102,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
4732 goto discard; 4102 goto discard;
4733 4103
4734 case TCP_SYN_SENT: 4104 case TCP_SYN_SENT:
4735 init_westwood(sk);
4736 init_bictcp(tp);
4737
4738 queued = tcp_rcv_synsent_state_process(sk, skb, th, len); 4105 queued = tcp_rcv_synsent_state_process(sk, skb, th, len);
4739 if (queued >= 0) 4106 if (queued >= 0)
4740 return queued; 4107 return queued;
@@ -4816,7 +4183,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
4816 */ 4183 */
4817 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr && 4184 if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
4818 !tp->srtt) 4185 !tp->srtt)
4819 tcp_ack_saw_tstamp(tp, 0); 4186 tcp_ack_saw_tstamp(tp, 0, 0);
4820 4187
4821 if (tp->rx_opt.tstamp_ok) 4188 if (tp->rx_opt.tstamp_ok)
4822 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; 4189 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
@@ -4828,6 +4195,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
4828 4195
4829 tcp_init_metrics(sk); 4196 tcp_init_metrics(sk);
4830 4197
4198 tcp_init_congestion_control(tp);
4199
4831 /* Prevent spurious tcp_cwnd_restart() on 4200 /* Prevent spurious tcp_cwnd_restart() on
4832 * first data packet. 4201 * first data packet.
4833 */ 4202 */
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 2d41d5d6ad19..ebf112347a97 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2048,6 +2048,7 @@ static int tcp_v4_init_sock(struct sock *sk)
2048 tp->mss_cache_std = tp->mss_cache = 536; 2048 tp->mss_cache_std = tp->mss_cache = 536;
2049 2049
2050 tp->reordering = sysctl_tcp_reordering; 2050 tp->reordering = sysctl_tcp_reordering;
2051 tp->ca_ops = &tcp_init_congestion_ops;
2051 2052
2052 sk->sk_state = TCP_CLOSE; 2053 sk->sk_state = TCP_CLOSE;
2053 2054
@@ -2070,6 +2071,8 @@ int tcp_v4_destroy_sock(struct sock *sk)
2070 2071
2071 tcp_clear_xmit_timers(sk); 2072 tcp_clear_xmit_timers(sk);
2072 2073
2074 tcp_cleanup_congestion_control(tp);
2075
2073 /* Cleanup up the write buffer. */ 2076 /* Cleanup up the write buffer. */
2074 sk_stream_writequeue_purge(sk); 2077 sk_stream_writequeue_purge(sk);
2075 2078
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index b3943e7562f3..f42a284164b7 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -774,6 +774,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
774 newtp->frto_counter = 0; 774 newtp->frto_counter = 0;
775 newtp->frto_highmark = 0; 775 newtp->frto_highmark = 0;
776 776
777 newtp->ca_ops = &tcp_reno;
778
777 tcp_set_ca_state(newtp, TCP_CA_Open); 779 tcp_set_ca_state(newtp, TCP_CA_Open);
778 tcp_init_xmit_timers(newsk); 780 tcp_init_xmit_timers(newsk);
779 skb_queue_head_init(&newtp->out_of_order_queue); 781 skb_queue_head_init(&newtp->out_of_order_queue);
@@ -842,8 +844,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
842 if (newtp->ecn_flags&TCP_ECN_OK) 844 if (newtp->ecn_flags&TCP_ECN_OK)
843 sock_set_flag(newsk, SOCK_NO_LARGESEND); 845 sock_set_flag(newsk, SOCK_NO_LARGESEND);
844 846
845 tcp_ca_init(newtp);
846
847 TCP_INC_STATS_BH(TCP_MIB_PASSIVEOPENS); 847 TCP_INC_STATS_BH(TCP_MIB_PASSIVEOPENS);
848 } 848 }
849 return newsk; 849 return newsk;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index f17c6577e337..0e17c244875c 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -111,8 +111,7 @@ static void tcp_cwnd_restart(struct tcp_sock *tp, struct dst_entry *dst)
111 u32 restart_cwnd = tcp_init_cwnd(tp, dst); 111 u32 restart_cwnd = tcp_init_cwnd(tp, dst);
112 u32 cwnd = tp->snd_cwnd; 112 u32 cwnd = tp->snd_cwnd;
113 113
114 if (tcp_is_vegas(tp)) 114 tcp_ca_event(tp, CA_EVENT_CWND_RESTART);
115 tcp_vegas_enable(tp);
116 115
117 tp->snd_ssthresh = tcp_current_ssthresh(tp); 116 tp->snd_ssthresh = tcp_current_ssthresh(tp);
118 restart_cwnd = min(restart_cwnd, cwnd); 117 restart_cwnd = min(restart_cwnd, cwnd);
@@ -280,6 +279,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
280#define SYSCTL_FLAG_WSCALE 0x2 279#define SYSCTL_FLAG_WSCALE 0x2
281#define SYSCTL_FLAG_SACK 0x4 280#define SYSCTL_FLAG_SACK 0x4
282 281
282 /* If congestion control is doing timestamping */
283 if (tp->ca_ops->rtt_sample)
284 do_gettimeofday(&skb->stamp);
285
283 sysctl_flags = 0; 286 sysctl_flags = 0;
284 if (tcb->flags & TCPCB_FLAG_SYN) { 287 if (tcb->flags & TCPCB_FLAG_SYN) {
285 tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS; 288 tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
@@ -304,17 +307,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
304 (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); 307 (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
305 } 308 }
306 309
307 /* 310 if (tcp_packets_in_flight(tp) == 0)
308 * If the connection is idle and we are restarting, 311 tcp_ca_event(tp, CA_EVENT_TX_START);
309 * then we don't want to do any Vegas calculations
310 * until we get fresh RTT samples. So when we
311 * restart, we reset our Vegas state to a clean
312 * slate. After we get acks for this flight of
313 * packets, _then_ we can make Vegas calculations
314 * again.
315 */
316 if (tcp_is_vegas(tp) && tcp_packets_in_flight(tp) == 0)
317 tcp_vegas_enable(tp);
318 312
319 th = (struct tcphdr *) skb_push(skb, tcp_header_size); 313 th = (struct tcphdr *) skb_push(skb, tcp_header_size);
320 skb->h.th = th; 314 skb->h.th = th;
@@ -521,6 +515,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
521 * skbs, which it never sent before. --ANK 515 * skbs, which it never sent before. --ANK
522 */ 516 */
523 TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when; 517 TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
518 buff->stamp = skb->stamp;
524 519
525 if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) { 520 if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
526 tp->lost_out -= tcp_skb_pcount(skb); 521 tp->lost_out -= tcp_skb_pcount(skb);
@@ -1449,7 +1444,6 @@ static inline void tcp_connect_init(struct sock *sk)
1449 tp->window_clamp = dst_metric(dst, RTAX_WINDOW); 1444 tp->window_clamp = dst_metric(dst, RTAX_WINDOW);
1450 tp->advmss = dst_metric(dst, RTAX_ADVMSS); 1445 tp->advmss = dst_metric(dst, RTAX_ADVMSS);
1451 tcp_initialize_rcv_mss(sk); 1446 tcp_initialize_rcv_mss(sk);
1452 tcp_ca_init(tp);
1453 1447
1454 tcp_select_initial_window(tcp_full_space(sk), 1448 tcp_select_initial_window(tcp_full_space(sk),
1455 tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), 1449 tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
@@ -1503,7 +1497,6 @@ int tcp_connect(struct sock *sk)
1503 TCP_SKB_CB(buff)->end_seq = tp->write_seq; 1497 TCP_SKB_CB(buff)->end_seq = tp->write_seq;
1504 tp->snd_nxt = tp->write_seq; 1498 tp->snd_nxt = tp->write_seq;
1505 tp->pushed_seq = tp->write_seq; 1499 tp->pushed_seq = tp->write_seq;
1506 tcp_ca_init(tp);
1507 1500
1508 /* Send it off. */ 1501 /* Send it off. */
1509 TCP_SKB_CB(buff)->when = tcp_time_stamp; 1502 TCP_SKB_CB(buff)->when = tcp_time_stamp;
diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c
new file mode 100644
index 000000000000..70e108e15c71
--- /dev/null
+++ b/net/ipv4/tcp_scalable.c
@@ -0,0 +1,68 @@
1/* Tom Kelly's Scalable TCP
2 *
3 * See htt://www-lce.eng.cam.ac.uk/~ctk21/scalable/
4 *
5 * John Heffner <jheffner@sc.edu>
6 */
7
8#include <linux/config.h>
9#include <linux/module.h>
10#include <net/tcp.h>
11
12/* These factors derived from the recommended values in the aer:
13 * .01 and and 7/8. We use 50 instead of 100 to account for
14 * delayed ack.
15 */
16#define TCP_SCALABLE_AI_CNT 50U
17#define TCP_SCALABLE_MD_SCALE 3
18
19static void tcp_scalable_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
20 u32 in_flight, int flag)
21{
22 if (in_flight < tp->snd_cwnd)
23 return;
24
25 if (tp->snd_cwnd <= tp->snd_ssthresh) {
26 tp->snd_cwnd++;
27 } else {
28 tp->snd_cwnd_cnt++;
29 if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)){
30 tp->snd_cwnd++;
31 tp->snd_cwnd_cnt = 0;
32 }
33 }
34 tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
35 tp->snd_cwnd_stamp = tcp_time_stamp;
36}
37
38static u32 tcp_scalable_ssthresh(struct tcp_sock *tp)
39{
40 return max(tp->snd_cwnd - (tp->snd_cwnd>>TCP_SCALABLE_MD_SCALE), 2U);
41}
42
43
44static struct tcp_congestion_ops tcp_scalable = {
45 .ssthresh = tcp_scalable_ssthresh,
46 .cong_avoid = tcp_scalable_cong_avoid,
47 .min_cwnd = tcp_reno_min_cwnd,
48
49 .owner = THIS_MODULE,
50 .name = "scalable",
51};
52
53static int __init tcp_scalable_register(void)
54{
55 return tcp_register_congestion_control(&tcp_scalable);
56}
57
58static void __exit tcp_scalable_unregister(void)
59{
60 tcp_unregister_congestion_control(&tcp_scalable);
61}
62
63module_init(tcp_scalable_register);
64module_exit(tcp_scalable_unregister);
65
66MODULE_AUTHOR("John Heffner");
67MODULE_LICENSE("GPL");
68MODULE_DESCRIPTION("Scalable TCP");
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
new file mode 100644
index 000000000000..9bd443db5193
--- /dev/null
+++ b/net/ipv4/tcp_vegas.c
@@ -0,0 +1,411 @@
1/*
2 * TCP Vegas congestion control
3 *
4 * This is based on the congestion detection/avoidance scheme described in
5 * Lawrence S. Brakmo and Larry L. Peterson.
6 * "TCP Vegas: End to end congestion avoidance on a global internet."
7 * IEEE Journal on Selected Areas in Communication, 13(8):1465--1480,
8 * October 1995. Available from:
9 * ftp://ftp.cs.arizona.edu/xkernel/Papers/jsac.ps
10 *
11 * See http://www.cs.arizona.edu/xkernel/ for their implementation.
12 * The main aspects that distinguish this implementation from the
13 * Arizona Vegas implementation are:
14 * o We do not change the loss detection or recovery mechanisms of
15 * Linux in any way. Linux already recovers from losses quite well,
16 * using fine-grained timers, NewReno, and FACK.
17 * o To avoid the performance penalty imposed by increasing cwnd
18 * only every-other RTT during slow start, we increase during
19 * every RTT during slow start, just like Reno.
20 * o Largely to allow continuous cwnd growth during slow start,
21 * we use the rate at which ACKs come back as the "actual"
22 * rate, rather than the rate at which data is sent.
23 * o To speed convergence to the right rate, we set the cwnd
24 * to achieve the right ("actual") rate when we exit slow start.
25 * o To filter out the noise caused by delayed ACKs, we use the
26 * minimum RTT sample observed during the last RTT to calculate
27 * the actual rate.
28 * o When the sender re-starts from idle, it waits until it has
29 * received ACKs for an entire flight of new data before making
30 * a cwnd adjustment decision. The original Vegas implementation
31 * assumed senders never went idle.
32 */
33
34#include <linux/config.h>
35#include <linux/mm.h>
36#include <linux/module.h>
37#include <linux/skbuff.h>
38#include <linux/tcp_diag.h>
39
40#include <net/tcp.h>
41
42/* Default values of the Vegas variables, in fixed-point representation
43 * with V_PARAM_SHIFT bits to the right of the binary point.
44 */
45#define V_PARAM_SHIFT 1
46static int alpha = 1<<V_PARAM_SHIFT;
47static int beta = 3<<V_PARAM_SHIFT;
48static int gamma = 1<<V_PARAM_SHIFT;
49
50module_param(alpha, int, 0644);
51MODULE_PARM_DESC(alpha, "lower bound of packets in network (scale by 2)");
52module_param(beta, int, 0644);
53MODULE_PARM_DESC(beta, "upper bound of packets in network (scale by 2)");
54module_param(gamma, int, 0644);
55MODULE_PARM_DESC(gamma, "limit on increase (scale by 2)");
56
57
58/* Vegas variables */
59struct vegas {
60 u32 beg_snd_nxt; /* right edge during last RTT */
61 u32 beg_snd_una; /* left edge during last RTT */
62 u32 beg_snd_cwnd; /* saves the size of the cwnd */
63 u8 doing_vegas_now;/* if true, do vegas for this RTT */
64 u16 cntRTT; /* # of RTTs measured within last RTT */
65 u32 minRTT; /* min of RTTs measured within last RTT (in usec) */
66 u32 baseRTT; /* the min of all Vegas RTT measurements seen (in usec) */
67};
68
69/* There are several situations when we must "re-start" Vegas:
70 *
71 * o when a connection is established
72 * o after an RTO
73 * o after fast recovery
74 * o when we send a packet and there is no outstanding
75 * unacknowledged data (restarting an idle connection)
76 *
77 * In these circumstances we cannot do a Vegas calculation at the
78 * end of the first RTT, because any calculation we do is using
79 * stale info -- both the saved cwnd and congestion feedback are
80 * stale.
81 *
82 * Instead we must wait until the completion of an RTT during
83 * which we actually receive ACKs.
84 */
85static inline void vegas_enable(struct tcp_sock *tp)
86{
87 struct vegas *vegas = tcp_ca(tp);
88
89 /* Begin taking Vegas samples next time we send something. */
90 vegas->doing_vegas_now = 1;
91
92 /* Set the beginning of the next send window. */
93 vegas->beg_snd_nxt = tp->snd_nxt;
94
95 vegas->cntRTT = 0;
96 vegas->minRTT = 0x7fffffff;
97}
98
99/* Stop taking Vegas samples for now. */
100static inline void vegas_disable(struct tcp_sock *tp)
101{
102 struct vegas *vegas = tcp_ca(tp);
103
104 vegas->doing_vegas_now = 0;
105}
106
107static void tcp_vegas_init(struct tcp_sock *tp)
108{
109 struct vegas *vegas = tcp_ca(tp);
110
111 vegas->baseRTT = 0x7fffffff;
112 vegas_enable(tp);
113}
114
115/* Do RTT sampling needed for Vegas.
116 * Basically we:
117 * o min-filter RTT samples from within an RTT to get the current
118 * propagation delay + queuing delay (we are min-filtering to try to
119 * avoid the effects of delayed ACKs)
120 * o min-filter RTT samples from a much longer window (forever for now)
121 * to find the propagation delay (baseRTT)
122 */
123static void tcp_vegas_rtt_calc(struct tcp_sock *tp, u32 usrtt)
124{
125 struct vegas *vegas = tcp_ca(tp);
126 u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */
127
128 /* Filter to find propagation delay: */
129 if (vrtt < vegas->baseRTT)
130 vegas->baseRTT = vrtt;
131
132 /* Find the min RTT during the last RTT to find
133 * the current prop. delay + queuing delay:
134 */
135 vegas->minRTT = min(vegas->minRTT, vrtt);
136 vegas->cntRTT++;
137}
138
139static void tcp_vegas_state(struct tcp_sock *tp, u8 ca_state)
140{
141
142 if (ca_state == TCP_CA_Open)
143 vegas_enable(tp);
144 else
145 vegas_disable(tp);
146}
147
148/*
149 * If the connection is idle and we are restarting,
150 * then we don't want to do any Vegas calculations
151 * until we get fresh RTT samples. So when we
152 * restart, we reset our Vegas state to a clean
153 * slate. After we get acks for this flight of
154 * packets, _then_ we can make Vegas calculations
155 * again.
156 */
157static void tcp_vegas_cwnd_event(struct tcp_sock *tp, enum tcp_ca_event event)
158{
159 if (event == CA_EVENT_CWND_RESTART ||
160 event == CA_EVENT_TX_START)
161 tcp_vegas_init(tp);
162}
163
164static void tcp_vegas_cong_avoid(struct tcp_sock *tp, u32 ack,
165 u32 seq_rtt, u32 in_flight, int flag)
166{
167 struct vegas *vegas = tcp_ca(tp);
168
169 if (!vegas->doing_vegas_now)
170 return tcp_reno_cong_avoid(tp, ack, seq_rtt, in_flight, flag);
171
172 /* The key players are v_beg_snd_una and v_beg_snd_nxt.
173 *
174 * These are so named because they represent the approximate values
175 * of snd_una and snd_nxt at the beginning of the current RTT. More
176 * precisely, they represent the amount of data sent during the RTT.
177 * At the end of the RTT, when we receive an ACK for v_beg_snd_nxt,
178 * we will calculate that (v_beg_snd_nxt - v_beg_snd_una) outstanding
179 * bytes of data have been ACKed during the course of the RTT, giving
180 * an "actual" rate of:
181 *
182 * (v_beg_snd_nxt - v_beg_snd_una) / (rtt duration)
183 *
184 * Unfortunately, v_beg_snd_una is not exactly equal to snd_una,
185 * because delayed ACKs can cover more than one segment, so they
186 * don't line up nicely with the boundaries of RTTs.
187 *
188 * Another unfortunate fact of life is that delayed ACKs delay the
189 * advance of the left edge of our send window, so that the number
190 * of bytes we send in an RTT is often less than our cwnd will allow.
191 * So we keep track of our cwnd separately, in v_beg_snd_cwnd.
192 */
193
194 if (after(ack, vegas->beg_snd_nxt)) {
195 /* Do the Vegas once-per-RTT cwnd adjustment. */
196 u32 old_wnd, old_snd_cwnd;
197
198
199 /* Here old_wnd is essentially the window of data that was
200 * sent during the previous RTT, and has all
201 * been acknowledged in the course of the RTT that ended
202 * with the ACK we just received. Likewise, old_snd_cwnd
203 * is the cwnd during the previous RTT.
204 */
205 old_wnd = (vegas->beg_snd_nxt - vegas->beg_snd_una) /
206 tp->mss_cache;
207 old_snd_cwnd = vegas->beg_snd_cwnd;
208
209 /* Save the extent of the current window so we can use this
210 * at the end of the next RTT.
211 */
212 vegas->beg_snd_una = vegas->beg_snd_nxt;
213 vegas->beg_snd_nxt = tp->snd_nxt;
214 vegas->beg_snd_cwnd = tp->snd_cwnd;
215
216 /* Take into account the current RTT sample too, to
217 * decrease the impact of delayed acks. This double counts
218 * this sample since we count it for the next window as well,
219 * but that's not too awful, since we're taking the min,
220 * rather than averaging.
221 */
222 tcp_vegas_rtt_calc(tp, seq_rtt*1000);
223
224 /* We do the Vegas calculations only if we got enough RTT
225 * samples that we can be reasonably sure that we got
226 * at least one RTT sample that wasn't from a delayed ACK.
227 * If we only had 2 samples total,
228 * then that means we're getting only 1 ACK per RTT, which
229 * means they're almost certainly delayed ACKs.
230 * If we have 3 samples, we should be OK.
231 */
232
233 if (vegas->cntRTT <= 2) {
234 /* We don't have enough RTT samples to do the Vegas
235 * calculation, so we'll behave like Reno.
236 */
237 if (tp->snd_cwnd > tp->snd_ssthresh)
238 tp->snd_cwnd++;
239 } else {
240 u32 rtt, target_cwnd, diff;
241
242 /* We have enough RTT samples, so, using the Vegas
243 * algorithm, we determine if we should increase or
244 * decrease cwnd, and by how much.
245 */
246
247 /* Pluck out the RTT we are using for the Vegas
248 * calculations. This is the min RTT seen during the
249 * last RTT. Taking the min filters out the effects
250 * of delayed ACKs, at the cost of noticing congestion
251 * a bit later.
252 */
253 rtt = vegas->minRTT;
254
255 /* Calculate the cwnd we should have, if we weren't
256 * going too fast.
257 *
258 * This is:
259 * (actual rate in segments) * baseRTT
260 * We keep it as a fixed point number with
261 * V_PARAM_SHIFT bits to the right of the binary point.
262 */
263 target_cwnd = ((old_wnd * vegas->baseRTT)
264 << V_PARAM_SHIFT) / rtt;
265
266 /* Calculate the difference between the window we had,
267 * and the window we would like to have. This quantity
268 * is the "Diff" from the Arizona Vegas papers.
269 *
270 * Again, this is a fixed point number with
271 * V_PARAM_SHIFT bits to the right of the binary
272 * point.
273 */
274 diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
275
276 if (tp->snd_cwnd < tp->snd_ssthresh) {
277 /* Slow start. */
278 if (diff > gamma) {
279 /* Going too fast. Time to slow down
280 * and switch to congestion avoidance.
281 */
282 tp->snd_ssthresh = 2;
283
284 /* Set cwnd to match the actual rate
285 * exactly:
286 * cwnd = (actual rate) * baseRTT
287 * Then we add 1 because the integer
288 * truncation robs us of full link
289 * utilization.
290 */
291 tp->snd_cwnd = min(tp->snd_cwnd,
292 (target_cwnd >>
293 V_PARAM_SHIFT)+1);
294
295 }
296 } else {
297 /* Congestion avoidance. */
298 u32 next_snd_cwnd;
299
300 /* Figure out where we would like cwnd
301 * to be.
302 */
303 if (diff > beta) {
304 /* The old window was too fast, so
305 * we slow down.
306 */
307 next_snd_cwnd = old_snd_cwnd - 1;
308 } else if (diff < alpha) {
309 /* We don't have enough extra packets
310 * in the network, so speed up.
311 */
312 next_snd_cwnd = old_snd_cwnd + 1;
313 } else {
314 /* Sending just as fast as we
315 * should be.
316 */
317 next_snd_cwnd = old_snd_cwnd;
318 }
319
320 /* Adjust cwnd upward or downward, toward the
321 * desired value.
322 */
323 if (next_snd_cwnd > tp->snd_cwnd)
324 tp->snd_cwnd++;
325 else if (next_snd_cwnd < tp->snd_cwnd)
326 tp->snd_cwnd--;
327 }
328 }
329
330 /* Wipe the slate clean for the next RTT. */
331 vegas->cntRTT = 0;
332 vegas->minRTT = 0x7fffffff;
333 }
334
335 /* The following code is executed for every ack we receive,
336 * except for conditions checked in should_advance_cwnd()
337 * before the call to tcp_cong_avoid(). Mainly this means that
338 * we only execute this code if the ack actually acked some
339 * data.
340 */
341
342 /* If we are in slow start, increase our cwnd in response to this ACK.
343 * (If we are not in slow start then we are in congestion avoidance,
344 * and adjust our congestion window only once per RTT. See the code
345 * above.)
346 */
347 if (tp->snd_cwnd <= tp->snd_ssthresh)
348 tp->snd_cwnd++;
349
350 /* to keep cwnd from growing without bound */
351 tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
352
353 /* Make sure that we are never so timid as to reduce our cwnd below
354 * 2 MSS.
355 *
356 * Going below 2 MSS would risk huge delayed ACKs from our receiver.
357 */
358 tp->snd_cwnd = max(tp->snd_cwnd, 2U);
359}
360
361/* Extract info for Tcp socket info provided via netlink. */
362static void tcp_vegas_get_info(struct tcp_sock *tp, u32 ext,
363 struct sk_buff *skb)
364{
365 const struct vegas *ca = tcp_ca(tp);
366 if (ext & (1<<(TCPDIAG_VEGASINFO-1))) {
367 struct tcpvegas_info *info;
368
369 info = RTA_DATA(__RTA_PUT(skb, TCPDIAG_VEGASINFO,
370 sizeof(*info)));
371
372 info->tcpv_enabled = ca->doing_vegas_now;
373 info->tcpv_rttcnt = ca->cntRTT;
374 info->tcpv_rtt = ca->baseRTT;
375 info->tcpv_minrtt = ca->minRTT;
376 rtattr_failure: ;
377 }
378}
379
380static struct tcp_congestion_ops tcp_vegas = {
381 .init = tcp_vegas_init,
382 .ssthresh = tcp_reno_ssthresh,
383 .cong_avoid = tcp_vegas_cong_avoid,
384 .min_cwnd = tcp_reno_min_cwnd,
385 .rtt_sample = tcp_vegas_rtt_calc,
386 .set_state = tcp_vegas_state,
387 .cwnd_event = tcp_vegas_cwnd_event,
388 .get_info = tcp_vegas_get_info,
389
390 .owner = THIS_MODULE,
391 .name = "vegas",
392};
393
394static int __init tcp_vegas_register(void)
395{
396 BUG_ON(sizeof(struct vegas) > TCP_CA_PRIV_SIZE);
397 tcp_register_congestion_control(&tcp_vegas);
398 return 0;
399}
400
401static void __exit tcp_vegas_unregister(void)
402{
403 tcp_unregister_congestion_control(&tcp_vegas);
404}
405
406module_init(tcp_vegas_register);
407module_exit(tcp_vegas_unregister);
408
409MODULE_AUTHOR("Stephen Hemminger");
410MODULE_LICENSE("GPL");
411MODULE_DESCRIPTION("TCP Vegas");
diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c
new file mode 100644
index 000000000000..ef827242c940
--- /dev/null
+++ b/net/ipv4/tcp_westwood.c
@@ -0,0 +1,259 @@
1/*
2 * TCP Westwood+
3 *
4 * Angelo Dell'Aera: TCP Westwood+ support
5 */
6
7#include <linux/config.h>
8#include <linux/mm.h>
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <linux/tcp_diag.h>
12#include <net/tcp.h>
13
14/* TCP Westwood structure */
15struct westwood {
16 u32 bw_ns_est; /* first bandwidth estimation..not too smoothed 8) */
17 u32 bw_est; /* bandwidth estimate */
18 u32 rtt_win_sx; /* here starts a new evaluation... */
19 u32 bk;
20 u32 snd_una; /* used for evaluating the number of acked bytes */
21 u32 cumul_ack;
22 u32 accounted;
23 u32 rtt;
24 u32 rtt_min; /* minimum observed RTT */
25};
26
27
28/* TCP Westwood functions and constants */
29#define TCP_WESTWOOD_RTT_MIN (HZ/20) /* 50ms */
30#define TCP_WESTWOOD_INIT_RTT (20*HZ) /* maybe too conservative?! */
31
32/*
33 * @tcp_westwood_create
34 * This function initializes fields used in TCP Westwood+,
35 * it is called after the initial SYN, so the sequence numbers
36 * are correct but new passive connections we have no
37 * information about RTTmin at this time so we simply set it to
38 * TCP_WESTWOOD_INIT_RTT. This value was chosen to be too conservative
39 * since in this way we're sure it will be updated in a consistent
40 * way as soon as possible. It will reasonably happen within the first
41 * RTT period of the connection lifetime.
42 */
43static void tcp_westwood_init(struct tcp_sock *tp)
44{
45 struct westwood *w = tcp_ca(tp);
46
47 w->bk = 0;
48 w->bw_ns_est = 0;
49 w->bw_est = 0;
50 w->accounted = 0;
51 w->cumul_ack = 0;
52 w->rtt_min = w->rtt = TCP_WESTWOOD_INIT_RTT;
53 w->rtt_win_sx = tcp_time_stamp;
54 w->snd_una = tp->snd_una;
55}
56
57/*
58 * @westwood_do_filter
59 * Low-pass filter. Implemented using constant coefficients.
60 */
61static inline u32 westwood_do_filter(u32 a, u32 b)
62{
63 return (((7 * a) + b) >> 3);
64}
65
66static inline void westwood_filter(struct westwood *w, u32 delta)
67{
68 w->bw_ns_est = westwood_do_filter(w->bw_ns_est, w->bk / delta);
69 w->bw_est = westwood_do_filter(w->bw_est, w->bw_ns_est);
70}
71
72/*
73 * @westwood_pkts_acked
74 * Called after processing group of packets.
75 * but all westwood needs is the last sample of srtt.
76 */
77static void tcp_westwood_pkts_acked(struct tcp_sock *tp, u32 cnt)
78{
79 struct westwood *w = tcp_ca(tp);
80 if (cnt > 0)
81 w->rtt = tp->srtt >> 3;
82}
83
84/*
85 * @westwood_update_window
86 * It updates RTT evaluation window if it is the right moment to do
87 * it. If so it calls filter for evaluating bandwidth.
88 */
89static void westwood_update_window(struct tcp_sock *tp)
90{
91 struct westwood *w = tcp_ca(tp);
92 s32 delta = tcp_time_stamp - w->rtt_win_sx;
93
94 /*
95 * See if a RTT-window has passed.
96 * Be careful since if RTT is less than
97 * 50ms we don't filter but we continue 'building the sample'.
98 * This minimum limit was chosen since an estimation on small
99 * time intervals is better to avoid...
100 * Obviously on a LAN we reasonably will always have
101 * right_bound = left_bound + WESTWOOD_RTT_MIN
102 */
103 if (w->rtt && delta > max_t(u32, w->rtt, TCP_WESTWOOD_RTT_MIN)) {
104 westwood_filter(w, delta);
105
106 w->bk = 0;
107 w->rtt_win_sx = tcp_time_stamp;
108 }
109}
110
111/*
112 * @westwood_fast_bw
113 * It is called when we are in fast path. In particular it is called when
114 * header prediction is successful. In such case in fact update is
115 * straight forward and doesn't need any particular care.
116 */
117static inline void westwood_fast_bw(struct tcp_sock *tp)
118{
119 struct westwood *w = tcp_ca(tp);
120
121 westwood_update_window(tp);
122
123 w->bk += tp->snd_una - w->snd_una;
124 w->snd_una = tp->snd_una;
125 w->rtt_min = min(w->rtt, w->rtt_min);
126}
127
128/*
129 * @westwood_acked_count
130 * This function evaluates cumul_ack for evaluating bk in case of
131 * delayed or partial acks.
132 */
133static inline u32 westwood_acked_count(struct tcp_sock *tp)
134{
135 struct westwood *w = tcp_ca(tp);
136
137 w->cumul_ack = tp->snd_una - w->snd_una;
138
139 /* If cumul_ack is 0 this is a dupack since it's not moving
140 * tp->snd_una.
141 */
142 if (!w->cumul_ack) {
143 w->accounted += tp->mss_cache;
144 w->cumul_ack = tp->mss_cache;
145 }
146
147 if (w->cumul_ack > tp->mss_cache) {
148 /* Partial or delayed ack */
149 if (w->accounted >= w->cumul_ack) {
150 w->accounted -= w->cumul_ack;
151 w->cumul_ack = tp->mss_cache;
152 } else {
153 w->cumul_ack -= w->accounted;
154 w->accounted = 0;
155 }
156 }
157
158 w->snd_una = tp->snd_una;
159
160 return w->cumul_ack;
161}
162
163static inline u32 westwood_bw_rttmin(const struct tcp_sock *tp)
164{
165 struct westwood *w = tcp_ca(tp);
166 return max_t(u32, (w->bw_est * w->rtt_min) / tp->mss_cache, 2);
167}
168
169/*
170 * TCP Westwood
171 * Here limit is evaluated as Bw estimation*RTTmin (for obtaining it
172 * in packets we use mss_cache). Rttmin is guaranteed to be >= 2
173 * so avoids ever returning 0.
174 */
175static u32 tcp_westwood_cwnd_min(struct tcp_sock *tp)
176{
177 return westwood_bw_rttmin(tp);
178}
179
180static void tcp_westwood_event(struct tcp_sock *tp, enum tcp_ca_event event)
181{
182 struct westwood *w = tcp_ca(tp);
183
184 switch(event) {
185 case CA_EVENT_FAST_ACK:
186 westwood_fast_bw(tp);
187 break;
188
189 case CA_EVENT_COMPLETE_CWR:
190 tp->snd_cwnd = tp->snd_ssthresh = westwood_bw_rttmin(tp);
191 break;
192
193 case CA_EVENT_FRTO:
194 tp->snd_ssthresh = westwood_bw_rttmin(tp);
195 break;
196
197 case CA_EVENT_SLOW_ACK:
198 westwood_update_window(tp);
199 w->bk += westwood_acked_count(tp);
200 w->rtt_min = min(w->rtt, w->rtt_min);
201 break;
202
203 default:
204 /* don't care */
205 break;
206 }
207}
208
209
210/* Extract info for Tcp socket info provided via netlink. */
211static void tcp_westwood_info(struct tcp_sock *tp, u32 ext,
212 struct sk_buff *skb)
213{
214 const struct westwood *ca = tcp_ca(tp);
215 if (ext & (1<<(TCPDIAG_VEGASINFO-1))) {
216 struct rtattr *rta;
217 struct tcpvegas_info *info;
218
219 rta = __RTA_PUT(skb, TCPDIAG_VEGASINFO, sizeof(*info));
220 info = RTA_DATA(rta);
221 info->tcpv_enabled = 1;
222 info->tcpv_rttcnt = 0;
223 info->tcpv_rtt = jiffies_to_usecs(ca->rtt);
224 info->tcpv_minrtt = jiffies_to_usecs(ca->rtt_min);
225 rtattr_failure: ;
226 }
227}
228
229
230static struct tcp_congestion_ops tcp_westwood = {
231 .init = tcp_westwood_init,
232 .ssthresh = tcp_reno_ssthresh,
233 .cong_avoid = tcp_reno_cong_avoid,
234 .min_cwnd = tcp_westwood_cwnd_min,
235 .cwnd_event = tcp_westwood_event,
236 .get_info = tcp_westwood_info,
237 .pkts_acked = tcp_westwood_pkts_acked,
238
239 .owner = THIS_MODULE,
240 .name = "westwood"
241};
242
243static int __init tcp_westwood_register(void)
244{
245 BUG_ON(sizeof(struct westwood) > TCP_CA_PRIV_SIZE);
246 return tcp_register_congestion_control(&tcp_westwood);
247}
248
249static void __exit tcp_westwood_unregister(void)
250{
251 tcp_unregister_congestion_control(&tcp_westwood);
252}
253
254module_init(tcp_westwood_register);
255module_exit(tcp_westwood_unregister);
256
257MODULE_AUTHOR("Stephen Hemminger, Angelo Dell'Aera");
258MODULE_LICENSE("GPL");
259MODULE_DESCRIPTION("TCP Westwood+");
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 14f5c53235fe..a54d4ef3fd35 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -57,6 +57,7 @@
57#endif 57#endif
58#include <linux/delay.h> 58#include <linux/delay.h>
59#include <linux/notifier.h> 59#include <linux/notifier.h>
60#include <linux/string.h>
60 61
61#include <net/sock.h> 62#include <net/sock.h>
62#include <net/snmp.h> 63#include <net/snmp.h>
@@ -3437,7 +3438,7 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
3437 * by sysctl and we wouldn't want anyone to change it under our feet 3438 * by sysctl and we wouldn't want anyone to change it under our feet
3438 * (see SIOCSIFNAME). 3439 * (see SIOCSIFNAME).
3439 */ 3440 */
3440 dev_name = net_sysctl_strdup(dev_name); 3441 dev_name = kstrdup(dev_name, GFP_KERNEL);
3441 if (!dev_name) 3442 if (!dev_name)
3442 goto free; 3443 goto free;
3443 3444
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 2414937f2a83..9dac7fdf4726 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2025,7 +2025,7 @@ static int tcp_v6_init_sock(struct sock *sk)
2025 sk->sk_state = TCP_CLOSE; 2025 sk->sk_state = TCP_CLOSE;
2026 2026
2027 tp->af_specific = &ipv6_specific; 2027 tp->af_specific = &ipv6_specific;
2028 2028 tp->ca_ops = &tcp_init_congestion_ops;
2029 sk->sk_write_space = sk_stream_write_space; 2029 sk->sk_write_space = sk_stream_write_space;
2030 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 2030 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
2031 2031
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index b22c9beb604d..447b89e556b1 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -449,6 +449,18 @@ config NET_EMATCH_META
449 To compile this code as a module, choose M here: the 449 To compile this code as a module, choose M here: the
450 module will be called em_meta. 450 module will be called em_meta.
451 451
452config NET_EMATCH_TEXT
453 tristate "Textsearch"
454 depends on NET_EMATCH
455 select TEXTSEARCH
456 ---help---
457 Say Y here if you want to be ablt to classify packets based on
458 textsearch comparisons. Please select the appropriate textsearch
459 algorithms in the Library section.
460
461 To compile this code as a module, choose M here: the
462 module will be called em_text.
463
452config NET_CLS_ACT 464config NET_CLS_ACT
453 bool "Packet ACTION" 465 bool "Packet ACTION"
454 depends on EXPERIMENTAL && NET_CLS && NET_QOS 466 depends on EXPERIMENTAL && NET_CLS && NET_QOS
diff --git a/net/sched/Makefile b/net/sched/Makefile
index eb3fe583eba8..8f58cecd6266 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -40,3 +40,4 @@ obj-$(CONFIG_NET_EMATCH_CMP) += em_cmp.o
40obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o 40obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o
41obj-$(CONFIG_NET_EMATCH_U32) += em_u32.o 41obj-$(CONFIG_NET_EMATCH_U32) += em_u32.o
42obj-$(CONFIG_NET_EMATCH_META) += em_meta.o 42obj-$(CONFIG_NET_EMATCH_META) += em_meta.o
43obj-$(CONFIG_NET_EMATCH_TEXT) += em_text.o
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
new file mode 100644
index 000000000000..873840d8d072
--- /dev/null
+++ b/net/sched/em_text.c
@@ -0,0 +1,157 @@
1/*
2 * net/sched/em_text.c Textsearch ematch
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Thomas Graf <tgraf@suug.ch>
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/string.h>
18#include <linux/skbuff.h>
19#include <linux/textsearch.h>
20#include <linux/tc_ematch/tc_em_text.h>
21#include <net/pkt_cls.h>
22
23struct text_match
24{
25 u16 from_offset;
26 u16 to_offset;
27 u8 from_layer;
28 u8 to_layer;
29 struct ts_config *config;
30};
31
32#define EM_TEXT_PRIV(m) ((struct text_match *) (m)->data)
33
34static int em_text_match(struct sk_buff *skb, struct tcf_ematch *m,
35 struct tcf_pkt_info *info)
36{
37 struct text_match *tm = EM_TEXT_PRIV(m);
38 int from, to;
39 struct ts_state state;
40
41 from = tcf_get_base_ptr(skb, tm->from_layer) - skb->data;
42 from += tm->from_offset;
43
44 to = tcf_get_base_ptr(skb, tm->to_layer) - skb->data;
45 to += tm->to_offset;
46
47 return skb_find_text(skb, from, to, tm->config, &state) != UINT_MAX;
48}
49
50static int em_text_change(struct tcf_proto *tp, void *data, int len,
51 struct tcf_ematch *m)
52{
53 struct text_match *tm;
54 struct tcf_em_text *conf = data;
55 struct ts_config *ts_conf;
56 int flags = 0;
57
58 printk("Configuring text: %s from %d:%d to %d:%d len %d\n", conf->algo, conf->from_offset,
59 conf->from_layer, conf->to_offset, conf->to_layer, conf->pattern_len);
60
61 if (len < sizeof(*conf) || len < (sizeof(*conf) + conf->pattern_len))
62 return -EINVAL;
63
64 if (conf->from_layer > conf->to_layer)
65 return -EINVAL;
66
67 if (conf->from_layer == conf->to_layer &&
68 conf->from_offset > conf->to_offset)
69 return -EINVAL;
70
71retry:
72 ts_conf = textsearch_prepare(conf->algo, (u8 *) conf + sizeof(*conf),
73 conf->pattern_len, GFP_KERNEL, flags);
74
75 if (flags & TS_AUTOLOAD)
76 rtnl_lock();
77
78 if (IS_ERR(ts_conf)) {
79 if (PTR_ERR(ts_conf) == -ENOENT && !(flags & TS_AUTOLOAD)) {
80 rtnl_unlock();
81 flags |= TS_AUTOLOAD;
82 goto retry;
83 } else
84 return PTR_ERR(ts_conf);
85 } else if (flags & TS_AUTOLOAD) {
86 textsearch_destroy(ts_conf);
87 return -EAGAIN;
88 }
89
90 tm = kmalloc(sizeof(*tm), GFP_KERNEL);
91 if (tm == NULL) {
92 textsearch_destroy(ts_conf);
93 return -ENOBUFS;
94 }
95
96 tm->from_offset = conf->from_offset;
97 tm->to_offset = conf->to_offset;
98 tm->from_layer = conf->from_layer;
99 tm->to_layer = conf->to_layer;
100 tm->config = ts_conf;
101
102 m->datalen = sizeof(*tm);
103 m->data = (unsigned long) tm;
104
105 return 0;
106}
107
108static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
109{
110 textsearch_destroy(EM_TEXT_PRIV(m)->config);
111}
112
113static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m)
114{
115 struct text_match *tm = EM_TEXT_PRIV(m);
116 struct tcf_em_text conf;
117
118 strncpy(conf.algo, tm->config->ops->name, sizeof(conf.algo) - 1);
119 conf.from_offset = tm->from_offset;
120 conf.to_offset = tm->to_offset;
121 conf.from_layer = tm->from_layer;
122 conf.to_layer = tm->to_layer;
123 conf.pattern_len = textsearch_get_pattern_len(tm->config);
124 conf.pad = 0;
125
126 RTA_PUT_NOHDR(skb, sizeof(conf), &conf);
127 RTA_APPEND(skb, conf.pattern_len, textsearch_get_pattern(tm->config));
128 return 0;
129
130rtattr_failure:
131 return -1;
132}
133
134static struct tcf_ematch_ops em_text_ops = {
135 .kind = TCF_EM_TEXT,
136 .change = em_text_change,
137 .match = em_text_match,
138 .destroy = em_text_destroy,
139 .dump = em_text_dump,
140 .owner = THIS_MODULE,
141 .link = LIST_HEAD_INIT(em_text_ops.link)
142};
143
144static int __init init_em_text(void)
145{
146 return tcf_em_register(&em_text_ops);
147}
148
149static void __exit exit_em_text(void)
150{
151 tcf_em_unregister(&em_text_ops);
152}
153
154MODULE_LICENSE("GPL");
155
156module_init(init_em_text);
157module_exit(exit_em_text);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 058189684c7c..86073df418f5 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -92,6 +92,17 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
92 sctp_cmd_seq_t *commands); 92 sctp_cmd_seq_t *commands);
93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); 93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
94 94
95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
96 __u16 error,
97 const struct sctp_association *asoc,
98 struct sctp_transport *transport);
99
100static sctp_disposition_t sctp_sf_violation_chunklen(
101 const struct sctp_endpoint *ep,
102 const struct sctp_association *asoc,
103 const sctp_subtype_t type,
104 void *arg,
105 sctp_cmd_seq_t *commands);
95 106
96/* Small helper function that checks if the chunk length 107/* Small helper function that checks if the chunk length
97 * is of the appropriate length. The 'required_length' argument 108 * is of the appropriate length. The 'required_length' argument
@@ -2328,7 +2339,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
2328 * 2339 *
2329 * This is common code called by several sctp_sf_*_abort() functions above. 2340 * This is common code called by several sctp_sf_*_abort() functions above.
2330 */ 2341 */
2331sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 2342static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
2332 __u16 error, 2343 __u16 error,
2333 const struct sctp_association *asoc, 2344 const struct sctp_association *asoc,
2334 struct sctp_transport *transport) 2345 struct sctp_transport *transport)
@@ -3687,7 +3698,8 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
3687 * 3698 *
3688 * Generate an ABORT chunk and terminate the association. 3699 * Generate an ABORT chunk and terminate the association.
3689 */ 3700 */
3690sctp_disposition_t sctp_sf_violation_chunklen(const struct sctp_endpoint *ep, 3701static sctp_disposition_t sctp_sf_violation_chunklen(
3702 const struct sctp_endpoint *ep,
3691 const struct sctp_association *asoc, 3703 const struct sctp_association *asoc,
3692 const sctp_subtype_t type, 3704 const sctp_subtype_t type,
3693 void *arg, 3705 void *arg,
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 32e8acbc60fe..62a073495276 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -41,6 +41,7 @@ EXPORT_SYMBOL(rpc_release_task);
41 41
42/* RPC client functions */ 42/* RPC client functions */
43EXPORT_SYMBOL(rpc_create_client); 43EXPORT_SYMBOL(rpc_create_client);
44EXPORT_SYMBOL(rpc_new_client);
44EXPORT_SYMBOL(rpc_clone_client); 45EXPORT_SYMBOL(rpc_clone_client);
45EXPORT_SYMBOL(rpc_bind_new_program); 46EXPORT_SYMBOL(rpc_bind_new_program);
46EXPORT_SYMBOL(rpc_destroy_client); 47EXPORT_SYMBOL(rpc_destroy_client);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 2b99b4028d31..d6baf6fdf8a9 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -8,6 +8,7 @@
8#include <linux/err.h> 8#include <linux/err.h>
9#include <linux/seq_file.h> 9#include <linux/seq_file.h>
10#include <linux/hash.h> 10#include <linux/hash.h>
11#include <linux/string.h>
11 12
12#define RPCDBG_FACILITY RPCDBG_AUTH 13#define RPCDBG_FACILITY RPCDBG_AUTH
13 14
@@ -20,14 +21,6 @@
20 */ 21 */
21 22
22 23
23static char *strdup(char *s)
24{
25 char *rv = kmalloc(strlen(s)+1, GFP_KERNEL);
26 if (rv)
27 strcpy(rv, s);
28 return rv;
29}
30
31struct unix_domain { 24struct unix_domain {
32 struct auth_domain h; 25 struct auth_domain h;
33 int addr_changes; 26 int addr_changes;
@@ -55,7 +48,7 @@ struct auth_domain *unix_domain_find(char *name)
55 if (new == NULL) 48 if (new == NULL)
56 return NULL; 49 return NULL;
57 cache_init(&new->h.h); 50 cache_init(&new->h.h);
58 new->h.name = strdup(name); 51 new->h.name = kstrdup(name, GFP_KERNEL);
59 new->h.flavour = RPC_AUTH_UNIX; 52 new->h.flavour = RPC_AUTH_UNIX;
60 new->addr_changes = 0; 53 new->addr_changes = 0;
61 new->h.h.expiry_time = NEVER; 54 new->h.h.expiry_time = NEVER;
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 352d531ee3c1..76ba6be3dfc9 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -176,10 +176,10 @@ endif
176define rule_cc_o_c 176define rule_cc_o_c
177 $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \ 177 $(if $($(quiet)cmd_checksrc),echo ' $($(quiet)cmd_checksrc)';) \
178 $(cmd_checksrc) \ 178 $(cmd_checksrc) \
179 $(if $($(quiet)cmd_cc_o_c),echo ' $($(quiet)cmd_cc_o_c)';) \ 179 $(if $($(quiet)cmd_cc_o_c),echo ' $(subst ','\'',$($(quiet)cmd_cc_o_c))';) \
180 $(cmd_cc_o_c); \ 180 $(cmd_cc_o_c); \
181 $(cmd_modversions) \ 181 $(cmd_modversions) \
182 scripts/basic/fixdep $(depfile) $@ '$(cmd_cc_o_c)' > $(@D)/.$(@F).tmp; \ 182 scripts/basic/fixdep $(depfile) $@ '$(subst ','\'',$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp; \
183 rm -f $(depfile); \ 183 rm -f $(depfile); \
184 mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd 184 mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
185endef 185endef
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
index 1e1736d81ee9..ace4706ab251 100644
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -432,8 +432,8 @@
432 <child> 432 <child>
433 <widget class="GtkScrolledWindow" id="scrolledwindow1"> 433 <widget class="GtkScrolledWindow" id="scrolledwindow1">
434 <property name="visible">True</property> 434 <property name="visible">True</property>
435 <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> 435 <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
436 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> 436 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
437 <property name="shadow_type">GTK_SHADOW_IN</property> 437 <property name="shadow_type">GTK_SHADOW_IN</property>
438 <property name="window_placement">GTK_CORNER_TOP_LEFT</property> 438 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
439 439
@@ -466,8 +466,8 @@
466 <child> 466 <child>
467 <widget class="GtkScrolledWindow" id="scrolledwindow2"> 467 <widget class="GtkScrolledWindow" id="scrolledwindow2">
468 <property name="visible">True</property> 468 <property name="visible">True</property>
469 <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> 469 <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
470 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> 470 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
471 <property name="shadow_type">GTK_SHADOW_IN</property> 471 <property name="shadow_type">GTK_SHADOW_IN</property>
472 <property name="window_placement">GTK_CORNER_TOP_LEFT</property> 472 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
473 473
@@ -496,7 +496,7 @@
496 <widget class="GtkScrolledWindow" id="scrolledwindow3"> 496 <widget class="GtkScrolledWindow" id="scrolledwindow3">
497 <property name="visible">True</property> 497 <property name="visible">True</property>
498 <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> 498 <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
499 <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> 499 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
500 <property name="shadow_type">GTK_SHADOW_IN</property> 500 <property name="shadow_type">GTK_SHADOW_IN</property>
501 <property name="window_placement">GTK_CORNER_TOP_LEFT</property> 501 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
502 502
diff --git a/security/commoncap.c b/security/commoncap.c
index 849b8c338ee8..04c12f58d656 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -149,7 +149,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
149 149
150 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid || 150 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
151 !cap_issubset (new_permitted, current->cap_permitted)) { 151 !cap_issubset (new_permitted, current->cap_permitted)) {
152 current->mm->dumpable = 0; 152 current->mm->dumpable = suid_dumpable;
153 153
154 if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) { 154 if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
155 if (!capable(CAP_SETUID)) { 155 if (!capable(CAP_SETUID)) {
diff --git a/security/dummy.c b/security/dummy.c
index b32eff146547..6ff887586479 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -130,7 +130,7 @@ static void dummy_bprm_free_security (struct linux_binprm *bprm)
130static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) 130static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
131{ 131{
132 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) { 132 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
133 current->mm->dumpable = 0; 133 current->mm->dumpable = suid_dumpable;
134 134
135 if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) { 135 if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) {
136 bprm->e_uid = current->uid; 136 bprm->e_uid = current->uid;
diff --git a/security/keys/Makefile b/security/keys/Makefile
index ddb495d65062..c392d750b208 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -7,8 +7,9 @@ obj-y := \
7 keyring.o \ 7 keyring.o \
8 keyctl.o \ 8 keyctl.o \
9 process_keys.o \ 9 process_keys.o \
10 user_defined.o \ 10 request_key.o \
11 request_key.o 11 request_key_auth.o \
12 user_defined.o
12 13
13obj-$(CONFIG_KEYS_COMPAT) += compat.o 14obj-$(CONFIG_KEYS_COMPAT) += compat.o
14obj-$(CONFIG_PROC_FS) += proc.o 15obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/security/keys/compat.c b/security/keys/compat.c
index aff8b22dcb5c..3303673c636e 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -1,6 +1,6 @@
1/* compat.c: 32-bit compatibility syscall for 64-bit systems 1/* compat.c: 32-bit compatibility syscall for 64-bit systems
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,7 @@
24 * - if you can, you should call sys_keyctl directly 24 * - if you can, you should call sys_keyctl directly
25 */ 25 */
26asmlinkage long compat_sys_keyctl(u32 option, 26asmlinkage long compat_sys_keyctl(u32 option,
27 u32 arg2, u32 arg3, u32 arg4, u32 arg5) 27 u32 arg2, u32 arg3, u32 arg4, u32 arg5)
28{ 28{
29 switch (option) { 29 switch (option) {
30 case KEYCTL_GET_KEYRING_ID: 30 case KEYCTL_GET_KEYRING_ID:
@@ -71,6 +71,9 @@ asmlinkage long compat_sys_keyctl(u32 option,
71 case KEYCTL_NEGATE: 71 case KEYCTL_NEGATE:
72 return keyctl_negate_key(arg2, arg3, arg4); 72 return keyctl_negate_key(arg2, arg3, arg4);
73 73
74 case KEYCTL_SET_REQKEY_KEYRING:
75 return keyctl_set_reqkey_keyring(arg2);
76
74 default: 77 default:
75 return -EOPNOTSUPP; 78 return -EOPNOTSUPP;
76 } 79 }
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 67b2b93a7489..46c8602661c9 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -1,6 +1,6 @@
1/* internal.h: authentication token and access key management internal defs 1/* internal.h: authentication token and access key management internal defs
2 * 2 *
3 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -15,6 +15,16 @@
15#include <linux/key.h> 15#include <linux/key.h>
16#include <linux/key-ui.h> 16#include <linux/key-ui.h>
17 17
18#if 0
19#define kenter(FMT, a...) printk("==> %s("FMT")\n",__FUNCTION__ , ## a)
20#define kleave(FMT, a...) printk("<== %s()"FMT"\n",__FUNCTION__ , ## a)
21#define kdebug(FMT, a...) printk(FMT"\n" , ## a)
22#else
23#define kenter(FMT, a...) do {} while(0)
24#define kleave(FMT, a...) do {} while(0)
25#define kdebug(FMT, a...) do {} while(0)
26#endif
27
18extern struct key_type key_type_dead; 28extern struct key_type key_type_dead;
19extern struct key_type key_type_user; 29extern struct key_type key_type_user;
20 30
@@ -66,20 +76,46 @@ extern struct key *__keyring_search_one(struct key *keyring,
66 const char *description, 76 const char *description,
67 key_perm_t perm); 77 key_perm_t perm);
68 78
79extern struct key *keyring_search_instkey(struct key *keyring,
80 key_serial_t target_id);
81
69typedef int (*key_match_func_t)(const struct key *, const void *); 82typedef int (*key_match_func_t)(const struct key *, const void *);
70 83
71extern struct key *keyring_search_aux(struct key *keyring, 84extern struct key *keyring_search_aux(struct key *keyring,
85 struct task_struct *tsk,
72 struct key_type *type, 86 struct key_type *type,
73 const void *description, 87 const void *description,
74 key_match_func_t match); 88 key_match_func_t match);
75 89
76extern struct key *search_process_keyrings_aux(struct key_type *type, 90extern struct key *search_process_keyrings(struct key_type *type,
77 const void *description, 91 const void *description,
78 key_match_func_t match); 92 key_match_func_t match,
93 struct task_struct *tsk);
79 94
80extern struct key *find_keyring_by_name(const char *name, key_serial_t bound); 95extern struct key *find_keyring_by_name(const char *name, key_serial_t bound);
81 96
82extern int install_thread_keyring(struct task_struct *tsk); 97extern int install_thread_keyring(struct task_struct *tsk);
98extern int install_process_keyring(struct task_struct *tsk);
99
100extern struct key *request_key_and_link(struct key_type *type,
101 const char *description,
102 const char *callout_info,
103 struct key *dest_keyring);
104
105/*
106 * request_key authorisation
107 */
108struct request_key_auth {
109 struct key *target_key;
110 struct task_struct *context;
111 pid_t pid;
112};
113
114extern struct key_type key_type_request_key_auth;
115extern struct key *request_key_auth_new(struct key *target,
116 struct key **_rkakey);
117
118extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
83 119
84/* 120/*
85 * keyctl functions 121 * keyctl functions
@@ -100,6 +136,7 @@ extern long keyctl_setperm_key(key_serial_t, key_perm_t);
100extern long keyctl_instantiate_key(key_serial_t, const void __user *, 136extern long keyctl_instantiate_key(key_serial_t, const void __user *,
101 size_t, key_serial_t); 137 size_t, key_serial_t);
102extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); 138extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
139extern long keyctl_set_reqkey_keyring(int);
103 140
104 141
105/* 142/*
diff --git a/security/keys/key.c b/security/keys/key.c
index 59402c843203..3304d37bb379 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
1/* key.c: basic authentication token and access key management 1/* key.c: basic authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -294,7 +294,6 @@ struct key *key_alloc(struct key_type *type, const char *desc,
294 } 294 }
295 295
296 atomic_set(&key->usage, 1); 296 atomic_set(&key->usage, 1);
297 rwlock_init(&key->lock);
298 init_rwsem(&key->sem); 297 init_rwsem(&key->sem);
299 key->type = type; 298 key->type = type;
300 key->user = user; 299 key->user = user;
@@ -308,7 +307,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
308 key->payload.data = NULL; 307 key->payload.data = NULL;
309 308
310 if (!not_in_quota) 309 if (!not_in_quota)
311 key->flags |= KEY_FLAG_IN_QUOTA; 310 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
312 311
313 memset(&key->type_data, 0, sizeof(key->type_data)); 312 memset(&key->type_data, 0, sizeof(key->type_data));
314 313
@@ -359,7 +358,7 @@ int key_payload_reserve(struct key *key, size_t datalen)
359 key_check(key); 358 key_check(key);
360 359
361 /* contemplate the quota adjustment */ 360 /* contemplate the quota adjustment */
362 if (delta != 0 && key->flags & KEY_FLAG_IN_QUOTA) { 361 if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
363 spin_lock(&key->user->lock); 362 spin_lock(&key->user->lock);
364 363
365 if (delta > 0 && 364 if (delta > 0 &&
@@ -392,7 +391,8 @@ EXPORT_SYMBOL(key_payload_reserve);
392static int __key_instantiate_and_link(struct key *key, 391static int __key_instantiate_and_link(struct key *key,
393 const void *data, 392 const void *data,
394 size_t datalen, 393 size_t datalen,
395 struct key *keyring) 394 struct key *keyring,
395 struct key *instkey)
396{ 396{
397 int ret, awaken; 397 int ret, awaken;
398 398
@@ -405,27 +405,25 @@ static int __key_instantiate_and_link(struct key *key,
405 down_write(&key_construction_sem); 405 down_write(&key_construction_sem);
406 406
407 /* can't instantiate twice */ 407 /* can't instantiate twice */
408 if (!(key->flags & KEY_FLAG_INSTANTIATED)) { 408 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
409 /* instantiate the key */ 409 /* instantiate the key */
410 ret = key->type->instantiate(key, data, datalen); 410 ret = key->type->instantiate(key, data, datalen);
411 411
412 if (ret == 0) { 412 if (ret == 0) {
413 /* mark the key as being instantiated */ 413 /* mark the key as being instantiated */
414 write_lock(&key->lock);
415
416 atomic_inc(&key->user->nikeys); 414 atomic_inc(&key->user->nikeys);
417 key->flags |= KEY_FLAG_INSTANTIATED; 415 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
418 416
419 if (key->flags & KEY_FLAG_USER_CONSTRUCT) { 417 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
420 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
421 awaken = 1; 418 awaken = 1;
422 }
423
424 write_unlock(&key->lock);
425 419
426 /* and link it into the destination keyring */ 420 /* and link it into the destination keyring */
427 if (keyring) 421 if (keyring)
428 ret = __key_link(keyring, key); 422 ret = __key_link(keyring, key);
423
424 /* disable the authorisation key */
425 if (instkey)
426 key_revoke(instkey);
429 } 427 }
430 } 428 }
431 429
@@ -446,19 +444,21 @@ static int __key_instantiate_and_link(struct key *key,
446int key_instantiate_and_link(struct key *key, 444int key_instantiate_and_link(struct key *key,
447 const void *data, 445 const void *data,
448 size_t datalen, 446 size_t datalen,
449 struct key *keyring) 447 struct key *keyring,
448 struct key *instkey)
450{ 449{
451 int ret; 450 int ret;
452 451
453 if (keyring) 452 if (keyring)
454 down_write(&keyring->sem); 453 down_write(&keyring->sem);
455 454
456 ret = __key_instantiate_and_link(key, data, datalen, keyring); 455 ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey);
457 456
458 if (keyring) 457 if (keyring)
459 up_write(&keyring->sem); 458 up_write(&keyring->sem);
460 459
461 return ret; 460 return ret;
461
462} /* end key_instantiate_and_link() */ 462} /* end key_instantiate_and_link() */
463 463
464EXPORT_SYMBOL(key_instantiate_and_link); 464EXPORT_SYMBOL(key_instantiate_and_link);
@@ -469,7 +469,8 @@ EXPORT_SYMBOL(key_instantiate_and_link);
469 */ 469 */
470int key_negate_and_link(struct key *key, 470int key_negate_and_link(struct key *key,
471 unsigned timeout, 471 unsigned timeout,
472 struct key *keyring) 472 struct key *keyring,
473 struct key *instkey)
473{ 474{
474 struct timespec now; 475 struct timespec now;
475 int ret, awaken; 476 int ret, awaken;
@@ -486,26 +487,26 @@ int key_negate_and_link(struct key *key,
486 down_write(&key_construction_sem); 487 down_write(&key_construction_sem);
487 488
488 /* can't instantiate twice */ 489 /* can't instantiate twice */
489 if (!(key->flags & KEY_FLAG_INSTANTIATED)) { 490 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
490 /* mark the key as being negatively instantiated */ 491 /* mark the key as being negatively instantiated */
491 write_lock(&key->lock);
492
493 atomic_inc(&key->user->nikeys); 492 atomic_inc(&key->user->nikeys);
494 key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE; 493 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
494 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
495 now = current_kernel_time(); 495 now = current_kernel_time();
496 key->expiry = now.tv_sec + timeout; 496 key->expiry = now.tv_sec + timeout;
497 497
498 if (key->flags & KEY_FLAG_USER_CONSTRUCT) { 498 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
499 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
500 awaken = 1; 499 awaken = 1;
501 }
502 500
503 write_unlock(&key->lock);
504 ret = 0; 501 ret = 0;
505 502
506 /* and link it into the destination keyring */ 503 /* and link it into the destination keyring */
507 if (keyring) 504 if (keyring)
508 ret = __key_link(keyring, key); 505 ret = __key_link(keyring, key);
506
507 /* disable the authorisation key */
508 if (instkey)
509 key_revoke(instkey);
509 } 510 }
510 511
511 up_write(&key_construction_sem); 512 up_write(&key_construction_sem);
@@ -553,8 +554,10 @@ static void key_cleanup(void *data)
553 rb_erase(&key->serial_node, &key_serial_tree); 554 rb_erase(&key->serial_node, &key_serial_tree);
554 spin_unlock(&key_serial_lock); 555 spin_unlock(&key_serial_lock);
555 556
557 key_check(key);
558
556 /* deal with the user's key tracking and quota */ 559 /* deal with the user's key tracking and quota */
557 if (key->flags & KEY_FLAG_IN_QUOTA) { 560 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
558 spin_lock(&key->user->lock); 561 spin_lock(&key->user->lock);
559 key->user->qnkeys--; 562 key->user->qnkeys--;
560 key->user->qnbytes -= key->quotalen; 563 key->user->qnbytes -= key->quotalen;
@@ -562,7 +565,7 @@ static void key_cleanup(void *data)
562 } 565 }
563 566
564 atomic_dec(&key->user->nkeys); 567 atomic_dec(&key->user->nkeys);
565 if (key->flags & KEY_FLAG_INSTANTIATED) 568 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
566 atomic_dec(&key->user->nikeys); 569 atomic_dec(&key->user->nikeys);
567 570
568 key_user_put(key->user); 571 key_user_put(key->user);
@@ -631,9 +634,9 @@ struct key *key_lookup(key_serial_t id)
631 goto error; 634 goto error;
632 635
633 found: 636 found:
634 /* pretent doesn't exist if it's dead */ 637 /* pretend it doesn't exist if it's dead */
635 if (atomic_read(&key->usage) == 0 || 638 if (atomic_read(&key->usage) == 0 ||
636 (key->flags & KEY_FLAG_DEAD) || 639 test_bit(KEY_FLAG_DEAD, &key->flags) ||
637 key->type == &key_type_dead) 640 key->type == &key_type_dead)
638 goto not_found; 641 goto not_found;
639 642
@@ -708,12 +711,9 @@ static inline struct key *__key_update(struct key *key, const void *payload,
708 711
709 ret = key->type->update(key, payload, plen); 712 ret = key->type->update(key, payload, plen);
710 713
711 if (ret == 0) { 714 if (ret == 0)
712 /* updating a negative key instantiates it */ 715 /* updating a negative key instantiates it */
713 write_lock(&key->lock); 716 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
714 key->flags &= ~KEY_FLAG_NEGATIVE;
715 write_unlock(&key->lock);
716 }
717 717
718 up_write(&key->sem); 718 up_write(&key->sem);
719 719
@@ -793,7 +793,7 @@ struct key *key_create_or_update(struct key *keyring,
793 } 793 }
794 794
795 /* instantiate it and link it into the target keyring */ 795 /* instantiate it and link it into the target keyring */
796 ret = __key_instantiate_and_link(key, payload, plen, keyring); 796 ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
797 if (ret < 0) { 797 if (ret < 0) {
798 key_put(key); 798 key_put(key);
799 key = ERR_PTR(ret); 799 key = ERR_PTR(ret);
@@ -841,12 +841,9 @@ int key_update(struct key *key, const void *payload, size_t plen)
841 down_write(&key->sem); 841 down_write(&key->sem);
842 ret = key->type->update(key, payload, plen); 842 ret = key->type->update(key, payload, plen);
843 843
844 if (ret == 0) { 844 if (ret == 0)
845 /* updating a negative key instantiates it */ 845 /* updating a negative key instantiates it */
846 write_lock(&key->lock); 846 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
847 key->flags &= ~KEY_FLAG_NEGATIVE;
848 write_unlock(&key->lock);
849 }
850 847
851 up_write(&key->sem); 848 up_write(&key->sem);
852 } 849 }
@@ -892,10 +889,7 @@ struct key *key_duplicate(struct key *source, const char *desc)
892 goto error2; 889 goto error2;
893 890
894 atomic_inc(&key->user->nikeys); 891 atomic_inc(&key->user->nikeys);
895 892 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
896 write_lock(&key->lock);
897 key->flags |= KEY_FLAG_INSTANTIATED;
898 write_unlock(&key->lock);
899 893
900 error_k: 894 error_k:
901 up_read(&key_types_sem); 895 up_read(&key_types_sem);
@@ -922,9 +916,7 @@ void key_revoke(struct key *key)
922 /* make sure no one's trying to change or use the key when we mark 916 /* make sure no one's trying to change or use the key when we mark
923 * it */ 917 * it */
924 down_write(&key->sem); 918 down_write(&key->sem);
925 write_lock(&key->lock); 919 set_bit(KEY_FLAG_REVOKED, &key->flags);
926 key->flags |= KEY_FLAG_REVOKED;
927 write_unlock(&key->lock);
928 up_write(&key->sem); 920 up_write(&key->sem);
929 921
930} /* end key_revoke() */ 922} /* end key_revoke() */
@@ -975,24 +967,33 @@ void unregister_key_type(struct key_type *ktype)
975 /* withdraw the key type */ 967 /* withdraw the key type */
976 list_del_init(&ktype->link); 968 list_del_init(&ktype->link);
977 969
978 /* need to withdraw all keys of this type */ 970 /* mark all the keys of this type dead */
979 spin_lock(&key_serial_lock); 971 spin_lock(&key_serial_lock);
980 972
981 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { 973 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
982 key = rb_entry(_n, struct key, serial_node); 974 key = rb_entry(_n, struct key, serial_node);
983 975
984 if (key->type != ktype) 976 if (key->type == ktype)
985 continue; 977 key->type = &key_type_dead;
978 }
979
980 spin_unlock(&key_serial_lock);
981
982 /* make sure everyone revalidates their keys */
983 synchronize_kernel();
986 984
987 write_lock(&key->lock); 985 /* we should now be able to destroy the payloads of all the keys of
988 key->type = &key_type_dead; 986 * this type with impunity */
989 write_unlock(&key->lock); 987 spin_lock(&key_serial_lock);
988
989 for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
990 key = rb_entry(_n, struct key, serial_node);
990 991
991 /* there shouldn't be anyone looking at the description or 992 if (key->type == ktype) {
992 * payload now */ 993 if (ktype->destroy)
993 if (ktype->destroy) 994 ktype->destroy(key);
994 ktype->destroy(key); 995 memset(&key->payload, 0xbd, sizeof(key->payload));
995 memset(&key->payload, 0xbd, sizeof(key->payload)); 996 }
996 } 997 }
997 998
998 spin_unlock(&key_serial_lock); 999 spin_unlock(&key_serial_lock);
@@ -1037,4 +1038,5 @@ void __init key_init(void)
1037 1038
1038 /* link the two root keyrings together */ 1039 /* link the two root keyrings together */
1039 key_link(&root_session_keyring, &root_user_keyring); 1040 key_link(&root_session_keyring, &root_user_keyring);
1041
1040} /* end key_init() */ 1042} /* end key_init() */
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index dc0011b3fac9..fea262860ea0 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1,6 +1,6 @@
1/* keyctl.c: userspace keyctl operations 1/* keyctl.c: userspace keyctl operations
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -49,6 +49,13 @@ asmlinkage long sys_add_key(const char __user *_type,
49 goto error; 49 goto error;
50 type[31] = '\0'; 50 type[31] = '\0';
51 51
52 if (!type[0])
53 goto error;
54
55 ret = -EPERM;
56 if (type[0] == '.')
57 goto error;
58
52 ret = -EFAULT; 59 ret = -EFAULT;
53 dlen = strnlen_user(_description, PAGE_SIZE - 1); 60 dlen = strnlen_user(_description, PAGE_SIZE - 1);
54 if (dlen <= 0) 61 if (dlen <= 0)
@@ -82,7 +89,7 @@ asmlinkage long sys_add_key(const char __user *_type,
82 } 89 }
83 90
84 /* find the target keyring (which must be writable) */ 91 /* find the target keyring (which must be writable) */
85 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 92 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
86 if (IS_ERR(keyring)) { 93 if (IS_ERR(keyring)) {
87 ret = PTR_ERR(keyring); 94 ret = PTR_ERR(keyring);
88 goto error3; 95 goto error3;
@@ -181,7 +188,7 @@ asmlinkage long sys_request_key(const char __user *_type,
181 /* get the destination keyring if specified */ 188 /* get the destination keyring if specified */
182 dest = NULL; 189 dest = NULL;
183 if (destringid) { 190 if (destringid) {
184 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE); 191 dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
185 if (IS_ERR(dest)) { 192 if (IS_ERR(dest)) {
186 ret = PTR_ERR(dest); 193 ret = PTR_ERR(dest);
187 goto error3; 194 goto error3;
@@ -196,23 +203,15 @@ asmlinkage long sys_request_key(const char __user *_type,
196 } 203 }
197 204
198 /* do the search */ 205 /* do the search */
199 key = request_key(ktype, description, callout_info); 206 key = request_key_and_link(ktype, description, callout_info, dest);
200 if (IS_ERR(key)) { 207 if (IS_ERR(key)) {
201 ret = PTR_ERR(key); 208 ret = PTR_ERR(key);
202 goto error5; 209 goto error5;
203 } 210 }
204 211
205 /* link the resulting key to the destination keyring */
206 if (dest) {
207 ret = key_link(dest, key);
208 if (ret < 0)
209 goto error6;
210 }
211
212 ret = key->serial; 212 ret = key->serial;
213 213
214 error6: 214 key_put(key);
215 key_put(key);
216 error5: 215 error5:
217 key_type_put(ktype); 216 key_type_put(ktype);
218 error4: 217 error4:
@@ -237,7 +236,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
237 struct key *key; 236 struct key *key;
238 long ret; 237 long ret;
239 238
240 key = lookup_user_key(id, create, 0, KEY_SEARCH); 239 key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
241 if (IS_ERR(key)) { 240 if (IS_ERR(key)) {
242 ret = PTR_ERR(key); 241 ret = PTR_ERR(key);
243 goto error; 242 goto error;
@@ -324,7 +323,7 @@ long keyctl_update_key(key_serial_t id,
324 } 323 }
325 324
326 /* find the target key (which must be writable) */ 325 /* find the target key (which must be writable) */
327 key = lookup_user_key(id, 0, 0, KEY_WRITE); 326 key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
328 if (IS_ERR(key)) { 327 if (IS_ERR(key)) {
329 ret = PTR_ERR(key); 328 ret = PTR_ERR(key);
330 goto error2; 329 goto error2;
@@ -352,7 +351,7 @@ long keyctl_revoke_key(key_serial_t id)
352 struct key *key; 351 struct key *key;
353 long ret; 352 long ret;
354 353
355 key = lookup_user_key(id, 0, 0, KEY_WRITE); 354 key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
356 if (IS_ERR(key)) { 355 if (IS_ERR(key)) {
357 ret = PTR_ERR(key); 356 ret = PTR_ERR(key);
358 goto error; 357 goto error;
@@ -378,7 +377,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
378 struct key *keyring; 377 struct key *keyring;
379 long ret; 378 long ret;
380 379
381 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 380 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
382 if (IS_ERR(keyring)) { 381 if (IS_ERR(keyring)) {
383 ret = PTR_ERR(keyring); 382 ret = PTR_ERR(keyring);
384 goto error; 383 goto error;
@@ -404,13 +403,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
404 struct key *keyring, *key; 403 struct key *keyring, *key;
405 long ret; 404 long ret;
406 405
407 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 406 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
408 if (IS_ERR(keyring)) { 407 if (IS_ERR(keyring)) {
409 ret = PTR_ERR(keyring); 408 ret = PTR_ERR(keyring);
410 goto error; 409 goto error;
411 } 410 }
412 411
413 key = lookup_user_key(id, 1, 0, KEY_LINK); 412 key = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
414 if (IS_ERR(key)) { 413 if (IS_ERR(key)) {
415 ret = PTR_ERR(key); 414 ret = PTR_ERR(key);
416 goto error2; 415 goto error2;
@@ -438,13 +437,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
438 struct key *keyring, *key; 437 struct key *keyring, *key;
439 long ret; 438 long ret;
440 439
441 keyring = lookup_user_key(ringid, 0, 0, KEY_WRITE); 440 keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
442 if (IS_ERR(keyring)) { 441 if (IS_ERR(keyring)) {
443 ret = PTR_ERR(keyring); 442 ret = PTR_ERR(keyring);
444 goto error; 443 goto error;
445 } 444 }
446 445
447 key = lookup_user_key(id, 0, 0, 0); 446 key = lookup_user_key(NULL, id, 0, 0, 0);
448 if (IS_ERR(key)) { 447 if (IS_ERR(key)) {
449 ret = PTR_ERR(key); 448 ret = PTR_ERR(key);
450 goto error2; 449 goto error2;
@@ -475,16 +474,29 @@ long keyctl_describe_key(key_serial_t keyid,
475 char __user *buffer, 474 char __user *buffer,
476 size_t buflen) 475 size_t buflen)
477{ 476{
478 struct key *key; 477 struct key *key, *instkey;
479 char *tmpbuf; 478 char *tmpbuf;
480 long ret; 479 long ret;
481 480
482 key = lookup_user_key(keyid, 0, 1, KEY_VIEW); 481 key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
483 if (IS_ERR(key)) { 482 if (IS_ERR(key)) {
483 /* viewing a key under construction is permitted if we have the
484 * authorisation token handy */
485 if (PTR_ERR(key) == -EACCES) {
486 instkey = key_get_instantiation_authkey(keyid);
487 if (!IS_ERR(instkey)) {
488 key_put(instkey);
489 key = lookup_user_key(NULL, keyid, 0, 1, 0);
490 if (!IS_ERR(key))
491 goto okay;
492 }
493 }
494
484 ret = PTR_ERR(key); 495 ret = PTR_ERR(key);
485 goto error; 496 goto error;
486 } 497 }
487 498
499okay:
488 /* calculate how much description we're going to return */ 500 /* calculate how much description we're going to return */
489 ret = -ENOMEM; 501 ret = -ENOMEM;
490 tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); 502 tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -568,7 +580,7 @@ long keyctl_keyring_search(key_serial_t ringid,
568 goto error2; 580 goto error2;
569 581
570 /* get the keyring at which to begin the search */ 582 /* get the keyring at which to begin the search */
571 keyring = lookup_user_key(ringid, 0, 0, KEY_SEARCH); 583 keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
572 if (IS_ERR(keyring)) { 584 if (IS_ERR(keyring)) {
573 ret = PTR_ERR(keyring); 585 ret = PTR_ERR(keyring);
574 goto error2; 586 goto error2;
@@ -577,7 +589,7 @@ long keyctl_keyring_search(key_serial_t ringid,
577 /* get the destination keyring if specified */ 589 /* get the destination keyring if specified */
578 dest = NULL; 590 dest = NULL;
579 if (destringid) { 591 if (destringid) {
580 dest = lookup_user_key(destringid, 1, 0, KEY_WRITE); 592 dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
581 if (IS_ERR(dest)) { 593 if (IS_ERR(dest)) {
582 ret = PTR_ERR(dest); 594 ret = PTR_ERR(dest);
583 goto error3; 595 goto error3;
@@ -656,24 +668,23 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
656 long ret; 668 long ret;
657 669
658 /* find the key first */ 670 /* find the key first */
659 key = lookup_user_key(keyid, 0, 0, 0); 671 key = lookup_user_key(NULL, keyid, 0, 0, 0);
660 if (!IS_ERR(key)) { 672 if (!IS_ERR(key)) {
661 /* see if we can read it directly */ 673 /* see if we can read it directly */
662 if (key_permission(key, KEY_READ)) 674 if (key_permission(key, KEY_READ))
663 goto can_read_key; 675 goto can_read_key;
664 676
665 /* can't; see if it's searchable from this process's 677 /* we can't; see if it's searchable from this process's
666 * keyrings */ 678 * keyrings
667 ret = -ENOKEY; 679 * - we automatically take account of the fact that it may be
668 if (key_permission(key, KEY_SEARCH)) { 680 * dangling off an instantiation key
669 /* okay - we do have search permission on the key 681 */
670 * itself, but do we have the key? */ 682 skey = search_process_keyrings(key->type, key,
671 skey = search_process_keyrings_aux(key->type, key, 683 keyctl_read_key_same, current);
672 keyctl_read_key_same); 684 if (!IS_ERR(skey))
673 if (!IS_ERR(skey)) 685 goto can_read_key2;
674 goto can_read_key2; 686
675 } 687 ret = PTR_ERR(skey);
676
677 goto error2; 688 goto error2;
678 } 689 }
679 690
@@ -719,7 +730,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
719 if (uid == (uid_t) -1 && gid == (gid_t) -1) 730 if (uid == (uid_t) -1 && gid == (gid_t) -1)
720 goto error; 731 goto error;
721 732
722 key = lookup_user_key(id, 1, 1, 0); 733 key = lookup_user_key(NULL, id, 1, 1, 0);
723 if (IS_ERR(key)) { 734 if (IS_ERR(key)) {
724 ret = PTR_ERR(key); 735 ret = PTR_ERR(key);
725 goto error; 736 goto error;
@@ -728,7 +739,6 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
728 /* make the changes with the locks held to prevent chown/chown races */ 739 /* make the changes with the locks held to prevent chown/chown races */
729 ret = -EACCES; 740 ret = -EACCES;
730 down_write(&key->sem); 741 down_write(&key->sem);
731 write_lock(&key->lock);
732 742
733 if (!capable(CAP_SYS_ADMIN)) { 743 if (!capable(CAP_SYS_ADMIN)) {
734 /* only the sysadmin can chown a key to some other UID */ 744 /* only the sysadmin can chown a key to some other UID */
@@ -755,7 +765,6 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
755 ret = 0; 765 ret = 0;
756 766
757 no_access: 767 no_access:
758 write_unlock(&key->lock);
759 up_write(&key->sem); 768 up_write(&key->sem);
760 key_put(key); 769 key_put(key);
761 error: 770 error:
@@ -778,32 +787,25 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
778 if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 787 if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
779 goto error; 788 goto error;
780 789
781 key = lookup_user_key(id, 1, 1, 0); 790 key = lookup_user_key(NULL, id, 1, 1, 0);
782 if (IS_ERR(key)) { 791 if (IS_ERR(key)) {
783 ret = PTR_ERR(key); 792 ret = PTR_ERR(key);
784 goto error; 793 goto error;
785 } 794 }
786 795
787 /* make the changes with the locks held to prevent chown/chmod 796 /* make the changes with the locks held to prevent chown/chmod races */
788 * races */
789 ret = -EACCES; 797 ret = -EACCES;
790 down_write(&key->sem); 798 down_write(&key->sem);
791 write_lock(&key->lock);
792 799
793 /* if we're not the sysadmin, we can only chmod a key that we 800 /* if we're not the sysadmin, we can only change a key that we own */
794 * own */ 801 if (capable(CAP_SYS_ADMIN) || key->uid == current->fsuid) {
795 if (!capable(CAP_SYS_ADMIN) && key->uid != current->fsuid) 802 key->perm = perm;
796 goto no_access; 803 ret = 0;
797 804 }
798 /* changing the permissions mask */
799 key->perm = perm;
800 ret = 0;
801 805
802 no_access:
803 write_unlock(&key->lock);
804 up_write(&key->sem); 806 up_write(&key->sem);
805 key_put(key); 807 key_put(key);
806 error: 808error:
807 return ret; 809 return ret;
808 810
809} /* end keyctl_setperm_key() */ 811} /* end keyctl_setperm_key() */
@@ -818,7 +820,8 @@ long keyctl_instantiate_key(key_serial_t id,
818 size_t plen, 820 size_t plen,
819 key_serial_t ringid) 821 key_serial_t ringid)
820{ 822{
821 struct key *key, *keyring; 823 struct request_key_auth *rka;
824 struct key *instkey, *keyring;
822 void *payload; 825 void *payload;
823 long ret; 826 long ret;
824 827
@@ -840,18 +843,21 @@ long keyctl_instantiate_key(key_serial_t id,
840 goto error2; 843 goto error2;
841 } 844 }
842 845
843 /* find the target key (which must be writable) */ 846 /* find the instantiation authorisation key */
844 key = lookup_user_key(id, 0, 1, KEY_WRITE); 847 instkey = key_get_instantiation_authkey(id);
845 if (IS_ERR(key)) { 848 if (IS_ERR(instkey)) {
846 ret = PTR_ERR(key); 849 ret = PTR_ERR(instkey);
847 goto error2; 850 goto error2;
848 } 851 }
849 852
850 /* find the destination keyring if present (which must also be 853 rka = instkey->payload.data;
851 * writable) */ 854
855 /* find the destination keyring amongst those belonging to the
856 * requesting task */
852 keyring = NULL; 857 keyring = NULL;
853 if (ringid) { 858 if (ringid) {
854 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 859 keyring = lookup_user_key(rka->context, ringid, 1, 0,
860 KEY_WRITE);
855 if (IS_ERR(keyring)) { 861 if (IS_ERR(keyring)) {
856 ret = PTR_ERR(keyring); 862 ret = PTR_ERR(keyring);
857 goto error3; 863 goto error3;
@@ -859,11 +865,12 @@ long keyctl_instantiate_key(key_serial_t id,
859 } 865 }
860 866
861 /* instantiate the key and link it into a keyring */ 867 /* instantiate the key and link it into a keyring */
862 ret = key_instantiate_and_link(key, payload, plen, keyring); 868 ret = key_instantiate_and_link(rka->target_key, payload, plen,
869 keyring, instkey);
863 870
864 key_put(keyring); 871 key_put(keyring);
865 error3: 872 error3:
866 key_put(key); 873 key_put(instkey);
867 error2: 874 error2:
868 kfree(payload); 875 kfree(payload);
869 error: 876 error:
@@ -878,21 +885,24 @@ long keyctl_instantiate_key(key_serial_t id,
878 */ 885 */
879long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid) 886long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
880{ 887{
881 struct key *key, *keyring; 888 struct request_key_auth *rka;
889 struct key *instkey, *keyring;
882 long ret; 890 long ret;
883 891
884 /* find the target key (which must be writable) */ 892 /* find the instantiation authorisation key */
885 key = lookup_user_key(id, 0, 1, KEY_WRITE); 893 instkey = key_get_instantiation_authkey(id);
886 if (IS_ERR(key)) { 894 if (IS_ERR(instkey)) {
887 ret = PTR_ERR(key); 895 ret = PTR_ERR(instkey);
888 goto error; 896 goto error;
889 } 897 }
890 898
899 rka = instkey->payload.data;
900
891 /* find the destination keyring if present (which must also be 901 /* find the destination keyring if present (which must also be
892 * writable) */ 902 * writable) */
893 keyring = NULL; 903 keyring = NULL;
894 if (ringid) { 904 if (ringid) {
895 keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE); 905 keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
896 if (IS_ERR(keyring)) { 906 if (IS_ERR(keyring)) {
897 ret = PTR_ERR(keyring); 907 ret = PTR_ERR(keyring);
898 goto error2; 908 goto error2;
@@ -900,11 +910,11 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
900 } 910 }
901 911
902 /* instantiate the key and link it into a keyring */ 912 /* instantiate the key and link it into a keyring */
903 ret = key_negate_and_link(key, timeout, keyring); 913 ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey);
904 914
905 key_put(keyring); 915 key_put(keyring);
906 error2: 916 error2:
907 key_put(key); 917 key_put(instkey);
908 error: 918 error:
909 return ret; 919 return ret;
910 920
@@ -912,6 +922,44 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
912 922
913/*****************************************************************************/ 923/*****************************************************************************/
914/* 924/*
925 * set the default keyring in which request_key() will cache keys
926 * - return the old setting
927 */
928long keyctl_set_reqkey_keyring(int reqkey_defl)
929{
930 int ret;
931
932 switch (reqkey_defl) {
933 case KEY_REQKEY_DEFL_THREAD_KEYRING:
934 ret = install_thread_keyring(current);
935 if (ret < 0)
936 return ret;
937 goto set;
938
939 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
940 ret = install_process_keyring(current);
941 if (ret < 0)
942 return ret;
943
944 case KEY_REQKEY_DEFL_DEFAULT:
945 case KEY_REQKEY_DEFL_SESSION_KEYRING:
946 case KEY_REQKEY_DEFL_USER_KEYRING:
947 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
948 set:
949 current->jit_keyring = reqkey_defl;
950
951 case KEY_REQKEY_DEFL_NO_CHANGE:
952 return current->jit_keyring;
953
954 case KEY_REQKEY_DEFL_GROUP_KEYRING:
955 default:
956 return -EINVAL;
957 }
958
959} /* end keyctl_set_reqkey_keyring() */
960
961/*****************************************************************************/
962/*
915 * the key control system call 963 * the key control system call
916 */ 964 */
917asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 965asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -980,6 +1028,9 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
980 (unsigned) arg3, 1028 (unsigned) arg3,
981 (key_serial_t) arg4); 1029 (key_serial_t) arg4);
982 1030
1031 case KEYCTL_SET_REQKEY_KEYRING:
1032 return keyctl_set_reqkey_keyring(arg2);
1033
983 default: 1034 default:
984 return -EOPNOTSUPP; 1035 return -EOPNOTSUPP;
985 } 1036 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index e2ab4f8e7481..90a551e4da66 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1,6 +1,6 @@
1/* keyring.c: keyring handling 1/* keyring.c: keyring handling
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -132,10 +132,17 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
132 (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key); 132 (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key);
133 133
134 ret = 0; 134 ret = 0;
135 sklist = source->payload.subscriptions;
136 135
137 if (sklist && sklist->nkeys > 0) { 136 /* find out how many keys are currently linked */
137 rcu_read_lock();
138 sklist = rcu_dereference(source->payload.subscriptions);
139 max = 0;
140 if (sklist)
138 max = sklist->nkeys; 141 max = sklist->nkeys;
142 rcu_read_unlock();
143
144 /* allocate a new payload and stuff load with key links */
145 if (max > 0) {
139 BUG_ON(max > limit); 146 BUG_ON(max > limit);
140 147
141 max = (max + 3) & ~3; 148 max = (max + 3) & ~3;
@@ -148,6 +155,10 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
148 if (!klist) 155 if (!klist)
149 goto error; 156 goto error;
150 157
158 /* set links */
159 rcu_read_lock();
160 sklist = rcu_dereference(source->payload.subscriptions);
161
151 klist->maxkeys = max; 162 klist->maxkeys = max;
152 klist->nkeys = sklist->nkeys; 163 klist->nkeys = sklist->nkeys;
153 memcpy(klist->keys, 164 memcpy(klist->keys,
@@ -157,7 +168,9 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
157 for (loop = klist->nkeys - 1; loop >= 0; loop--) 168 for (loop = klist->nkeys - 1; loop >= 0; loop--)
158 atomic_inc(&klist->keys[loop]->usage); 169 atomic_inc(&klist->keys[loop]->usage);
159 170
160 keyring->payload.subscriptions = klist; 171 rcu_read_unlock();
172
173 rcu_assign_pointer(keyring->payload.subscriptions, klist);
161 ret = 0; 174 ret = 0;
162 } 175 }
163 176
@@ -192,7 +205,7 @@ static void keyring_destroy(struct key *keyring)
192 write_unlock(&keyring_name_lock); 205 write_unlock(&keyring_name_lock);
193 } 206 }
194 207
195 klist = keyring->payload.subscriptions; 208 klist = rcu_dereference(keyring->payload.subscriptions);
196 if (klist) { 209 if (klist) {
197 for (loop = klist->nkeys - 1; loop >= 0; loop--) 210 for (loop = klist->nkeys - 1; loop >= 0; loop--)
198 key_put(klist->keys[loop]); 211 key_put(klist->keys[loop]);
@@ -216,17 +229,20 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
216 seq_puts(m, "[anon]"); 229 seq_puts(m, "[anon]");
217 } 230 }
218 231
219 klist = keyring->payload.subscriptions; 232 rcu_read_lock();
233 klist = rcu_dereference(keyring->payload.subscriptions);
220 if (klist) 234 if (klist)
221 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); 235 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
222 else 236 else
223 seq_puts(m, ": empty"); 237 seq_puts(m, ": empty");
238 rcu_read_unlock();
224 239
225} /* end keyring_describe() */ 240} /* end keyring_describe() */
226 241
227/*****************************************************************************/ 242/*****************************************************************************/
228/* 243/*
229 * read a list of key IDs from the keyring's contents 244 * read a list of key IDs from the keyring's contents
245 * - the keyring's semaphore is read-locked
230 */ 246 */
231static long keyring_read(const struct key *keyring, 247static long keyring_read(const struct key *keyring,
232 char __user *buffer, size_t buflen) 248 char __user *buffer, size_t buflen)
@@ -237,7 +253,7 @@ static long keyring_read(const struct key *keyring,
237 int loop, ret; 253 int loop, ret;
238 254
239 ret = 0; 255 ret = 0;
240 klist = keyring->payload.subscriptions; 256 klist = rcu_dereference(keyring->payload.subscriptions);
241 257
242 if (klist) { 258 if (klist) {
243 /* calculate how much data we could return */ 259 /* calculate how much data we could return */
@@ -292,7 +308,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
292 uid, gid, KEY_USR_ALL, not_in_quota); 308 uid, gid, KEY_USR_ALL, not_in_quota);
293 309
294 if (!IS_ERR(keyring)) { 310 if (!IS_ERR(keyring)) {
295 ret = key_instantiate_and_link(keyring, NULL, 0, dest); 311 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
296 if (ret < 0) { 312 if (ret < 0) {
297 key_put(keyring); 313 key_put(keyring);
298 keyring = ERR_PTR(ret); 314 keyring = ERR_PTR(ret);
@@ -310,17 +326,18 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
310 * - we only find keys on which we have search permission 326 * - we only find keys on which we have search permission
311 * - we use the supplied match function to see if the description (or other 327 * - we use the supplied match function to see if the description (or other
312 * feature of interest) matches 328 * feature of interest) matches
313 * - we readlock the keyrings as we search down the tree 329 * - we rely on RCU to prevent the keyring lists from disappearing on us
314 * - we return -EAGAIN if we didn't find any matching key 330 * - we return -EAGAIN if we didn't find any matching key
315 * - we return -ENOKEY if we only found negative matching keys 331 * - we return -ENOKEY if we only found negative matching keys
316 */ 332 */
317struct key *keyring_search_aux(struct key *keyring, 333struct key *keyring_search_aux(struct key *keyring,
334 struct task_struct *context,
318 struct key_type *type, 335 struct key_type *type,
319 const void *description, 336 const void *description,
320 key_match_func_t match) 337 key_match_func_t match)
321{ 338{
322 struct { 339 struct {
323 struct key *keyring; 340 struct keyring_list *keylist;
324 int kix; 341 int kix;
325 } stack[KEYRING_SEARCH_MAX_DEPTH]; 342 } stack[KEYRING_SEARCH_MAX_DEPTH];
326 343
@@ -328,13 +345,15 @@ struct key *keyring_search_aux(struct key *keyring,
328 struct timespec now; 345 struct timespec now;
329 struct key *key; 346 struct key *key;
330 long err; 347 long err;
331 int sp, psp, kix; 348 int sp, kix;
332 349
333 key_check(keyring); 350 key_check(keyring);
334 351
352 rcu_read_lock();
353
335 /* top keyring must have search permission to begin the search */ 354 /* top keyring must have search permission to begin the search */
336 key = ERR_PTR(-EACCES); 355 key = ERR_PTR(-EACCES);
337 if (!key_permission(keyring, KEY_SEARCH)) 356 if (!key_task_permission(keyring, context, KEY_SEARCH))
338 goto error; 357 goto error;
339 358
340 key = ERR_PTR(-ENOTDIR); 359 key = ERR_PTR(-ENOTDIR);
@@ -347,11 +366,10 @@ struct key *keyring_search_aux(struct key *keyring,
347 366
348 /* start processing a new keyring */ 367 /* start processing a new keyring */
349 descend: 368 descend:
350 read_lock(&keyring->lock); 369 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
351 if (keyring->flags & KEY_FLAG_REVOKED)
352 goto not_this_keyring; 370 goto not_this_keyring;
353 371
354 keylist = keyring->payload.subscriptions; 372 keylist = rcu_dereference(keyring->payload.subscriptions);
355 if (!keylist) 373 if (!keylist)
356 goto not_this_keyring; 374 goto not_this_keyring;
357 375
@@ -364,7 +382,7 @@ struct key *keyring_search_aux(struct key *keyring,
364 continue; 382 continue;
365 383
366 /* skip revoked keys and expired keys */ 384 /* skip revoked keys and expired keys */
367 if (key->flags & KEY_FLAG_REVOKED) 385 if (test_bit(KEY_FLAG_REVOKED, &key->flags))
368 continue; 386 continue;
369 387
370 if (key->expiry && now.tv_sec >= key->expiry) 388 if (key->expiry && now.tv_sec >= key->expiry)
@@ -375,11 +393,11 @@ struct key *keyring_search_aux(struct key *keyring,
375 continue; 393 continue;
376 394
377 /* key must have search permissions */ 395 /* key must have search permissions */
378 if (!key_permission(key, KEY_SEARCH)) 396 if (!key_task_permission(key, context, KEY_SEARCH))
379 continue; 397 continue;
380 398
381 /* we set a different error code if we find a negative key */ 399 /* we set a different error code if we find a negative key */
382 if (key->flags & KEY_FLAG_NEGATIVE) { 400 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
383 err = -ENOKEY; 401 err = -ENOKEY;
384 continue; 402 continue;
385 } 403 }
@@ -390,48 +408,37 @@ struct key *keyring_search_aux(struct key *keyring,
390 /* search through the keyrings nested in this one */ 408 /* search through the keyrings nested in this one */
391 kix = 0; 409 kix = 0;
392 ascend: 410 ascend:
393 while (kix < keylist->nkeys) { 411 for (; kix < keylist->nkeys; kix++) {
394 key = keylist->keys[kix]; 412 key = keylist->keys[kix];
395 if (key->type != &key_type_keyring) 413 if (key->type != &key_type_keyring)
396 goto next; 414 continue;
397 415
398 /* recursively search nested keyrings 416 /* recursively search nested keyrings
399 * - only search keyrings for which we have search permission 417 * - only search keyrings for which we have search permission
400 */ 418 */
401 if (sp >= KEYRING_SEARCH_MAX_DEPTH) 419 if (sp >= KEYRING_SEARCH_MAX_DEPTH)
402 goto next; 420 continue;
403
404 if (!key_permission(key, KEY_SEARCH))
405 goto next;
406 421
407 /* evade loops in the keyring tree */ 422 if (!key_task_permission(key, context, KEY_SEARCH))
408 for (psp = 0; psp < sp; psp++) 423 continue;
409 if (stack[psp].keyring == keyring)
410 goto next;
411 424
412 /* stack the current position */ 425 /* stack the current position */
413 stack[sp].keyring = keyring; 426 stack[sp].keylist = keylist;
414 stack[sp].kix = kix; 427 stack[sp].kix = kix;
415 sp++; 428 sp++;
416 429
417 /* begin again with the new keyring */ 430 /* begin again with the new keyring */
418 keyring = key; 431 keyring = key;
419 goto descend; 432 goto descend;
420
421 next:
422 kix++;
423 } 433 }
424 434
425 /* the keyring we're looking at was disqualified or didn't contain a 435 /* the keyring we're looking at was disqualified or didn't contain a
426 * matching key */ 436 * matching key */
427 not_this_keyring: 437 not_this_keyring:
428 read_unlock(&keyring->lock);
429
430 if (sp > 0) { 438 if (sp > 0) {
431 /* resume the processing of a keyring higher up in the tree */ 439 /* resume the processing of a keyring higher up in the tree */
432 sp--; 440 sp--;
433 keyring = stack[sp].keyring; 441 keylist = stack[sp].keylist;
434 keylist = keyring->payload.subscriptions;
435 kix = stack[sp].kix + 1; 442 kix = stack[sp].kix + 1;
436 goto ascend; 443 goto ascend;
437 } 444 }
@@ -442,16 +449,9 @@ struct key *keyring_search_aux(struct key *keyring,
442 /* we found a viable match */ 449 /* we found a viable match */
443 found: 450 found:
444 atomic_inc(&key->usage); 451 atomic_inc(&key->usage);
445 read_unlock(&keyring->lock);
446
447 /* unwind the keyring stack */
448 while (sp > 0) {
449 sp--;
450 read_unlock(&stack[sp].keyring->lock);
451 }
452
453 key_check(key); 452 key_check(key);
454 error: 453 error:
454 rcu_read_unlock();
455 return key; 455 return key;
456 456
457} /* end keyring_search_aux() */ 457} /* end keyring_search_aux() */
@@ -469,7 +469,11 @@ struct key *keyring_search(struct key *keyring,
469 struct key_type *type, 469 struct key_type *type,
470 const char *description) 470 const char *description)
471{ 471{
472 return keyring_search_aux(keyring, type, description, type->match); 472 if (!type->match)
473 return ERR_PTR(-ENOKEY);
474
475 return keyring_search_aux(keyring, current,
476 type, description, type->match);
473 477
474} /* end keyring_search() */ 478} /* end keyring_search() */
475 479
@@ -489,15 +493,18 @@ struct key *__keyring_search_one(struct key *keyring,
489 struct key *key; 493 struct key *key;
490 int loop; 494 int loop;
491 495
492 klist = keyring->payload.subscriptions; 496 rcu_read_lock();
497
498 klist = rcu_dereference(keyring->payload.subscriptions);
493 if (klist) { 499 if (klist) {
494 for (loop = 0; loop < klist->nkeys; loop++) { 500 for (loop = 0; loop < klist->nkeys; loop++) {
495 key = klist->keys[loop]; 501 key = klist->keys[loop];
496 502
497 if (key->type == ktype && 503 if (key->type == ktype &&
498 key->type->match(key, description) && 504 (!key->type->match ||
505 key->type->match(key, description)) &&
499 key_permission(key, perm) && 506 key_permission(key, perm) &&
500 !(key->flags & KEY_FLAG_REVOKED) 507 !test_bit(KEY_FLAG_REVOKED, &key->flags)
501 ) 508 )
502 goto found; 509 goto found;
503 } 510 }
@@ -509,12 +516,58 @@ struct key *__keyring_search_one(struct key *keyring,
509 found: 516 found:
510 atomic_inc(&key->usage); 517 atomic_inc(&key->usage);
511 error: 518 error:
519 rcu_read_unlock();
512 return key; 520 return key;
513 521
514} /* end __keyring_search_one() */ 522} /* end __keyring_search_one() */
515 523
516/*****************************************************************************/ 524/*****************************************************************************/
517/* 525/*
526 * search for an instantiation authorisation key matching a target key
527 * - the RCU read lock must be held by the caller
528 * - a target_id of zero specifies any valid token
529 */
530struct key *keyring_search_instkey(struct key *keyring,
531 key_serial_t target_id)
532{
533 struct request_key_auth *rka;
534 struct keyring_list *klist;
535 struct key *instkey;
536 int loop;
537
538 klist = rcu_dereference(keyring->payload.subscriptions);
539 if (klist) {
540 for (loop = 0; loop < klist->nkeys; loop++) {
541 instkey = klist->keys[loop];
542
543 if (instkey->type != &key_type_request_key_auth)
544 continue;
545
546 rka = instkey->payload.data;
547 if (target_id && rka->target_key->serial != target_id)
548 continue;
549
550 /* the auth key is revoked during instantiation */
551 if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
552 goto found;
553
554 instkey = ERR_PTR(-EKEYREVOKED);
555 goto error;
556 }
557 }
558
559 instkey = ERR_PTR(-EACCES);
560 goto error;
561
562found:
563 atomic_inc(&instkey->usage);
564error:
565 return instkey;
566
567} /* end keyring_search_instkey() */
568
569/*****************************************************************************/
570/*
518 * find a keyring with the specified name 571 * find a keyring with the specified name
519 * - all named keyrings are searched 572 * - all named keyrings are searched
520 * - only find keyrings with search permission for the process 573 * - only find keyrings with search permission for the process
@@ -540,7 +593,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
540 &keyring_name_hash[bucket], 593 &keyring_name_hash[bucket],
541 type_data.link 594 type_data.link
542 ) { 595 ) {
543 if (keyring->flags & KEY_FLAG_REVOKED) 596 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
544 continue; 597 continue;
545 598
546 if (strcmp(keyring->description, name) != 0) 599 if (strcmp(keyring->description, name) != 0)
@@ -579,7 +632,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
579static int keyring_detect_cycle(struct key *A, struct key *B) 632static int keyring_detect_cycle(struct key *A, struct key *B)
580{ 633{
581 struct { 634 struct {
582 struct key *subtree; 635 struct keyring_list *keylist;
583 int kix; 636 int kix;
584 } stack[KEYRING_SEARCH_MAX_DEPTH]; 637 } stack[KEYRING_SEARCH_MAX_DEPTH];
585 638
@@ -587,20 +640,21 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
587 struct key *subtree, *key; 640 struct key *subtree, *key;
588 int sp, kix, ret; 641 int sp, kix, ret;
589 642
643 rcu_read_lock();
644
590 ret = -EDEADLK; 645 ret = -EDEADLK;
591 if (A == B) 646 if (A == B)
592 goto error; 647 goto cycle_detected;
593 648
594 subtree = B; 649 subtree = B;
595 sp = 0; 650 sp = 0;
596 651
597 /* start processing a new keyring */ 652 /* start processing a new keyring */
598 descend: 653 descend:
599 read_lock(&subtree->lock); 654 if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
600 if (subtree->flags & KEY_FLAG_REVOKED)
601 goto not_this_keyring; 655 goto not_this_keyring;
602 656
603 keylist = subtree->payload.subscriptions; 657 keylist = rcu_dereference(subtree->payload.subscriptions);
604 if (!keylist) 658 if (!keylist)
605 goto not_this_keyring; 659 goto not_this_keyring;
606 kix = 0; 660 kix = 0;
@@ -619,7 +673,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
619 goto too_deep; 673 goto too_deep;
620 674
621 /* stack the current position */ 675 /* stack the current position */
622 stack[sp].subtree = subtree; 676 stack[sp].keylist = keylist;
623 stack[sp].kix = kix; 677 stack[sp].kix = kix;
624 sp++; 678 sp++;
625 679
@@ -632,13 +686,10 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
632 /* the keyring we're looking at was disqualified or didn't contain a 686 /* the keyring we're looking at was disqualified or didn't contain a
633 * matching key */ 687 * matching key */
634 not_this_keyring: 688 not_this_keyring:
635 read_unlock(&subtree->lock);
636
637 if (sp > 0) { 689 if (sp > 0) {
638 /* resume the checking of a keyring higher up in the tree */ 690 /* resume the checking of a keyring higher up in the tree */
639 sp--; 691 sp--;
640 subtree = stack[sp].subtree; 692 keylist = stack[sp].keylist;
641 keylist = subtree->payload.subscriptions;
642 kix = stack[sp].kix + 1; 693 kix = stack[sp].kix + 1;
643 goto ascend; 694 goto ascend;
644 } 695 }
@@ -646,30 +697,36 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
646 ret = 0; /* no cycles detected */ 697 ret = 0; /* no cycles detected */
647 698
648 error: 699 error:
700 rcu_read_unlock();
649 return ret; 701 return ret;
650 702
651 too_deep: 703 too_deep:
652 ret = -ELOOP; 704 ret = -ELOOP;
653 goto error_unwind; 705 goto error;
706
654 cycle_detected: 707 cycle_detected:
655 ret = -EDEADLK; 708 ret = -EDEADLK;
656 error_unwind:
657 read_unlock(&subtree->lock);
658
659 /* unwind the keyring stack */
660 while (sp > 0) {
661 sp--;
662 read_unlock(&stack[sp].subtree->lock);
663 }
664
665 goto error; 709 goto error;
666 710
667} /* end keyring_detect_cycle() */ 711} /* end keyring_detect_cycle() */
668 712
669/*****************************************************************************/ 713/*****************************************************************************/
670/* 714/*
715 * dispose of a keyring list after the RCU grace period
716 */
717static void keyring_link_rcu_disposal(struct rcu_head *rcu)
718{
719 struct keyring_list *klist =
720 container_of(rcu, struct keyring_list, rcu);
721
722 kfree(klist);
723
724} /* end keyring_link_rcu_disposal() */
725
726/*****************************************************************************/
727/*
671 * link a key into to a keyring 728 * link a key into to a keyring
672 * - must be called with the keyring's semaphore held 729 * - must be called with the keyring's semaphore write-locked
673 */ 730 */
674int __key_link(struct key *keyring, struct key *key) 731int __key_link(struct key *keyring, struct key *key)
675{ 732{
@@ -679,7 +736,7 @@ int __key_link(struct key *keyring, struct key *key)
679 int ret; 736 int ret;
680 737
681 ret = -EKEYREVOKED; 738 ret = -EKEYREVOKED;
682 if (keyring->flags & KEY_FLAG_REVOKED) 739 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
683 goto error; 740 goto error;
684 741
685 ret = -ENOTDIR; 742 ret = -ENOTDIR;
@@ -710,9 +767,10 @@ int __key_link(struct key *keyring, struct key *key)
710 /* there's sufficient slack space to add directly */ 767 /* there's sufficient slack space to add directly */
711 atomic_inc(&key->usage); 768 atomic_inc(&key->usage);
712 769
713 write_lock(&keyring->lock); 770 klist->keys[klist->nkeys] = key;
714 klist->keys[klist->nkeys++] = key; 771 smp_wmb();
715 write_unlock(&keyring->lock); 772 klist->nkeys++;
773 smp_wmb();
716 774
717 ret = 0; 775 ret = 0;
718 } 776 }
@@ -723,6 +781,8 @@ int __key_link(struct key *keyring, struct key *key)
723 max += klist->maxkeys; 781 max += klist->maxkeys;
724 782
725 ret = -ENFILE; 783 ret = -ENFILE;
784 if (max > 65535)
785 goto error3;
726 size = sizeof(*klist) + sizeof(*key) * max; 786 size = sizeof(*klist) + sizeof(*key) * max;
727 if (size > PAGE_SIZE) 787 if (size > PAGE_SIZE)
728 goto error3; 788 goto error3;
@@ -743,14 +803,13 @@ int __key_link(struct key *keyring, struct key *key)
743 803
744 /* add the key into the new space */ 804 /* add the key into the new space */
745 atomic_inc(&key->usage); 805 atomic_inc(&key->usage);
746
747 write_lock(&keyring->lock);
748 keyring->payload.subscriptions = nklist;
749 nklist->keys[nklist->nkeys++] = key; 806 nklist->keys[nklist->nkeys++] = key;
750 write_unlock(&keyring->lock); 807
808 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
751 809
752 /* dispose of the old keyring list */ 810 /* dispose of the old keyring list */
753 kfree(klist); 811 if (klist)
812 call_rcu(&klist->rcu, keyring_link_rcu_disposal);
754 813
755 ret = 0; 814 ret = 0;
756 } 815 }
@@ -791,11 +850,26 @@ EXPORT_SYMBOL(key_link);
791 850
792/*****************************************************************************/ 851/*****************************************************************************/
793/* 852/*
853 * dispose of a keyring list after the RCU grace period, freeing the unlinked
854 * key
855 */
856static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
857{
858 struct keyring_list *klist =
859 container_of(rcu, struct keyring_list, rcu);
860
861 key_put(klist->keys[klist->delkey]);
862 kfree(klist);
863
864} /* end keyring_unlink_rcu_disposal() */
865
866/*****************************************************************************/
867/*
794 * unlink the first link to a key from a keyring 868 * unlink the first link to a key from a keyring
795 */ 869 */
796int key_unlink(struct key *keyring, struct key *key) 870int key_unlink(struct key *keyring, struct key *key)
797{ 871{
798 struct keyring_list *klist; 872 struct keyring_list *klist, *nklist;
799 int loop, ret; 873 int loop, ret;
800 874
801 key_check(keyring); 875 key_check(keyring);
@@ -819,31 +893,45 @@ int key_unlink(struct key *keyring, struct key *key)
819 ret = -ENOENT; 893 ret = -ENOENT;
820 goto error; 894 goto error;
821 895
822 key_is_present: 896key_is_present:
897 /* we need to copy the key list for RCU purposes */
898 nklist = kmalloc(sizeof(*klist) + sizeof(*key) * klist->maxkeys,
899 GFP_KERNEL);
900 if (!nklist)
901 goto nomem;
902 nklist->maxkeys = klist->maxkeys;
903 nklist->nkeys = klist->nkeys - 1;
904
905 if (loop > 0)
906 memcpy(&nklist->keys[0],
907 &klist->keys[0],
908 loop * sizeof(klist->keys[0]));
909
910 if (loop < nklist->nkeys)
911 memcpy(&nklist->keys[loop],
912 &klist->keys[loop + 1],
913 (nklist->nkeys - loop) * sizeof(klist->keys[0]));
914
823 /* adjust the user's quota */ 915 /* adjust the user's quota */
824 key_payload_reserve(keyring, 916 key_payload_reserve(keyring,
825 keyring->datalen - KEYQUOTA_LINK_BYTES); 917 keyring->datalen - KEYQUOTA_LINK_BYTES);
826 918
827 /* shuffle down the key pointers 919 rcu_assign_pointer(keyring->payload.subscriptions, nklist);
828 * - it might be worth shrinking the allocated memory, but that runs
829 * the risk of ENOMEM as we would have to copy
830 */
831 write_lock(&keyring->lock);
832 920
833 klist->nkeys--; 921 up_write(&keyring->sem);
834 if (loop < klist->nkeys)
835 memcpy(&klist->keys[loop],
836 &klist->keys[loop + 1],
837 (klist->nkeys - loop) * sizeof(struct key *));
838 922
839 write_unlock(&keyring->lock); 923 /* schedule for later cleanup */
924 klist->delkey = loop;
925 call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
840 926
841 up_write(&keyring->sem);
842 key_put(key);
843 ret = 0; 927 ret = 0;
844 928
845 error: 929error:
846 return ret; 930 return ret;
931nomem:
932 ret = -ENOMEM;
933 up_write(&keyring->sem);
934 goto error;
847 935
848} /* end key_unlink() */ 936} /* end key_unlink() */
849 937
@@ -851,13 +939,32 @@ EXPORT_SYMBOL(key_unlink);
851 939
852/*****************************************************************************/ 940/*****************************************************************************/
853/* 941/*
942 * dispose of a keyring list after the RCU grace period, releasing the keys it
943 * links to
944 */
945static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
946{
947 struct keyring_list *klist;
948 int loop;
949
950 klist = container_of(rcu, struct keyring_list, rcu);
951
952 for (loop = klist->nkeys - 1; loop >= 0; loop--)
953 key_put(klist->keys[loop]);
954
955 kfree(klist);
956
957} /* end keyring_clear_rcu_disposal() */
958
959/*****************************************************************************/
960/*
854 * clear the specified process keyring 961 * clear the specified process keyring
855 * - implements keyctl(KEYCTL_CLEAR) 962 * - implements keyctl(KEYCTL_CLEAR)
856 */ 963 */
857int keyring_clear(struct key *keyring) 964int keyring_clear(struct key *keyring)
858{ 965{
859 struct keyring_list *klist; 966 struct keyring_list *klist;
860 int loop, ret; 967 int ret;
861 968
862 ret = -ENOTDIR; 969 ret = -ENOTDIR;
863 if (keyring->type == &key_type_keyring) { 970 if (keyring->type == &key_type_keyring) {
@@ -870,20 +977,15 @@ int keyring_clear(struct key *keyring)
870 key_payload_reserve(keyring, 977 key_payload_reserve(keyring,
871 sizeof(struct keyring_list)); 978 sizeof(struct keyring_list));
872 979
873 write_lock(&keyring->lock); 980 rcu_assign_pointer(keyring->payload.subscriptions,
874 keyring->payload.subscriptions = NULL; 981 NULL);
875 write_unlock(&keyring->lock);
876 } 982 }
877 983
878 up_write(&keyring->sem); 984 up_write(&keyring->sem);
879 985
880 /* free the keys after the locks have been dropped */ 986 /* free the keys after the locks have been dropped */
881 if (klist) { 987 if (klist)
882 for (loop = klist->nkeys - 1; loop >= 0; loop--) 988 call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
883 key_put(klist->keys[loop]);
884
885 kfree(klist);
886 }
887 989
888 ret = 0; 990 ret = 0;
889 } 991 }
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 91343b85c39c..c55cf1fd0826 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -140,7 +140,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
140 140
141 now = current_kernel_time(); 141 now = current_kernel_time();
142 142
143 read_lock(&key->lock); 143 rcu_read_lock();
144 144
145 /* come up with a suitable timeout value */ 145 /* come up with a suitable timeout value */
146 if (key->expiry == 0) { 146 if (key->expiry == 0) {
@@ -164,14 +164,17 @@ static int proc_keys_show(struct seq_file *m, void *v)
164 sprintf(xbuf, "%luw", timo / (60*60*24*7)); 164 sprintf(xbuf, "%luw", timo / (60*60*24*7));
165 } 165 }
166 166
167#define showflag(KEY, LETTER, FLAG) \
168 (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-')
169
167 seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ", 170 seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ",
168 key->serial, 171 key->serial,
169 key->flags & KEY_FLAG_INSTANTIATED ? 'I' : '-', 172 showflag(key, 'I', KEY_FLAG_INSTANTIATED),
170 key->flags & KEY_FLAG_REVOKED ? 'R' : '-', 173 showflag(key, 'R', KEY_FLAG_REVOKED),
171 key->flags & KEY_FLAG_DEAD ? 'D' : '-', 174 showflag(key, 'D', KEY_FLAG_DEAD),
172 key->flags & KEY_FLAG_IN_QUOTA ? 'Q' : '-', 175 showflag(key, 'Q', KEY_FLAG_IN_QUOTA),
173 key->flags & KEY_FLAG_USER_CONSTRUCT ? 'U' : '-', 176 showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT),
174 key->flags & KEY_FLAG_NEGATIVE ? 'N' : '-', 177 showflag(key, 'N', KEY_FLAG_NEGATIVE),
175 atomic_read(&key->usage), 178 atomic_read(&key->usage),
176 xbuf, 179 xbuf,
177 key->perm, 180 key->perm,
@@ -179,11 +182,13 @@ static int proc_keys_show(struct seq_file *m, void *v)
179 key->gid, 182 key->gid,
180 key->type->name); 183 key->type->name);
181 184
185#undef showflag
186
182 if (key->type->describe) 187 if (key->type->describe)
183 key->type->describe(key, m); 188 key->type->describe(key, m);
184 seq_putc(m, '\n'); 189 seq_putc(m, '\n');
185 190
186 read_unlock(&key->lock); 191 rcu_read_unlock();
187 192
188 return 0; 193 return 0;
189 194
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 2eb0e471cd40..34db087bbcc7 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -1,6 +1,6 @@
1/* process_keys.c: management of a process's keyrings 1/* process_keys.c: management of a process's keyrings
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -38,10 +38,9 @@ struct key root_user_keyring = {
38 .serial = 2, 38 .serial = 2,
39 .type = &key_type_keyring, 39 .type = &key_type_keyring,
40 .user = &root_key_user, 40 .user = &root_key_user,
41 .lock = RW_LOCK_UNLOCKED,
42 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), 41 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
43 .perm = KEY_USR_ALL, 42 .perm = KEY_USR_ALL,
44 .flags = KEY_FLAG_INSTANTIATED, 43 .flags = 1 << KEY_FLAG_INSTANTIATED,
45 .description = "_uid.0", 44 .description = "_uid.0",
46#ifdef KEY_DEBUGGING 45#ifdef KEY_DEBUGGING
47 .magic = KEY_DEBUG_MAGIC, 46 .magic = KEY_DEBUG_MAGIC,
@@ -54,10 +53,9 @@ struct key root_session_keyring = {
54 .serial = 1, 53 .serial = 1,
55 .type = &key_type_keyring, 54 .type = &key_type_keyring,
56 .user = &root_key_user, 55 .user = &root_key_user,
57 .lock = RW_LOCK_UNLOCKED,
58 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), 56 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
59 .perm = KEY_USR_ALL, 57 .perm = KEY_USR_ALL,
60 .flags = KEY_FLAG_INSTANTIATED, 58 .flags = 1 << KEY_FLAG_INSTANTIATED,
61 .description = "_uid_ses.0", 59 .description = "_uid_ses.0",
62#ifdef KEY_DEBUGGING 60#ifdef KEY_DEBUGGING
63 .magic = KEY_DEBUG_MAGIC, 61 .magic = KEY_DEBUG_MAGIC,
@@ -167,7 +165,7 @@ int install_thread_keyring(struct task_struct *tsk)
167/* 165/*
168 * make sure a process keyring is installed 166 * make sure a process keyring is installed
169 */ 167 */
170static int install_process_keyring(struct task_struct *tsk) 168int install_process_keyring(struct task_struct *tsk)
171{ 169{
172 unsigned long flags; 170 unsigned long flags;
173 struct key *keyring; 171 struct key *keyring;
@@ -183,7 +181,7 @@ static int install_process_keyring(struct task_struct *tsk)
183 goto error; 181 goto error;
184 } 182 }
185 183
186 /* attach or swap keyrings */ 184 /* attach keyring */
187 spin_lock_irqsave(&tsk->sighand->siglock, flags); 185 spin_lock_irqsave(&tsk->sighand->siglock, flags);
188 if (!tsk->signal->process_keyring) { 186 if (!tsk->signal->process_keyring) {
189 tsk->signal->process_keyring = keyring; 187 tsk->signal->process_keyring = keyring;
@@ -229,12 +227,14 @@ static int install_session_keyring(struct task_struct *tsk,
229 227
230 /* install the keyring */ 228 /* install the keyring */
231 spin_lock_irqsave(&tsk->sighand->siglock, flags); 229 spin_lock_irqsave(&tsk->sighand->siglock, flags);
232 old = tsk->signal->session_keyring; 230 old = rcu_dereference(tsk->signal->session_keyring);
233 tsk->signal->session_keyring = keyring; 231 rcu_assign_pointer(tsk->signal->session_keyring, keyring);
234 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 232 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
235 233
236 ret = 0; 234 ret = 0;
237 235
236 /* we're using RCU on the pointer */
237 synchronize_kernel();
238 key_put(old); 238 key_put(old);
239 error: 239 error:
240 return ret; 240 return ret;
@@ -247,8 +247,6 @@ static int install_session_keyring(struct task_struct *tsk,
247 */ 247 */
248int copy_thread_group_keys(struct task_struct *tsk) 248int copy_thread_group_keys(struct task_struct *tsk)
249{ 249{
250 unsigned long flags;
251
252 key_check(current->thread_group->session_keyring); 250 key_check(current->thread_group->session_keyring);
253 key_check(current->thread_group->process_keyring); 251 key_check(current->thread_group->process_keyring);
254 252
@@ -256,10 +254,10 @@ int copy_thread_group_keys(struct task_struct *tsk)
256 tsk->signal->process_keyring = NULL; 254 tsk->signal->process_keyring = NULL;
257 255
258 /* same session keyring */ 256 /* same session keyring */
259 spin_lock_irqsave(&current->sighand->siglock, flags); 257 rcu_read_lock();
260 tsk->signal->session_keyring = 258 tsk->signal->session_keyring =
261 key_get(current->signal->session_keyring); 259 key_get(rcu_dereference(current->signal->session_keyring));
262 spin_unlock_irqrestore(&current->sighand->siglock, flags); 260 rcu_read_unlock();
263 261
264 return 0; 262 return 0;
265 263
@@ -349,9 +347,7 @@ void key_fsuid_changed(struct task_struct *tsk)
349 /* update the ownership of the thread keyring */ 347 /* update the ownership of the thread keyring */
350 if (tsk->thread_keyring) { 348 if (tsk->thread_keyring) {
351 down_write(&tsk->thread_keyring->sem); 349 down_write(&tsk->thread_keyring->sem);
352 write_lock(&tsk->thread_keyring->lock);
353 tsk->thread_keyring->uid = tsk->fsuid; 350 tsk->thread_keyring->uid = tsk->fsuid;
354 write_unlock(&tsk->thread_keyring->lock);
355 up_write(&tsk->thread_keyring->sem); 351 up_write(&tsk->thread_keyring->sem);
356 } 352 }
357 353
@@ -366,9 +362,7 @@ void key_fsgid_changed(struct task_struct *tsk)
366 /* update the ownership of the thread keyring */ 362 /* update the ownership of the thread keyring */
367 if (tsk->thread_keyring) { 363 if (tsk->thread_keyring) {
368 down_write(&tsk->thread_keyring->sem); 364 down_write(&tsk->thread_keyring->sem);
369 write_lock(&tsk->thread_keyring->lock);
370 tsk->thread_keyring->gid = tsk->fsgid; 365 tsk->thread_keyring->gid = tsk->fsgid;
371 write_unlock(&tsk->thread_keyring->lock);
372 up_write(&tsk->thread_keyring->sem); 366 up_write(&tsk->thread_keyring->sem);
373 } 367 }
374 368
@@ -382,13 +376,13 @@ void key_fsgid_changed(struct task_struct *tsk)
382 * - we return -EAGAIN if we didn't find any matching key 376 * - we return -EAGAIN if we didn't find any matching key
383 * - we return -ENOKEY if we found only negative matching keys 377 * - we return -ENOKEY if we found only negative matching keys
384 */ 378 */
385struct key *search_process_keyrings_aux(struct key_type *type, 379struct key *search_process_keyrings(struct key_type *type,
386 const void *description, 380 const void *description,
387 key_match_func_t match) 381 key_match_func_t match,
382 struct task_struct *context)
388{ 383{
389 struct task_struct *tsk = current; 384 struct request_key_auth *rka;
390 unsigned long flags; 385 struct key *key, *ret, *err, *instkey;
391 struct key *key, *ret, *err, *tmp;
392 386
393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 387 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
394 * searchable, but we failed to find a key or we found a negative key; 388 * searchable, but we failed to find a key or we found a negative key;
@@ -402,9 +396,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
402 err = ERR_PTR(-EAGAIN); 396 err = ERR_PTR(-EAGAIN);
403 397
404 /* search the thread keyring first */ 398 /* search the thread keyring first */
405 if (tsk->thread_keyring) { 399 if (context->thread_keyring) {
406 key = keyring_search_aux(tsk->thread_keyring, type, 400 key = keyring_search_aux(context->thread_keyring,
407 description, match); 401 context, type, description, match);
408 if (!IS_ERR(key)) 402 if (!IS_ERR(key))
409 goto found; 403 goto found;
410 404
@@ -422,9 +416,9 @@ struct key *search_process_keyrings_aux(struct key_type *type,
422 } 416 }
423 417
424 /* search the process keyring second */ 418 /* search the process keyring second */
425 if (tsk->signal->process_keyring) { 419 if (context->signal->process_keyring) {
426 key = keyring_search_aux(tsk->signal->process_keyring, 420 key = keyring_search_aux(context->signal->process_keyring,
427 type, description, match); 421 context, type, description, match);
428 if (!IS_ERR(key)) 422 if (!IS_ERR(key))
429 goto found; 423 goto found;
430 424
@@ -441,52 +435,93 @@ struct key *search_process_keyrings_aux(struct key_type *type,
441 } 435 }
442 } 436 }
443 437
444 /* search the session keyring last */ 438 /* search the session keyring */
445 spin_lock_irqsave(&tsk->sighand->siglock, flags); 439 if (context->signal->session_keyring) {
440 rcu_read_lock();
441 key = keyring_search_aux(
442 rcu_dereference(context->signal->session_keyring),
443 context, type, description, match);
444 rcu_read_unlock();
446 445
447 tmp = tsk->signal->session_keyring; 446 if (!IS_ERR(key))
448 if (!tmp) 447 goto found;
449 tmp = tsk->user->session_keyring;
450 atomic_inc(&tmp->usage);
451 448
452 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 449 switch (PTR_ERR(key)) {
450 case -EAGAIN: /* no key */
451 if (ret)
452 break;
453 case -ENOKEY: /* negative key */
454 ret = key;
455 break;
456 default:
457 err = key;
458 break;
459 }
460
461 /* if this process has a session keyring and that has an
462 * instantiation authorisation key in the bottom level, then we
463 * also search the keyrings of the process mentioned there */
464 if (context != current)
465 goto no_key;
466
467 rcu_read_lock();
468 instkey = __keyring_search_one(
469 rcu_dereference(context->signal->session_keyring),
470 &key_type_request_key_auth, NULL, 0);
471 rcu_read_unlock();
472
473 if (IS_ERR(instkey))
474 goto no_key;
475
476 rka = instkey->payload.data;
453 477
454 key = keyring_search_aux(tmp, type, description, match); 478 key = search_process_keyrings(type, description, match,
455 key_put(tmp); 479 rka->context);
456 if (!IS_ERR(key)) 480 key_put(instkey);
457 goto found;
458 481
459 switch (PTR_ERR(key)) { 482 if (!IS_ERR(key))
460 case -EAGAIN: /* no key */ 483 goto found;
461 if (ret) 484
485 switch (PTR_ERR(key)) {
486 case -EAGAIN: /* no key */
487 if (ret)
488 break;
489 case -ENOKEY: /* negative key */
490 ret = key;
462 break; 491 break;
463 case -ENOKEY: /* negative key */ 492 default:
464 ret = key; 493 err = key;
465 break; 494 break;
466 default: 495 }
467 err = key; 496 }
468 break; 497 /* or search the user-session keyring */
498 else {
499 key = keyring_search_aux(context->user->session_keyring,
500 context, type, description, match);
501 if (!IS_ERR(key))
502 goto found;
503
504 switch (PTR_ERR(key)) {
505 case -EAGAIN: /* no key */
506 if (ret)
507 break;
508 case -ENOKEY: /* negative key */
509 ret = key;
510 break;
511 default:
512 err = key;
513 break;
514 }
469 } 515 }
470 516
517
518no_key:
471 /* no key - decide on the error we're going to go for */ 519 /* no key - decide on the error we're going to go for */
472 key = ret ? ret : err; 520 key = ret ? ret : err;
473 521
474 found: 522found:
475 return key; 523 return key;
476 524
477} /* end search_process_keyrings_aux() */
478
479/*****************************************************************************/
480/*
481 * search the process keyrings for the first matching key
482 * - we return -EAGAIN if we didn't find any matching key
483 * - we return -ENOKEY if we found only negative matching keys
484 */
485struct key *search_process_keyrings(struct key_type *type,
486 const char *description)
487{
488 return search_process_keyrings_aux(type, description, type->match);
489
490} /* end search_process_keyrings() */ 525} /* end search_process_keyrings() */
491 526
492/*****************************************************************************/ 527/*****************************************************************************/
@@ -495,72 +530,73 @@ struct key *search_process_keyrings(struct key_type *type,
495 * - don't create special keyrings unless so requested 530 * - don't create special keyrings unless so requested
496 * - partially constructed keys aren't found unless requested 531 * - partially constructed keys aren't found unless requested
497 */ 532 */
498struct key *lookup_user_key(key_serial_t id, int create, int partial, 533struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
499 key_perm_t perm) 534 int create, int partial, key_perm_t perm)
500{ 535{
501 struct task_struct *tsk = current;
502 unsigned long flags;
503 struct key *key; 536 struct key *key;
504 int ret; 537 int ret;
505 538
539 if (!context)
540 context = current;
541
506 key = ERR_PTR(-ENOKEY); 542 key = ERR_PTR(-ENOKEY);
507 543
508 switch (id) { 544 switch (id) {
509 case KEY_SPEC_THREAD_KEYRING: 545 case KEY_SPEC_THREAD_KEYRING:
510 if (!tsk->thread_keyring) { 546 if (!context->thread_keyring) {
511 if (!create) 547 if (!create)
512 goto error; 548 goto error;
513 549
514 ret = install_thread_keyring(tsk); 550 ret = install_thread_keyring(context);
515 if (ret < 0) { 551 if (ret < 0) {
516 key = ERR_PTR(ret); 552 key = ERR_PTR(ret);
517 goto error; 553 goto error;
518 } 554 }
519 } 555 }
520 556
521 key = tsk->thread_keyring; 557 key = context->thread_keyring;
522 atomic_inc(&key->usage); 558 atomic_inc(&key->usage);
523 break; 559 break;
524 560
525 case KEY_SPEC_PROCESS_KEYRING: 561 case KEY_SPEC_PROCESS_KEYRING:
526 if (!tsk->signal->process_keyring) { 562 if (!context->signal->process_keyring) {
527 if (!create) 563 if (!create)
528 goto error; 564 goto error;
529 565
530 ret = install_process_keyring(tsk); 566 ret = install_process_keyring(context);
531 if (ret < 0) { 567 if (ret < 0) {
532 key = ERR_PTR(ret); 568 key = ERR_PTR(ret);
533 goto error; 569 goto error;
534 } 570 }
535 } 571 }
536 572
537 key = tsk->signal->process_keyring; 573 key = context->signal->process_keyring;
538 atomic_inc(&key->usage); 574 atomic_inc(&key->usage);
539 break; 575 break;
540 576
541 case KEY_SPEC_SESSION_KEYRING: 577 case KEY_SPEC_SESSION_KEYRING:
542 if (!tsk->signal->session_keyring) { 578 if (!context->signal->session_keyring) {
543 /* always install a session keyring upon access if one 579 /* always install a session keyring upon access if one
544 * doesn't exist yet */ 580 * doesn't exist yet */
545 ret = install_session_keyring( 581 ret = install_session_keyring(
546 tsk, tsk->user->session_keyring); 582 context, context->user->session_keyring);
547 if (ret < 0) 583 if (ret < 0)
548 goto error; 584 goto error;
549 } 585 }
550 586
551 spin_lock_irqsave(&tsk->sighand->siglock, flags); 587 rcu_read_lock();
552 key = tsk->signal->session_keyring; 588 key = rcu_dereference(context->signal->session_keyring);
553 atomic_inc(&key->usage); 589 atomic_inc(&key->usage);
554 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 590 rcu_read_unlock();
555 break; 591 break;
556 592
557 case KEY_SPEC_USER_KEYRING: 593 case KEY_SPEC_USER_KEYRING:
558 key = tsk->user->uid_keyring; 594 key = context->user->uid_keyring;
559 atomic_inc(&key->usage); 595 atomic_inc(&key->usage);
560 break; 596 break;
561 597
562 case KEY_SPEC_USER_SESSION_KEYRING: 598 case KEY_SPEC_USER_SESSION_KEYRING:
563 key = tsk->user->session_keyring; 599 key = context->user->session_keyring;
564 atomic_inc(&key->usage); 600 atomic_inc(&key->usage);
565 break; 601 break;
566 602
@@ -580,7 +616,7 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
580 break; 616 break;
581 } 617 }
582 618
583 /* check the status and permissions */ 619 /* check the status */
584 if (perm) { 620 if (perm) {
585 ret = key_validate(key); 621 ret = key_validate(key);
586 if (ret < 0) 622 if (ret < 0)
@@ -588,11 +624,13 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
588 } 624 }
589 625
590 ret = -EIO; 626 ret = -EIO;
591 if (!partial && !(key->flags & KEY_FLAG_INSTANTIATED)) 627 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
592 goto invalid_key; 628 goto invalid_key;
593 629
630 /* check the permissions */
594 ret = -EACCES; 631 ret = -EACCES;
595 if (!key_permission(key, perm)) 632
633 if (!key_task_permission(key, context, perm))
596 goto invalid_key; 634 goto invalid_key;
597 635
598 error: 636 error:
@@ -615,7 +653,6 @@ struct key *lookup_user_key(key_serial_t id, int create, int partial,
615long join_session_keyring(const char *name) 653long join_session_keyring(const char *name)
616{ 654{
617 struct task_struct *tsk = current; 655 struct task_struct *tsk = current;
618 unsigned long flags;
619 struct key *keyring; 656 struct key *keyring;
620 long ret; 657 long ret;
621 658
@@ -625,9 +662,9 @@ long join_session_keyring(const char *name)
625 if (ret < 0) 662 if (ret < 0)
626 goto error; 663 goto error;
627 664
628 spin_lock_irqsave(&tsk->sighand->siglock, flags); 665 rcu_read_lock();
629 ret = tsk->signal->session_keyring->serial; 666 ret = rcu_dereference(tsk->signal->session_keyring)->serial;
630 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 667 rcu_read_unlock();
631 goto error; 668 goto error;
632 } 669 }
633 670
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 9705b1aeba5d..dfcd983af1fd 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -1,6 +1,6 @@
1/* request_key.c: request a key from userspace 1/* request_key.c: request a key from userspace
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/kmod.h> 14#include <linux/kmod.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/keyctl.h>
16#include "internal.h" 17#include "internal.h"
17 18
18struct key_construction { 19struct key_construction {
@@ -27,18 +28,26 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
27/* 28/*
28 * request userspace finish the construction of a key 29 * request userspace finish the construction of a key
29 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>" 30 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
30 * - if callout_info is an empty string, it'll be rendered as a "-" instead
31 */ 31 */
32static int call_request_key(struct key *key, 32static int call_request_key(struct key *key,
33 const char *op, 33 const char *op,
34 const char *callout_info) 34 const char *callout_info)
35{ 35{
36 struct task_struct *tsk = current; 36 struct task_struct *tsk = current;
37 unsigned long flags;
38 key_serial_t prkey, sskey; 37 key_serial_t prkey, sskey;
38 struct key *session_keyring, *rkakey;
39 char *argv[10], *envp[3], uid_str[12], gid_str[12]; 39 char *argv[10], *envp[3], uid_str[12], gid_str[12];
40 char key_str[12], keyring_str[3][12]; 40 char key_str[12], keyring_str[3][12];
41 int i; 41 int ret, i;
42
43 kenter("{%d},%s,%s", key->serial, op, callout_info);
44
45 /* generate a new session keyring with an auth key in it */
46 session_keyring = request_key_auth_new(key, &rkakey);
47 if (IS_ERR(session_keyring)) {
48 ret = PTR_ERR(session_keyring);
49 goto error;
50 }
42 51
43 /* record the UID and GID */ 52 /* record the UID and GID */
44 sprintf(uid_str, "%d", current->fsuid); 53 sprintf(uid_str, "%d", current->fsuid);
@@ -55,17 +64,17 @@ static int call_request_key(struct key *key,
55 if (tsk->signal->process_keyring) 64 if (tsk->signal->process_keyring)
56 prkey = tsk->signal->process_keyring->serial; 65 prkey = tsk->signal->process_keyring->serial;
57 66
58 sskey = 0; 67 sprintf(keyring_str[1], "%d", prkey);
59 spin_lock_irqsave(&tsk->sighand->siglock, flags);
60 if (tsk->signal->session_keyring)
61 sskey = tsk->signal->session_keyring->serial;
62 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
63
64 68
65 if (!sskey) 69 if (tsk->signal->session_keyring) {
70 rcu_read_lock();
71 sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
72 rcu_read_unlock();
73 }
74 else {
66 sskey = tsk->user->session_keyring->serial; 75 sskey = tsk->user->session_keyring->serial;
76 }
67 77
68 sprintf(keyring_str[1], "%d", prkey);
69 sprintf(keyring_str[2], "%d", sskey); 78 sprintf(keyring_str[2], "%d", sskey);
70 79
71 /* set up a minimal environment */ 80 /* set up a minimal environment */
@@ -84,11 +93,20 @@ static int call_request_key(struct key *key,
84 argv[i++] = keyring_str[0]; 93 argv[i++] = keyring_str[0];
85 argv[i++] = keyring_str[1]; 94 argv[i++] = keyring_str[1];
86 argv[i++] = keyring_str[2]; 95 argv[i++] = keyring_str[2];
87 argv[i++] = callout_info[0] ? (char *) callout_info : "-"; 96 argv[i++] = (char *) callout_info;
88 argv[i] = NULL; 97 argv[i] = NULL;
89 98
90 /* do it */ 99 /* do it */
91 return call_usermodehelper(argv[0], argv, envp, 1); 100 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1);
101
102 /* dispose of the special keys */
103 key_revoke(rkakey);
104 key_put(rkakey);
105 key_put(session_keyring);
106
107 error:
108 kleave(" = %d", ret);
109 return ret;
92 110
93} /* end call_request_key() */ 111} /* end call_request_key() */
94 112
@@ -105,7 +123,9 @@ static struct key *__request_key_construction(struct key_type *type,
105 struct key_construction cons; 123 struct key_construction cons;
106 struct timespec now; 124 struct timespec now;
107 struct key *key; 125 struct key *key;
108 int ret, negative; 126 int ret, negated;
127
128 kenter("%s,%s,%s", type->name, description, callout_info);
109 129
110 /* create a key and add it to the queue */ 130 /* create a key and add it to the queue */
111 key = key_alloc(type, description, 131 key = key_alloc(type, description,
@@ -113,9 +133,7 @@ static struct key *__request_key_construction(struct key_type *type,
113 if (IS_ERR(key)) 133 if (IS_ERR(key))
114 goto alloc_failed; 134 goto alloc_failed;
115 135
116 write_lock(&key->lock); 136 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
117 key->flags |= KEY_FLAG_USER_CONSTRUCT;
118 write_unlock(&key->lock);
119 137
120 cons.key = key; 138 cons.key = key;
121 list_add_tail(&cons.link, &key->user->consq); 139 list_add_tail(&cons.link, &key->user->consq);
@@ -130,7 +148,7 @@ static struct key *__request_key_construction(struct key_type *type,
130 148
131 /* if the key wasn't instantiated, then we want to give an error */ 149 /* if the key wasn't instantiated, then we want to give an error */
132 ret = -ENOKEY; 150 ret = -ENOKEY;
133 if (!(key->flags & KEY_FLAG_INSTANTIATED)) 151 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
134 goto request_failed; 152 goto request_failed;
135 153
136 down_write(&key_construction_sem); 154 down_write(&key_construction_sem);
@@ -139,12 +157,13 @@ static struct key *__request_key_construction(struct key_type *type,
139 157
140 /* also give an error if the key was negatively instantiated */ 158 /* also give an error if the key was negatively instantiated */
141 check_not_negative: 159 check_not_negative:
142 if (key->flags & KEY_FLAG_NEGATIVE) { 160 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
143 key_put(key); 161 key_put(key);
144 key = ERR_PTR(-ENOKEY); 162 key = ERR_PTR(-ENOKEY);
145 } 163 }
146 164
147 out: 165 out:
166 kleave(" = %p", key);
148 return key; 167 return key;
149 168
150 request_failed: 169 request_failed:
@@ -152,24 +171,23 @@ static struct key *__request_key_construction(struct key_type *type,
152 * - remove from construction queue 171 * - remove from construction queue
153 * - mark the key as dead 172 * - mark the key as dead
154 */ 173 */
155 negative = 0; 174 negated = 0;
156 down_write(&key_construction_sem); 175 down_write(&key_construction_sem);
157 176
158 list_del(&cons.link); 177 list_del(&cons.link);
159 178
160 write_lock(&key->lock);
161 key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
162
163 /* check it didn't get instantiated between the check and the down */ 179 /* check it didn't get instantiated between the check and the down */
164 if (!(key->flags & KEY_FLAG_INSTANTIATED)) { 180 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
165 key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE; 181 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
166 negative = 1; 182 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
183 negated = 1;
167 } 184 }
168 185
169 write_unlock(&key->lock); 186 clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
187
170 up_write(&key_construction_sem); 188 up_write(&key_construction_sem);
171 189
172 if (!negative) 190 if (!negated)
173 goto check_not_negative; /* surprisingly, the key got 191 goto check_not_negative; /* surprisingly, the key got
174 * instantiated */ 192 * instantiated */
175 193
@@ -178,13 +196,12 @@ static struct key *__request_key_construction(struct key_type *type,
178 key->expiry = now.tv_sec + key_negative_timeout; 196 key->expiry = now.tv_sec + key_negative_timeout;
179 197
180 if (current->signal->session_keyring) { 198 if (current->signal->session_keyring) {
181 unsigned long flags;
182 struct key *keyring; 199 struct key *keyring;
183 200
184 spin_lock_irqsave(&current->sighand->siglock, flags); 201 rcu_read_lock();
185 keyring = current->signal->session_keyring; 202 keyring = rcu_dereference(current->signal->session_keyring);
186 atomic_inc(&keyring->usage); 203 atomic_inc(&keyring->usage);
187 spin_unlock_irqrestore(&current->sighand->siglock, flags); 204 rcu_read_unlock();
188 205
189 key_link(keyring, key); 206 key_link(keyring, key);
190 key_put(keyring); 207 key_put(keyring);
@@ -220,6 +237,9 @@ static struct key *request_key_construction(struct key_type *type,
220 237
221 DECLARE_WAITQUEUE(myself, current); 238 DECLARE_WAITQUEUE(myself, current);
222 239
240 kenter("%s,%s,{%d},%s",
241 type->name, description, user->uid, callout_info);
242
223 /* see if there's such a key under construction already */ 243 /* see if there's such a key under construction already */
224 down_write(&key_construction_sem); 244 down_write(&key_construction_sem);
225 245
@@ -236,6 +256,7 @@ static struct key *request_key_construction(struct key_type *type,
236 /* see about getting userspace to construct the key */ 256 /* see about getting userspace to construct the key */
237 key = __request_key_construction(type, description, callout_info); 257 key = __request_key_construction(type, description, callout_info);
238 error: 258 error:
259 kleave(" = %p", key);
239 return key; 260 return key;
240 261
241 /* someone else has the same key under construction 262 /* someone else has the same key under construction
@@ -249,8 +270,10 @@ static struct key *request_key_construction(struct key_type *type,
249 add_wait_queue(&request_key_conswq, &myself); 270 add_wait_queue(&request_key_conswq, &myself);
250 271
251 for (;;) { 272 for (;;) {
252 set_current_state(TASK_UNINTERRUPTIBLE); 273 set_current_state(TASK_INTERRUPTIBLE);
253 if (!(ckey->flags & KEY_FLAG_USER_CONSTRUCT)) 274 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
275 break;
276 if (signal_pending(current))
254 break; 277 break;
255 schedule(); 278 schedule();
256 } 279 }
@@ -271,21 +294,83 @@ static struct key *request_key_construction(struct key_type *type,
271 294
272/*****************************************************************************/ 295/*****************************************************************************/
273/* 296/*
297 * link a freshly minted key to an appropriate destination keyring
298 */
299static void request_key_link(struct key *key, struct key *dest_keyring)
300{
301 struct task_struct *tsk = current;
302 struct key *drop = NULL;
303
304 kenter("{%d},%p", key->serial, dest_keyring);
305
306 /* find the appropriate keyring */
307 if (!dest_keyring) {
308 switch (tsk->jit_keyring) {
309 case KEY_REQKEY_DEFL_DEFAULT:
310 case KEY_REQKEY_DEFL_THREAD_KEYRING:
311 dest_keyring = tsk->thread_keyring;
312 if (dest_keyring)
313 break;
314
315 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
316 dest_keyring = tsk->signal->process_keyring;
317 if (dest_keyring)
318 break;
319
320 case KEY_REQKEY_DEFL_SESSION_KEYRING:
321 rcu_read_lock();
322 dest_keyring = key_get(
323 rcu_dereference(tsk->signal->session_keyring));
324 rcu_read_unlock();
325 drop = dest_keyring;
326
327 if (dest_keyring)
328 break;
329
330 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
331 dest_keyring = current->user->session_keyring;
332 break;
333
334 case KEY_REQKEY_DEFL_USER_KEYRING:
335 dest_keyring = current->user->uid_keyring;
336 break;
337
338 case KEY_REQKEY_DEFL_GROUP_KEYRING:
339 default:
340 BUG();
341 }
342 }
343
344 /* and attach the key to it */
345 key_link(dest_keyring, key);
346
347 key_put(drop);
348
349 kleave("");
350
351} /* end request_key_link() */
352
353/*****************************************************************************/
354/*
274 * request a key 355 * request a key
275 * - search the process's keyrings 356 * - search the process's keyrings
276 * - check the list of keys being created or updated 357 * - check the list of keys being created or updated
277 * - call out to userspace for a key if requested (supplementary info can be 358 * - call out to userspace for a key if supplementary info was provided
278 * passed) 359 * - cache the key in an appropriate keyring
279 */ 360 */
280struct key *request_key(struct key_type *type, 361struct key *request_key_and_link(struct key_type *type,
281 const char *description, 362 const char *description,
282 const char *callout_info) 363 const char *callout_info,
364 struct key *dest_keyring)
283{ 365{
284 struct key_user *user; 366 struct key_user *user;
285 struct key *key; 367 struct key *key;
286 368
369 kenter("%s,%s,%s,%p",
370 type->name, description, callout_info, dest_keyring);
371
287 /* search all the process keyrings for a key */ 372 /* search all the process keyrings for a key */
288 key = search_process_keyrings_aux(type, description, type->match); 373 key = search_process_keyrings(type, description, type->match, current);
289 374
290 if (PTR_ERR(key) == -EAGAIN) { 375 if (PTR_ERR(key) == -EAGAIN) {
291 /* the search failed, but the keyrings were searchable, so we 376 /* the search failed, but the keyrings were searchable, so we
@@ -296,12 +381,13 @@ struct key *request_key(struct key_type *type,
296 381
297 /* - get hold of the user's construction queue */ 382 /* - get hold of the user's construction queue */
298 user = key_user_lookup(current->fsuid); 383 user = key_user_lookup(current->fsuid);
299 if (!user) { 384 if (!user)
300 key = ERR_PTR(-ENOMEM); 385 goto nomem;
301 goto error; 386
302 } 387 do {
388 if (signal_pending(current))
389 goto interrupted;
303 390
304 for (;;) {
305 /* ask userspace (returns NULL if it waited on a key 391 /* ask userspace (returns NULL if it waited on a key
306 * being constructed) */ 392 * being constructed) */
307 key = request_key_construction(type, description, 393 key = request_key_construction(type, description,
@@ -311,18 +397,46 @@ struct key *request_key(struct key_type *type,
311 397
312 /* someone else made the key we want, so we need to 398 /* someone else made the key we want, so we need to
313 * search again as it might now be available to us */ 399 * search again as it might now be available to us */
314 key = search_process_keyrings_aux(type, description, 400 key = search_process_keyrings(type, description,
315 type->match); 401 type->match, current);
316 if (PTR_ERR(key) != -EAGAIN) 402
317 break; 403 } while (PTR_ERR(key) == -EAGAIN);
318 }
319 404
320 key_user_put(user); 405 key_user_put(user);
406
407 /* link the new key into the appropriate keyring */
408 if (!PTR_ERR(key))
409 request_key_link(key, dest_keyring);
321 } 410 }
322 411
323 error: 412error:
413 kleave(" = %p", key);
324 return key; 414 return key;
325 415
416nomem:
417 key = ERR_PTR(-ENOMEM);
418 goto error;
419
420interrupted:
421 key_user_put(user);
422 key = ERR_PTR(-EINTR);
423 goto error;
424
425} /* end request_key_and_link() */
426
427/*****************************************************************************/
428/*
429 * request a key
430 * - search the process's keyrings
431 * - check the list of keys being created or updated
432 * - call out to userspace for a key if supplementary info was provided
433 */
434struct key *request_key(struct key_type *type,
435 const char *description,
436 const char *callout_info)
437{
438 return request_key_and_link(type, description, callout_info, NULL);
439
326} /* end request_key() */ 440} /* end request_key() */
327 441
328EXPORT_SYMBOL(request_key); 442EXPORT_SYMBOL(request_key);
@@ -339,7 +453,8 @@ int key_validate(struct key *key)
339 if (key) { 453 if (key) {
340 /* check it's still accessible */ 454 /* check it's still accessible */
341 ret = -EKEYREVOKED; 455 ret = -EKEYREVOKED;
342 if (key->flags & (KEY_FLAG_REVOKED | KEY_FLAG_DEAD)) 456 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
457 test_bit(KEY_FLAG_DEAD, &key->flags))
343 goto error; 458 goto error;
344 459
345 /* check it hasn't expired */ 460 /* check it hasn't expired */
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
new file mode 100644
index 000000000000..f22264632229
--- /dev/null
+++ b/security/keys/request_key_auth.c
@@ -0,0 +1,180 @@
1/* request_key_auth.c: request key authorisation controlling key def
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/sched.h>
14#include <linux/err.h>
15#include <linux/seq_file.h>
16#include "internal.h"
17
18static int request_key_auth_instantiate(struct key *, const void *, size_t);
19static void request_key_auth_describe(const struct key *, struct seq_file *);
20static void request_key_auth_destroy(struct key *);
21
22/*
23 * the request-key authorisation key type definition
24 */
25struct key_type key_type_request_key_auth = {
26 .name = ".request_key_auth",
27 .def_datalen = sizeof(struct request_key_auth),
28 .instantiate = request_key_auth_instantiate,
29 .describe = request_key_auth_describe,
30 .destroy = request_key_auth_destroy,
31};
32
33/*****************************************************************************/
34/*
35 * instantiate a request-key authorisation record
36 */
37static int request_key_auth_instantiate(struct key *key,
38 const void *data,
39 size_t datalen)
40{
41 struct request_key_auth *rka, *irka;
42 struct key *instkey;
43 int ret;
44
45 ret = -ENOMEM;
46 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
47 if (rka) {
48 /* see if the calling process is already servicing the key
49 * request of another process */
50 instkey = key_get_instantiation_authkey(0);
51 if (!IS_ERR(instkey)) {
52 /* it is - use that instantiation context here too */
53 irka = instkey->payload.data;
54 rka->context = irka->context;
55 rka->pid = irka->pid;
56 key_put(instkey);
57 }
58 else {
59 /* it isn't - use this process as the context */
60 rka->context = current;
61 rka->pid = current->pid;
62 }
63
64 rka->target_key = key_get((struct key *) data);
65 key->payload.data = rka;
66 ret = 0;
67 }
68
69 return ret;
70
71} /* end request_key_auth_instantiate() */
72
73/*****************************************************************************/
74/*
75 *
76 */
77static void request_key_auth_describe(const struct key *key,
78 struct seq_file *m)
79{
80 struct request_key_auth *rka = key->payload.data;
81
82 seq_puts(m, "key:");
83 seq_puts(m, key->description);
84 seq_printf(m, " pid:%d", rka->pid);
85
86} /* end request_key_auth_describe() */
87
88/*****************************************************************************/
89/*
90 * destroy an instantiation authorisation token key
91 */
92static void request_key_auth_destroy(struct key *key)
93{
94 struct request_key_auth *rka = key->payload.data;
95
96 kenter("{%d}", key->serial);
97
98 key_put(rka->target_key);
99
100} /* end request_key_auth_destroy() */
101
102/*****************************************************************************/
103/*
104 * create a session keyring to be for the invokation of /sbin/request-key and
105 * stick an authorisation token in it
106 */
107struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
108{
109 struct key *keyring, *rkakey = NULL;
110 char desc[20];
111 int ret;
112
113 kenter("%d,", target->serial);
114
115 /* allocate a new session keyring */
116 sprintf(desc, "_req.%u", target->serial);
117
118 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
119 if (IS_ERR(keyring)) {
120 kleave("= %ld", PTR_ERR(keyring));
121 return keyring;
122 }
123
124 /* allocate the auth key */
125 sprintf(desc, "%x", target->serial);
126
127 rkakey = key_alloc(&key_type_request_key_auth, desc,
128 current->fsuid, current->fsgid,
129 KEY_USR_VIEW, 1);
130 if (IS_ERR(rkakey)) {
131 key_put(keyring);
132 kleave("= %ld", PTR_ERR(rkakey));
133 return rkakey;
134 }
135
136 /* construct and attach to the keyring */
137 ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL);
138 if (ret < 0) {
139 key_revoke(rkakey);
140 key_put(rkakey);
141 key_put(keyring);
142 kleave("= %d", ret);
143 return ERR_PTR(ret);
144 }
145
146 *_rkakey = rkakey;
147 kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial);
148 return keyring;
149
150} /* end request_key_auth_new() */
151
152/*****************************************************************************/
153/*
154 * get the authorisation key for instantiation of a specific key if attached to
155 * the current process's keyrings
156 * - this key is inserted into a keyring and that is set as /sbin/request-key's
157 * session keyring
158 * - a target_id of zero specifies any valid token
159 */
160struct key *key_get_instantiation_authkey(key_serial_t target_id)
161{
162 struct task_struct *tsk = current;
163 struct key *instkey;
164
165 /* we must have our own personal session keyring */
166 if (!tsk->signal->session_keyring)
167 return ERR_PTR(-EACCES);
168
169 /* and it must contain a suitable request authorisation key
170 * - lock RCU against session keyring changing
171 */
172 rcu_read_lock();
173
174 instkey = keyring_search_instkey(
175 rcu_dereference(tsk->signal->session_keyring), target_id);
176
177 rcu_read_unlock();
178 return instkey;
179
180} /* end key_get_instantiation_authkey() */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 8d65b3a28129..e446acba73d3 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -42,12 +42,21 @@ struct key_type key_type_user = {
42 .read = user_read, 42 .read = user_read,
43}; 43};
44 44
45struct user_key_payload {
46 struct rcu_head rcu; /* RCU destructor */
47 unsigned short datalen; /* length of this data */
48 char data[0]; /* actual data */
49};
50
51EXPORT_SYMBOL_GPL(key_type_user);
52
45/*****************************************************************************/ 53/*****************************************************************************/
46/* 54/*
47 * instantiate a user defined key 55 * instantiate a user defined key
48 */ 56 */
49static int user_instantiate(struct key *key, const void *data, size_t datalen) 57static int user_instantiate(struct key *key, const void *data, size_t datalen)
50{ 58{
59 struct user_key_payload *upayload;
51 int ret; 60 int ret;
52 61
53 ret = -EINVAL; 62 ret = -EINVAL;
@@ -58,13 +67,15 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen)
58 if (ret < 0) 67 if (ret < 0)
59 goto error; 68 goto error;
60 69
61 /* attach the data */
62 ret = -ENOMEM; 70 ret = -ENOMEM;
63 key->payload.data = kmalloc(datalen, GFP_KERNEL); 71 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
64 if (!key->payload.data) 72 if (!upayload)
65 goto error; 73 goto error;
66 74
67 memcpy(key->payload.data, data, datalen); 75 /* attach the data */
76 upayload->datalen = datalen;
77 memcpy(upayload->data, data, datalen);
78 rcu_assign_pointer(key->payload.data, upayload);
68 ret = 0; 79 ret = 0;
69 80
70 error: 81 error:
@@ -75,18 +86,25 @@ static int user_instantiate(struct key *key, const void *data, size_t datalen)
75/*****************************************************************************/ 86/*****************************************************************************/
76/* 87/*
77 * duplicate a user defined key 88 * duplicate a user defined key
89 * - both keys' semaphores are locked against further modification
90 * - the new key cannot yet be accessed
78 */ 91 */
79static int user_duplicate(struct key *key, const struct key *source) 92static int user_duplicate(struct key *key, const struct key *source)
80{ 93{
94 struct user_key_payload *upayload, *spayload;
81 int ret; 95 int ret;
82 96
83 /* just copy the payload */ 97 /* just copy the payload */
84 ret = -ENOMEM; 98 ret = -ENOMEM;
85 key->payload.data = kmalloc(source->datalen, GFP_KERNEL); 99 upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL);
100 if (upayload) {
101 spayload = rcu_dereference(source->payload.data);
102 BUG_ON(source->datalen != spayload->datalen);
103
104 upayload->datalen = key->datalen = spayload->datalen;
105 memcpy(upayload->data, spayload->data, key->datalen);
86 106
87 if (key->payload.data) { 107 key->payload.data = upayload;
88 key->datalen = source->datalen;
89 memcpy(key->payload.data, source->payload.data, source->datalen);
90 ret = 0; 108 ret = 0;
91 } 109 }
92 110
@@ -96,40 +114,54 @@ static int user_duplicate(struct key *key, const struct key *source)
96 114
97/*****************************************************************************/ 115/*****************************************************************************/
98/* 116/*
117 * dispose of the old data from an updated user defined key
118 */
119static void user_update_rcu_disposal(struct rcu_head *rcu)
120{
121 struct user_key_payload *upayload;
122
123 upayload = container_of(rcu, struct user_key_payload, rcu);
124
125 kfree(upayload);
126
127} /* end user_update_rcu_disposal() */
128
129/*****************************************************************************/
130/*
99 * update a user defined key 131 * update a user defined key
132 * - the key's semaphore is write-locked
100 */ 133 */
101static int user_update(struct key *key, const void *data, size_t datalen) 134static int user_update(struct key *key, const void *data, size_t datalen)
102{ 135{
103 void *new, *zap; 136 struct user_key_payload *upayload, *zap;
104 int ret; 137 int ret;
105 138
106 ret = -EINVAL; 139 ret = -EINVAL;
107 if (datalen <= 0 || datalen > 32767 || !data) 140 if (datalen <= 0 || datalen > 32767 || !data)
108 goto error; 141 goto error;
109 142
110 /* copy the data */ 143 /* construct a replacement payload */
111 ret = -ENOMEM; 144 ret = -ENOMEM;
112 new = kmalloc(datalen, GFP_KERNEL); 145 upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
113 if (!new) 146 if (!upayload)
114 goto error; 147 goto error;
115 148
116 memcpy(new, data, datalen); 149 upayload->datalen = datalen;
150 memcpy(upayload->data, data, datalen);
117 151
118 /* check the quota and attach the new data */ 152 /* check the quota and attach the new data */
119 zap = new; 153 zap = upayload;
120 write_lock(&key->lock);
121 154
122 ret = key_payload_reserve(key, datalen); 155 ret = key_payload_reserve(key, datalen);
123 156
124 if (ret == 0) { 157 if (ret == 0) {
125 /* attach the new data, displacing the old */ 158 /* attach the new data, displacing the old */
126 zap = key->payload.data; 159 zap = key->payload.data;
127 key->payload.data = new; 160 rcu_assign_pointer(key->payload.data, upayload);
128 key->expiry = 0; 161 key->expiry = 0;
129 } 162 }
130 163
131 write_unlock(&key->lock); 164 call_rcu(&zap->rcu, user_update_rcu_disposal);
132 kfree(zap);
133 165
134 error: 166 error:
135 return ret; 167 return ret;
@@ -152,13 +184,15 @@ static int user_match(const struct key *key, const void *description)
152 */ 184 */
153static void user_destroy(struct key *key) 185static void user_destroy(struct key *key)
154{ 186{
155 kfree(key->payload.data); 187 struct user_key_payload *upayload = key->payload.data;
188
189 kfree(upayload);
156 190
157} /* end user_destroy() */ 191} /* end user_destroy() */
158 192
159/*****************************************************************************/ 193/*****************************************************************************/
160/* 194/*
161 * describe the user 195 * describe the user key
162 */ 196 */
163static void user_describe(const struct key *key, struct seq_file *m) 197static void user_describe(const struct key *key, struct seq_file *m)
164{ 198{
@@ -171,18 +205,23 @@ static void user_describe(const struct key *key, struct seq_file *m)
171/*****************************************************************************/ 205/*****************************************************************************/
172/* 206/*
173 * read the key data 207 * read the key data
208 * - the key's semaphore is read-locked
174 */ 209 */
175static long user_read(const struct key *key, 210static long user_read(const struct key *key,
176 char __user *buffer, size_t buflen) 211 char __user *buffer, size_t buflen)
177{ 212{
178 long ret = key->datalen; 213 struct user_key_payload *upayload;
214 long ret;
215
216 upayload = rcu_dereference(key->payload.data);
217 ret = upayload->datalen;
179 218
180 /* we can return the data as is */ 219 /* we can return the data as is */
181 if (buffer && buflen > 0) { 220 if (buffer && buflen > 0) {
182 if (buflen > key->datalen) 221 if (buflen > upayload->datalen)
183 buflen = key->datalen; 222 buflen = upayload->datalen;
184 223
185 if (copy_to_user(buffer, key->payload.data, buflen) != 0) 224 if (copy_to_user(buffer, upayload->data, buflen) != 0)
186 ret = -EFAULT; 225 ret = -EFAULT;
187 } 226 }
188 227
diff --git a/sound/core/info.c b/sound/core/info.c
index 31faffe01cb0..5e122bbe7c92 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -24,6 +24,7 @@
24#include <linux/vmalloc.h> 24#include <linux/vmalloc.h>
25#include <linux/time.h> 25#include <linux/time.h>
26#include <linux/smp_lock.h> 26#include <linux/smp_lock.h>
27#include <linux/string.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/minors.h> 29#include <sound/minors.h>
29#include <sound/info.h> 30#include <sound/info.h>
@@ -754,7 +755,7 @@ static snd_info_entry_t *snd_info_create_entry(const char *name)
754 entry = kcalloc(1, sizeof(*entry), GFP_KERNEL); 755 entry = kcalloc(1, sizeof(*entry), GFP_KERNEL);
755 if (entry == NULL) 756 if (entry == NULL)
756 return NULL; 757 return NULL;
757 entry->name = snd_kmalloc_strdup(name, GFP_KERNEL); 758 entry->name = kstrdup(name, GFP_KERNEL);
758 if (entry->name == NULL) { 759 if (entry->name == NULL) {
759 kfree(entry); 760 kfree(entry);
760 return NULL; 761 return NULL;
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index f9e4ce443454..12107968d402 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -22,6 +22,7 @@
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/string.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/minors.h> 27#include <sound/minors.h>
27#include <sound/info.h> 28#include <sound/info.h>
@@ -51,7 +52,7 @@ int snd_oss_info_register(int dev, int num, char *string)
51 x = NULL; 52 x = NULL;
52 } 53 }
53 } else { 54 } else {
54 x = snd_kmalloc_strdup(string, GFP_KERNEL); 55 x = kstrdup(string, GFP_KERNEL);
55 if (x == NULL) { 56 if (x == NULL) {
56 up(&strings); 57 up(&strings);
57 return -ENOMEM; 58 return -ENOMEM;
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 20860fec9364..c1fb28e84330 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -184,6 +184,20 @@ void snd_hidden_vfree(void *obj)
184 snd_wrapper_vfree(obj); 184 snd_wrapper_vfree(obj);
185} 185}
186 186
187char *snd_hidden_kstrdup(const char *s, int flags)
188{
189 int len;
190 char *buf;
191
192 if (!s) return NULL;
193
194 len = strlen(s) + 1;
195 buf = _snd_kmalloc(len, flags);
196 if (buf)
197 memcpy(buf, s, len);
198 return buf;
199}
200
187static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) 201static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
188{ 202{
189 snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc); 203 snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
@@ -214,36 +228,9 @@ int __exit snd_memory_info_done(void)
214 return 0; 228 return 0;
215} 229}
216 230
217#else
218
219#define _snd_kmalloc kmalloc
220
221#endif /* CONFIG_SND_DEBUG_MEMORY */ 231#endif /* CONFIG_SND_DEBUG_MEMORY */
222 232
223/** 233/**
224 * snd_kmalloc_strdup - copy the string
225 * @string: the original string
226 * @flags: allocation conditions, GFP_XXX
227 *
228 * Allocates a memory chunk via kmalloc() and copies the string to it.
229 *
230 * Returns the pointer, or NULL if no enoguh memory.
231 */
232char *snd_kmalloc_strdup(const char *string, int flags)
233{
234 size_t len;
235 char *ptr;
236
237 if (!string)
238 return NULL;
239 len = strlen(string) + 1;
240 ptr = _snd_kmalloc(len, flags);
241 if (ptr)
242 memcpy(ptr, string, len);
243 return ptr;
244}
245
246/**
247 * copy_to_user_fromio - copy data from mmio-space to user-space 234 * copy_to_user_fromio - copy data from mmio-space to user-space
248 * @dst: the destination pointer on user-space 235 * @dst: the destination pointer on user-space
249 * @src: the source pointer on mmio 236 * @src: the source pointer on mmio
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 98ed9a9f0da6..98fc0766f885 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -24,6 +24,7 @@
24#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/string.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/minors.h> 29#include <sound/minors.h>
29#include <sound/control.h> 30#include <sound/control.h>
@@ -1137,7 +1138,7 @@ static void snd_mixer_oss_proc_write(snd_info_entry_t *entry,
1137 goto __unlock; 1138 goto __unlock;
1138 } 1139 }
1139 tbl->oss_id = ch; 1140 tbl->oss_id = ch;
1140 tbl->name = snd_kmalloc_strdup(str, GFP_KERNEL); 1141 tbl->name = kstrdup(str, GFP_KERNEL);
1141 if (! tbl->name) { 1142 if (! tbl->name) {
1142 kfree(tbl); 1143 kfree(tbl);
1143 goto __unlock; 1144 goto __unlock;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index cab30977e7c0..de7444c586f9 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -33,6 +33,7 @@
33#include <linux/time.h> 33#include <linux/time.h>
34#include <linux/vmalloc.h> 34#include <linux/vmalloc.h>
35#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
36#include <linux/string.h>
36#include <sound/core.h> 37#include <sound/core.h>
37#include <sound/minors.h> 38#include <sound/minors.h>
38#include <sound/pcm.h> 39#include <sound/pcm.h>
@@ -2360,7 +2361,7 @@ static void snd_pcm_oss_proc_write(snd_info_entry_t *entry,
2360 for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next); 2361 for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next);
2361 setup1->next = setup; 2362 setup1->next = setup;
2362 } 2363 }
2363 template.task_name = snd_kmalloc_strdup(task_name, GFP_KERNEL); 2364 template.task_name = kstrdup(task_name, GFP_KERNEL);
2364 } else { 2365 } else {
2365 buffer->error = -ENOMEM; 2366 buffer->error = -ENOMEM;
2366 } 2367 }
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 0815fadeb3ec..7612884f530b 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -399,8 +399,8 @@ EXPORT_SYMBOL(snd_hidden_kcalloc);
399EXPORT_SYMBOL(snd_hidden_kfree); 399EXPORT_SYMBOL(snd_hidden_kfree);
400EXPORT_SYMBOL(snd_hidden_vmalloc); 400EXPORT_SYMBOL(snd_hidden_vmalloc);
401EXPORT_SYMBOL(snd_hidden_vfree); 401EXPORT_SYMBOL(snd_hidden_vfree);
402EXPORT_SYMBOL(snd_hidden_kstrdup);
402#endif 403#endif
403EXPORT_SYMBOL(snd_kmalloc_strdup);
404EXPORT_SYMBOL(copy_to_user_fromio); 404EXPORT_SYMBOL(copy_to_user_fromio);
405EXPORT_SYMBOL(copy_from_user_toio); 405EXPORT_SYMBOL(copy_from_user_toio);
406 /* init.c */ 406 /* init.c */
diff --git a/sound/core/timer.c b/sound/core/timer.c
index b498e5482d77..cfaccd415b3b 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -26,6 +26,7 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/time.h> 27#include <linux/time.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/string.h>
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/timer.h> 31#include <sound/timer.h>
31#include <sound/control.h> 32#include <sound/control.h>
@@ -100,7 +101,7 @@ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *ti
100 timeri = kcalloc(1, sizeof(*timeri), GFP_KERNEL); 101 timeri = kcalloc(1, sizeof(*timeri), GFP_KERNEL);
101 if (timeri == NULL) 102 if (timeri == NULL)
102 return NULL; 103 return NULL;
103 timeri->owner = snd_kmalloc_strdup(owner, GFP_KERNEL); 104 timeri->owner = kstrdup(owner, GFP_KERNEL);
104 if (! timeri->owner) { 105 if (! timeri->owner) {
105 kfree(timeri); 106 kfree(timeri);
106 return NULL; 107 return NULL;
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 609838e8ef67..5eb766dd564b 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -21,6 +21,7 @@
21 21
22#include <sound/driver.h> 22#include <sound/driver.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/string.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/gus.h> 26#include <sound/gus.h>
26#include <sound/info.h> 27#include <sound/info.h>
@@ -213,7 +214,7 @@ snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
213 if (share_id != NULL) 214 if (share_id != NULL)
214 memcpy(&block.share_id, share_id, sizeof(block.share_id)); 215 memcpy(&block.share_id, share_id, sizeof(block.share_id));
215 block.owner = owner; 216 block.owner = owner;
216 block.name = snd_kmalloc_strdup(name, GFP_KERNEL); 217 block.name = kstrdup(name, GFP_KERNEL);
217 nblock = snd_gf1_mem_xalloc(alloc, &block); 218 nblock = snd_gf1_mem_xalloc(alloc, &block);
218 snd_gf1_mem_lock(alloc, 1); 219 snd_gf1_mem_lock(alloc, 1);
219 return nblock; 220 return nblock;
@@ -253,13 +254,13 @@ int snd_gf1_mem_init(snd_gus_card_t * gus)
253 if (gus->gf1.enh_mode) { 254 if (gus->gf1.enh_mode) {
254 block.ptr = 0; 255 block.ptr = 0;
255 block.size = 1024; 256 block.size = 1024;
256 block.name = snd_kmalloc_strdup("InterWave LFOs", GFP_KERNEL); 257 block.name = kstrdup("InterWave LFOs", GFP_KERNEL);
257 if (snd_gf1_mem_xalloc(alloc, &block) == NULL) 258 if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
258 return -ENOMEM; 259 return -ENOMEM;
259 } 260 }
260 block.ptr = gus->gf1.default_voice_address; 261 block.ptr = gus->gf1.default_voice_address;
261 block.size = 4; 262 block.size = 4;
262 block.name = snd_kmalloc_strdup("Voice default (NULL's)", GFP_KERNEL); 263 block.name = kstrdup("Voice default (NULL's)", GFP_KERNEL);
263 if (snd_gf1_mem_xalloc(alloc, &block) == NULL) 264 if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
264 return -ENOMEM; 265 return -ENOMEM;
265#ifdef CONFIG_SND_DEBUG 266#ifdef CONFIG_SND_DEBUG
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9edd558d6bd3..bab89843d850 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1781,7 +1781,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
1781 1781
1782 knew = &spec->kctl_alloc[spec->num_kctl_used]; 1782 knew = &spec->kctl_alloc[spec->num_kctl_used];
1783 *knew = alc880_control_templates[type]; 1783 *knew = alc880_control_templates[type];
1784 knew->name = snd_kmalloc_strdup(name, GFP_KERNEL); 1784 knew->name = kstrdup(name, GFP_KERNEL);
1785 if (! knew->name) 1785 if (! knew->name)
1786 return -ENOMEM; 1786 return -ENOMEM;
1787 knew->private_value = val; 1787 knew->private_value = val;
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index 16f3b461627a..60d0b2c66698 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -22,6 +22,7 @@
22#include <linux/wait.h> 22#include <linux/wait.h>
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/string.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/emux_synth.h> 27#include <sound/emux_synth.h>
27#include <linux/init.h> 28#include <linux/init.h>
@@ -76,7 +77,7 @@ int snd_emux_register(snd_emux_t *emu, snd_card_t *card, int index, char *name)
76 snd_assert(name != NULL, return -EINVAL); 77 snd_assert(name != NULL, return -EINVAL);
77 78
78 emu->card = card; 79 emu->card = card;
79 emu->name = snd_kmalloc_strdup(name, GFP_KERNEL); 80 emu->name = kstrdup(name, GFP_KERNEL);
80 emu->voices = kcalloc(emu->max_voices, sizeof(snd_emux_voice_t), GFP_KERNEL); 81 emu->voices = kcalloc(emu->max_voices, sizeof(snd_emux_voice_t), GFP_KERNEL);
81 if (emu->voices == NULL) 82 if (emu->voices == NULL)
82 return -ENOMEM; 83 return -ENOMEM;