aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-07-08 11:52:42 -0400
committerTony Luck <tony.luck@intel.com>2005-07-08 11:52:42 -0400
commit88c3cdfdde3cf87e1831265ea4246430bef34fc9 (patch)
treecaea510ffb2f81a5ea13b00ecb8a4146ad462048
parent2b2c3750330325ae5071582b5c4dbdf1c8bc1e51 (diff)
parenta92b7b80579fe68fe229892815c750f6652eb6a9 (diff)
Auto merge with /home/aegl/GIT/linus
-rw-r--r--Documentation/dvb/README.dvb-usb132
-rw-r--r--Documentation/dvb/bt8xx.txt79
-rw-r--r--Documentation/feature-removal-schedule.txt16
-rw-r--r--Documentation/infiniband/user_verbs.txt69
-rw-r--r--Documentation/power/video.txt1
-rw-r--r--MAINTAINERS7
-rw-r--r--Makefile6
-rw-r--r--arch/frv/defconfig627
-rw-r--r--arch/i386/kernel/cpu/common.c5
-rw-r--r--arch/i386/kernel/cpu/intel.c2
-rw-r--r--arch/i386/kernel/cpu/mtrr/generic.c22
-rw-r--r--arch/i386/kernel/cpu/mtrr/main.c76
-rw-r--r--arch/i386/kernel/cpu/mtrr/mtrr.h1
-rw-r--r--arch/i386/kernel/smpboot.c18
-rw-r--r--arch/i386/kernel/time.c2
-rw-r--r--arch/i386/kernel/timers/timer_hpet.c4
-rw-r--r--arch/i386/kernel/vmlinux.lds.S3
-rw-r--r--arch/i386/mm/ioremap.c6
-rw-r--r--arch/i386/power/cpu.c1
-rw-r--r--arch/m32r/kernel/setup_m32700ut.c55
-rw-r--r--arch/m32r/kernel/setup_mappi.c51
-rw-r--r--arch/m32r/kernel/setup_mappi2.c4
-rw-r--r--arch/m32r/kernel/setup_mappi3.c52
-rw-r--r--arch/m32r/kernel/setup_oaks32r.c5
-rw-r--r--arch/m32r/kernel/setup_opsput.c53
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c2
-rw-r--r--arch/ppc64/kernel/cputable.c365
-rw-r--r--arch/ppc64/kernel/head.S10
-rw-r--r--arch/ppc64/kernel/hvconsole.c51
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c94
-rw-r--r--arch/ppc64/kernel/idle.c283
-rw-r--r--arch/ppc64/kernel/maple_setup.c3
-rw-r--r--arch/ppc64/kernel/misc.S6
-rw-r--r--arch/ppc64/kernel/pSeries_setup.c156
-rw-r--r--arch/ppc64/kernel/pmac_setup.c5
-rw-r--r--arch/ppc64/kernel/setup.c8
-rw-r--r--arch/ppc64/kernel/sys_ppc32.c54
-rw-r--r--arch/ppc64/kernel/sysfs.c14
-rw-r--r--arch/ppc64/kernel/vdso32/vdso32.lds.S4
-rw-r--r--arch/um/Kconfig6
-rw-r--r--arch/um/Kconfig_i38612
-rw-r--r--arch/um/Kconfig_x86_6412
-rw-r--r--arch/um/Makefile-i3862
-rw-r--r--arch/um/Makefile-x86_642
-rw-r--r--arch/um/defconfig58
-rw-r--r--arch/um/drivers/line.c37
-rw-r--r--arch/um/include/mem.h1
-rw-r--r--arch/um/include/registers.h1
-rw-r--r--arch/um/include/sysdep-i386/ptrace_user.h13
-rw-r--r--arch/um/include/sysdep-i386/stub.h65
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace_user.h14
-rw-r--r--arch/um/include/sysdep-x86_64/stub.h58
-rw-r--r--arch/um/include/time_user.h1
-rw-r--r--arch/um/include/tlb.h30
-rw-r--r--arch/um/kernel/dyn.lds.S6
-rw-r--r--arch/um/kernel/physmem.c8
-rw-r--r--arch/um/kernel/process.c28
-rw-r--r--arch/um/kernel/skas/Makefile7
-rw-r--r--arch/um/kernel/skas/clone.c44
-rw-r--r--arch/um/kernel/skas/exec_kern.c2
-rw-r--r--arch/um/kernel/skas/include/mm_id.h17
-rw-r--r--arch/um/kernel/skas/include/mmu-skas.h7
-rw-r--r--arch/um/kernel/skas/include/skas.h16
-rw-r--r--arch/um/kernel/skas/include/stub-data.h18
-rw-r--r--arch/um/kernel/skas/mem.c6
-rw-r--r--arch/um/kernel/skas/mem_user.c225
-rw-r--r--arch/um/kernel/skas/mmu.c141
-rw-r--r--arch/um/kernel/skas/process.c216
-rw-r--r--arch/um/kernel/skas/process_kern.c33
-rw-r--r--arch/um/kernel/skas/tlb.c29
-rw-r--r--arch/um/kernel/time.c7
-rw-r--r--arch/um/kernel/tlb.c132
-rw-r--r--arch/um/kernel/tt/tlb.c4
-rw-r--r--arch/um/kernel/uml.lds.S7
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c5
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c5
-rw-r--r--arch/um/scripts/Makefile.rules5
-rw-r--r--arch/um/sys-i386/Makefile12
-rw-r--r--arch/um/sys-i386/stub.S8
-rw-r--r--arch/um/sys-i386/stub_segv.c30
-rw-r--r--arch/um/sys-x86_64/Makefile12
-rw-r--r--arch/um/sys-x86_64/stub.S15
-rw-r--r--arch/um/sys-x86_64/stub_segv.c31
-rw-r--r--arch/x86_64/kernel/setup.c4
-rw-r--r--arch/x86_64/kernel/suspend.c1
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S4
-rw-r--r--arch/xtensa/kernel/syscalls.c152
-rw-r--r--arch/xtensa/kernel/syscalls.h57
-rw-r--r--drivers/bluetooth/bluecard_cs.c7
-rw-r--r--drivers/bluetooth/bt3c_cs.c7
-rw-r--r--drivers/bluetooth/btuart_cs.c7
-rw-r--r--drivers/bluetooth/dtl1_cs.c7
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/hvc_console.c429
-rw-r--r--drivers/char/hvc_vio.c152
-rw-r--r--drivers/char/hvsi.c8
-rw-r--r--drivers/char/n_tty.c33
-rw-r--r--drivers/char/pcmcia/synclink_cs.c7
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/sysrq.c2
-rw-r--r--drivers/cpufreq/cpufreq.c4
-rw-r--r--drivers/ide/legacy/ide-cs.c7
-rw-r--r--drivers/infiniband/Kconfig10
-rw-r--r--drivers/infiniband/core/Makefile5
-rw-r--r--drivers/infiniband/core/uverbs.h132
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c1006
-rw-r--r--drivers/infiniband/core/uverbs_main.c698
-rw-r--r--drivers/infiniband/core/uverbs_mem.c221
-rw-r--r--drivers/infiniband/core/verbs.c32
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c76
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c141
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.h14
-rw-r--r--drivers/infiniband/hw/mthca/mthca_pd.c24
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c330
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h16
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c215
-rw-r--r--drivers/infiniband/hw/mthca/mthca_user.h81
-rw-r--r--drivers/infiniband/include/ib_user_verbs.h389
-rw-r--r--drivers/infiniband/include/ib_verbs.h124
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c7
-rw-r--r--drivers/isdn/hisax/avma1_cs.c7
-rw-r--r--drivers/isdn/hisax/elsa_cs.c7
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c7
-rw-r--r--drivers/isdn/hisax/teles_cs.c7
-rw-r--r--drivers/md/dm-raid1.c1
-rw-r--r--drivers/media/common/saa7146_core.c13
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/Kconfig14
-rw-r--r--drivers/media/dvb/b2c2/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c165
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c12
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c12
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c122
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h548
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c2
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c34
-rw-r--r--drivers/media/dvb/b2c2/flexcop.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_be.h458
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_le.h458
-rw-r--r--drivers/media/dvb/b2c2/skystar2.c2644
-rw-r--r--drivers/media/dvb/bt8xx/dst.c233
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c349
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h3
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c4
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c19
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c44
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h22
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig34
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c10
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c295
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h30
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c62
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c2
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c73
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c76
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c96
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.h42
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-common.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h10
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c14
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c182
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h26
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c2
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c45
-rw-r--r--drivers/media/dvb/frontends/Kconfig13
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/cx22702.c29
-rw-r--r--drivers/media/dvb/frontends/cx22702.h5
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c85
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h6
-rw-r--r--drivers/media/dvb/frontends/l64781.c9
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.c611
-rw-r--r--drivers/media/dvb/frontends/lgdt3302.h49
-rw-r--r--drivers/media/dvb/frontends/lgdt3302_priv.h72
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c800
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h41
-rw-r--r--drivers/media/dvb/frontends/stv0297.c8
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c235
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h31
-rw-r--r--drivers/media/dvb/pluto2/Kconfig16
-rw-r--r--drivers/media/dvb/pluto2/Makefile3
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c809
-rw-r--r--drivers/media/dvb/ttpci/Kconfig9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c251
-rw-r--r--drivers/media/dvb/ttpci/av7110.h7
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c220
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.h4
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c395
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h12
-rw-r--r--drivers/media/dvb/ttpci/av7110_ipack.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c10
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c21
-rw-r--r--drivers/media/dvb/ttpci/budget.c99
-rw-r--r--drivers/media/dvb/ttusb-budget/Kconfig1
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c50
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c11
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusbdecfe.c14
-rw-r--r--drivers/media/video/Kconfig1
-rw-r--r--drivers/media/video/cx88/cx88-cards.c65
-rw-r--r--drivers/media/video/cx88/cx88-core.c19
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c66
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c3
-rw-r--r--drivers/media/video/cx88/cx88-input.c96
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c13
-rw-r--r--drivers/media/video/cx88/cx88-video.c59
-rw-r--r--drivers/media/video/cx88/cx88.h10
-rw-r--r--drivers/message/fusion/mptbase.c14
-rw-r--r--drivers/message/fusion/mptscsih.h2
-rw-r--r--drivers/message/i2o/config-osm.c2
-rw-r--r--drivers/mtd/maps/pcmciamtd.c7
-rw-r--r--drivers/net/pcmcia/3c574_cs.c7
-rw-r--r--drivers/net/pcmcia/3c589_cs.c7
-rw-r--r--drivers/net/pcmcia/axnet_cs.c7
-rw-r--r--drivers/net/pcmcia/com20020_cs.c7
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c7
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c7
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c7
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c7
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c6
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c7
-rw-r--r--drivers/net/skge.c4
-rw-r--r--drivers/net/sungem.c4
-rw-r--r--drivers/net/sungem_phy.c69
-rw-r--r--drivers/net/sungem_phy.h3
-rw-r--r--drivers/net/typhoon.c6
-rw-r--r--drivers/net/wireless/airo_cs.c7
-rw-r--r--drivers/net/wireless/atmel_cs.c17
-rw-r--r--drivers/net/wireless/netwave_cs.c7
-rw-r--r--drivers/net/wireless/orinoco_cs.c7
-rw-r--r--drivers/net/wireless/ray_cs.c7
-rw-r--r--drivers/net/wireless/wavelan_cs.c7
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h1
-rw-r--r--drivers/net/wireless/wl3501_cs.c19
-rw-r--r--drivers/parport/parport_cs.c7
-rw-r--r--drivers/pci/pcie/portdrv_core.c6
-rw-r--r--drivers/pcmcia/Kconfig17
-rw-r--r--drivers/pcmcia/au1000_generic.h1
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c1
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c1
-rw-r--r--drivers/pcmcia/cardbus.c1
-rw-r--r--drivers/pcmcia/cs.c16
-rw-r--r--drivers/pcmcia/cs_internal.h16
-rw-r--r--drivers/pcmcia/ds.c99
-rw-r--r--drivers/pcmcia/hd64465_ss.c1
-rw-r--r--drivers/pcmcia/i82365.c9
-rw-r--r--drivers/pcmcia/m32r_cfc.c1
-rw-r--r--drivers/pcmcia/m32r_pcc.c1
-rw-r--r--drivers/pcmcia/pcmcia_compat.c48
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c27
-rw-r--r--drivers/pcmcia/pcmcia_resource.c143
-rw-r--r--drivers/pcmcia/sa1100_generic.c1
-rw-r--r--drivers/pcmcia/soc_common.h1
-rw-r--r--drivers/pcmcia/socket_sysfs.c1
-rw-r--r--drivers/pcmcia/tcic.c1
-rw-r--r--drivers/pcmcia/ti113x.h4
-rw-r--r--drivers/pcmcia/yenta_socket.c11
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c7
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c7
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c17
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c4
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c5
-rw-r--r--drivers/serial/serial_cs.c7
-rw-r--r--drivers/telephony/ixj_pcmcia.c7
-rw-r--r--drivers/usb/host/sl811_cs.c7
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/logo/Kconfig5
-rw-r--r--drivers/video/logo/Makefile1
-rw-r--r--drivers/video/logo/logo.c5
-rw-r--r--drivers/video/logo/logo_m32r_clut224.ppm1292
-rw-r--r--drivers/video/s1d13xxxfb.c10
-rw-r--r--drivers/video/savage/savagefb_driver.c2
-rw-r--r--fs/Kconfig8
-rw-r--r--fs/autofs4/waitq.c4
-rw-r--r--fs/bio.c2
-rw-r--r--fs/buffer.c25
-rw-r--r--fs/dcookies.c6
-rw-r--r--fs/ext3/inode.c2
-rw-r--r--fs/hppfs/hppfs_kern.c7
-rw-r--r--fs/inode.c4
-rw-r--r--fs/ioprio.c4
-rw-r--r--fs/locks.c4
-rw-r--r--fs/namei.c2
-rw-r--r--fs/namespace.c130
-rw-r--r--fs/nfsd/nfs4proc.c6
-rw-r--r--fs/nfsd/nfs4recover.c32
-rw-r--r--fs/nfsd/nfs4state.c231
-rw-r--r--fs/nfsd/nfs4xdr.c15
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/super.c1
-rw-r--r--include/asm-alpha/pgtable.h2
-rw-r--r--include/asm-i386/mmzone.h24
-rw-r--r--include/asm-i386/processor.h8
-rw-r--r--include/asm-m32r/s1d13806.h199
-rw-r--r--include/asm-ppc/unistd.h2
-rw-r--r--include/asm-ppc64/cputable.h3
-rw-r--r--include/asm-ppc64/hvconsole.h17
-rw-r--r--include/asm-ppc64/machdep.h5
-rw-r--r--include/asm-ppc64/processor.h26
-rw-r--r--include/asm-ppc64/unistd.h6
-rw-r--r--include/asm-um/mmu_context.h6
-rw-r--r--include/asm-x86_64/proto.h7
-rw-r--r--include/asm-xtensa/unistd.h98
-rw-r--r--include/linux/buffer_head.h3
-rw-r--r--include/linux/cache.h6
-rw-r--r--include/linux/cpufreq.h2
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/gfp.h4
-rw-r--r--include/linux/ioprio.h3
-rw-r--r--include/linux/mount.h6
-rw-r--r--include/linux/namespace.h3
-rw-r--r--include/linux/nfsd/nfsd.h2
-rw-r--r--include/linux/nfsd/state.h9
-rw-r--r--include/linux/slab.h4
-rw-r--r--include/linux/string.h2
-rw-r--r--include/linux/swap.h2
-rw-r--r--include/linux/syscalls.h3
-rw-r--r--include/pcmcia/cs.h42
-rw-r--r--include/pcmcia/cs_types.h4
-rw-r--r--include/pcmcia/ds.h20
-rw-r--r--include/pcmcia/version.h3
-rw-r--r--ipc/compat.c1
-rw-r--r--kernel/power/disk.c10
-rw-r--r--kernel/power/process.c6
-rw-r--r--kernel/power/swsusp.c33
-rw-r--r--kernel/profile.c4
-rw-r--r--kernel/sched.c7
-rw-r--r--lib/radix-tree.c2
-rw-r--r--mm/mempool.c2
-rw-r--r--mm/oom_kill.c10
-rw-r--r--mm/page_alloc.c8
-rw-r--r--mm/slab.c12
-rw-r--r--net/sunrpc/xprt.c2
-rw-r--r--security/keys/keyring.c15
-rw-r--r--sound/oss/cs46xx.c6
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c20
-rw-r--r--sound/pcmcia/vx/vx_entry.c12
-rw-r--r--sound/pcmcia/vx/vxpocket.c1
344 files changed, 14701 insertions, 7136 deletions
diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb
index c7ed01b9f8f4..ac0797ea646c 100644
--- a/Documentation/dvb/README.dvb-usb
+++ b/Documentation/dvb/README.dvb-usb
@@ -13,14 +13,17 @@ different way: With the help of a dvb-usb-framework.
13The framework provides generic functions (mostly kernel API calls), such as: 13The framework provides generic functions (mostly kernel API calls), such as:
14 14
15- Transport Stream URB handling in conjunction with dvb-demux-feed-control 15- Transport Stream URB handling in conjunction with dvb-demux-feed-control
16 (bulk and isoc (TODO) are supported) 16 (bulk and isoc are supported)
17- registering the device for the DVB-API 17- registering the device for the DVB-API
18- registering an I2C-adapter if applicable 18- registering an I2C-adapter if applicable
19- remote-control/input-device handling 19- remote-control/input-device handling
20- firmware requesting and loading (currently just for the Cypress USB 20- firmware requesting and loading (currently just for the Cypress USB
21 controller) 21 controllers)
22- other functions/methods which can be shared by several drivers (such as 22- other functions/methods which can be shared by several drivers (such as
23 functions for bulk-control-commands) 23 functions for bulk-control-commands)
24- TODO: a I2C-chunker. It creates device-specific chunks of register-accesses
25 depending on length of a register and the number of values that can be
26 multi-written and multi-read.
24 27
25The source code of the particular DVB USB devices does just the communication 28The 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 29with the device via the bus. The connection between the DVB-API-functionality
@@ -36,93 +39,18 @@ the dvb-usb-lib.
36TODO: dynamic enabling and disabling of the pid-filter in regard to number of 39TODO: dynamic enabling and disabling of the pid-filter in regard to number of
37feeds requested. 40feeds requested.
38 41
39Supported devices USB1.1 42Supported devices
40======================== 43========================
41 44
42Produced and reselled by Twinhan: 45See the LinuxTV DVB Wiki at www.linuxtv.org for a complete list of
43--------------------------------- 46cards/drivers/firmwares:
44- TwinhanDTV USB-Ter DVB-T Device (VP7041)
45 http://www.twinhan.com/product_terrestrial_3.asp
46 47
47- TwinhanDTV Magic Box (VP7041e) 48http://www.linuxtv.org/wiki/index.php/DVB_USB
48 http://www.twinhan.com/product_terrestrial_4.asp
49
50- HAMA DVB-T USB device
51 http://www.hama.de/portal/articleId*110620/action*2598
52
53- CTS Portable (Chinese Television System) (2)
54 http://www.2cts.tv/ctsportable/
55
56- Unknown USB DVB-T device with vendor ID Hyper-Paltek
57
58
59Produced and reselled by KWorld:
60--------------------------------
61- KWorld V-Stream XPERT DTV DVB-T USB
62 http://www.kworld.com.tw/en/product/DVBT-USB/DVBT-USB.html
63
64- JetWay DTV DVB-T USB
65 http://www.jetway.com.tw/evisn/product/lcd-tv/DVT-USB/dtv-usb.htm
66
67- ADSTech Instant TV DVB-T USB
68 http://www.adstech.com/products/PTV-333/intro/PTV-333_intro.asp?pid=PTV-333
69
70
71Others:
72-------
73- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner)
74 http://82.161.246.249/products-tvbox.html
75
76- Compro Videomate DVB-U2000 - DVB-T USB (2)
77 http://www.comprousa.com/products/vmu2000.htm
78
79- Grandtec USB DVB-T
80 http://www.grand.com.tw/
81
82- AVerMedia AverTV DVBT USB
83 http://www.avermedia.com/
84
85- DiBcom USB DVB-T reference device (non-public)
86
87
88Supported devices USB2.0-only
89=============================
90- Twinhan MagicBox II
91 http://www.twinhan.com/product_terrestrial_7.asp
92
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
100 http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529
101
102
103Supported devices USB2.0 and USB1.1
104=============================
105- Typhoon/Yakumo/HAMA/Yuan DVB-T mobile USB2.0
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
110
111- Artec T1 USB TVBOX (FX2) (2)
112
113- Hauppauge WinTV NOVA-T USB2
114 http://www.hauppauge.com/
115
116- KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B)
117
118- DiBcom USB2.0 DVB-T reference device (non-public)
119
120- AVerMedia AverTV A800 DVB-T USB2.0
121
1221) It is working almost - work-in-progress.
1232) No test reports received yet.
124 49
1250. History & News: 500. History & News:
51 2005-06-30 - added support for WideView WT-220U (Thanks to Steve Chang)
52 2005-05-30 - added basic isochronous support to the dvb-usb-framework
53 added support for Conexant Hybrid reference design and Nebula DigiTV USB
126 2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework 54 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. 55 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. 56 2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
@@ -137,7 +65,7 @@ Supported devices USB2.0 and USB1.1
137 2005-01-31 - distorted streaming is gone for USB1.1 devices 65 2005-01-31 - distorted streaming is gone for USB1.1 devices
138 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb 66 2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
139 - first almost working version for HanfTek UMT-010 67 - first almost working version for HanfTek UMT-010
140 - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010 68 - found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
141 2005-01-10 - refactoring completed, now everything is very delightful 69 2005-01-10 - refactoring completed, now everything is very delightful
142 - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a 70 - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
143 Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich. 71 Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
@@ -187,25 +115,13 @@ Supported devices USB2.0 and USB1.1
1871. How to use? 1151. How to use?
1881.1. Firmware 1161.1. Firmware
189 117
190Most of the USB drivers need to download a firmware to start working. 118Most of the USB drivers need to download a firmware to the device before start
191 119working.
192for USB1.1 (AN2135) you need: dvb-usb-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
197
198The files can be found on http://www.linuxtv.org/download/firmware/ .
199 120
200We do not have the permission (yet) to publish the following firmware-files. 121Have a look at the Wikipage for the DVB-USB-drivers to find out, which firmware
201You'll need to extract them from the windows drivers. 122you need for your device:
202 123
203You should be able to use "get_dvb_firmware dvb-usb" to get the firmware: 124http://www.linuxtv.org/wiki/index.php/DVB_USB
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
209 125
2101.2. Compiling 1261.2. Compiling
211 127
@@ -289,6 +205,9 @@ Patches, comments and suggestions are very very welcome.
289 Gunnar Wittich and Joachim von Caron for their trust for providing 205 Gunnar Wittich and Joachim von Caron for their trust for providing
290 root-shells on their machines to implement support for new devices. 206 root-shells on their machines to implement support for new devices.
291 207
208 Allan Third and Michael Hutchinson for their help to write the Nebula
209 digitv-driver.
210
292 Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei 211 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 212 Jung from AVerMedia who kindly provided a special firmware to get the device
294 up and running in Linux. 213 up and running in Linux.
@@ -296,7 +215,12 @@ Patches, comments and suggestions are very very welcome.
296 Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by 215 Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
297 writing the vp7045-driver. 216 writing the vp7045-driver.
298 217
299 Some guys on the linux-dvb mailing list for encouraging me 218 Steve Chang from WideView for providing information for new devices and
219 firmware files.
220
221 Michael Paxton for submitting remote control keymaps.
222
223 Some guys on the linux-dvb mailing list for encouraging me.
300 224
301 Peter Schildmann >peter.schildmann-nospam-at-web.de< for his 225 Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
302 user-level firmware loader, which saves a lot of time 226 user-level firmware loader, which saves a lot of time
@@ -305,4 +229,4 @@ Patches, comments and suggestions are very very welcome.
305 Ulf Hermenau for helping me out with traditional chinese. 229 Ulf Hermenau for helping me out with traditional chinese.
306 230
307 André Smoktun and Christian Frömmel for supporting me with 231 André Smoktun and Christian Frömmel for supporting me with
308 hardware and listening to my problems very patient. 232 hardware and listening to my problems very patiently.
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
index 3a3260794758..e6b8d05bc08d 100644
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,66 +1,55 @@
1How to get the Nebula, PCTV and Twinhan DST cards working 1How to get the Nebula Electronics DigiTV, Pinnacle PCTV Sat, Twinhan DST + clones working
2========================================================= 2=========================================================================================
3 3
4This class of cards has a bt878a as the PCI interface, and 41) General information
5require the bttv driver. 5======================
6 6
7Please pay close attention to the warning about the bttv module 7This class of cards has a bt878a chip as the PCI interface.
8options below for the DST card. 8The different card drivers require the bttv driver to provide the means
9to access the i2c bus and the gpio pins of the bt8xx chipset.
9 10
101) General informations 112) Compilation rules for Kernel >= 2.6.12
11======================= 12=========================================
12 13
13These drivers require the bttv driver to provide the means to access 14Enable the following options:
14the i2c bus and the gpio pins of the bt8xx chipset.
15 15
16Because of this, you need to enable
17"Device drivers" => "Multimedia devices" 16"Device drivers" => "Multimedia devices"
18 => "Video For Linux" => "BT848 Video For Linux" 17 => "Video For Linux" => "BT848 Video For Linux"
19
20Furthermore you need to enable
21"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" 18"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
22 => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards" 19 => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
23 20
242) Loading Modules 213) Loading Modules, described by two approaches
25================== 22===============================================
26 23
27In general you need to load the bttv driver, which will handle the gpio and 24In general you need to load the bttv driver, which will handle the gpio and
28i2c communication for us, plus the common dvb-bt8xx device driver. 25i2c communication for us, plus the common dvb-bt8xx device driver,
29The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and 26which is called the backend.
30TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver. 27The frontends for Nebula DigiTV (nxt6000), Pinnacle PCTV Sat (cx24110),
28TwinHan DST + clones (dst and dst-ca) are loaded automatically by the backend.
29For further details about TwinHan DST + clones see /Documentation/dvb/ci.txt.
31 30
323a) Nebula / Pinnacle PCTV 313a) The manual approach
33-------------------------- 32-----------------------
34 33
35 $ modprobe bttv (normally bttv is being loaded automatically by kmod) 34Loading modules:
36 $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading) 35modprobe bttv
36modprobe dvb-bt8xx
37 37
38Unloading modules:
39modprobe -r dvb-bt8xx
40modprobe -r bttv
38 41
393b) TwinHan and Clones 423b) The automatic approach
40-------------------------- 43--------------------------
41 44
42 $ modprobe bttv i2c_hw=1 card=0x71 45If not already done by installation, place a line either in
43 $ modprobe dvb-bt8xx 46/etc/modules.conf or in /etc/modprobe.conf containing this text:
44 $ modprobe dst 47alias char-major-81 bttv
45
46The value 0x71 will override the PCI type detection for dvb-bt8xx,
47which is necessary for TwinHan cards.
48
49If you're having an older card (blue color circuit) and card=0x71 locks
50your machine, try using 0x68, too. If that does not work, ask on the
51mailing list.
52
53The DST module takes a couple of useful parameters:
54 48
55a. verbose takes values 0 to 5. These values control the verbosity level. 49Then place a line in /etc/modules containing this text:
56b. debug takes values 0 and 1. You can either disable or enable debugging. 50dvb-bt8xx
57c. dst_addons takes values 0 and 0x20:
58- A value of 0 means it is a FTA card.
59- A value of 0x20 means it has a Conditional Access slot.
60 51
61The autodetected values are determined by the "response string" 52Reboot your system and have fun!
62of the card, which you can see in your logs:
63e.g.: dst_get_device_id: Recognize [DSTMCI]
64 53
65-- 54--
66Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla 55Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 1d227ee3792a..12dde43fe657 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -119,3 +119,19 @@ Why: Match the other drivers' name for the same function, duplicate names
119 will be available until removal of old names. 119 will be available until removal of old names.
120Who: Grant Coady <gcoady@gmail.com> 120Who: Grant Coady <gcoady@gmail.com>
121 121
122---------------------------
123
124What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
125When: November 2005
126Files: drivers/pcmcia/: pcmcia_ioctl.c
127Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a
128 normal hotpluggable bus, and with it using the default kernel
129 infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA
130 control ioctl needed by cardmgr and cardctl from pcmcia-cs is
131 unnecessary, and makes further cleanups and integration of the
132 PCMCIA subsystem into the Linux kernel device driver model more
133 difficult. The features provided by cardmgr and cardctl are either
134 handled by the kernel itself now or are available in the new
135 pcmciautils package available at
136 http://kernel.org/pub/linux/utils/kernel/pcmcia/
137Who: Dominik Brodowski <linux@brodo.de>
diff --git a/Documentation/infiniband/user_verbs.txt b/Documentation/infiniband/user_verbs.txt
new file mode 100644
index 000000000000..f847501e50b5
--- /dev/null
+++ b/Documentation/infiniband/user_verbs.txt
@@ -0,0 +1,69 @@
1USERSPACE VERBS ACCESS
2
3 The ib_uverbs module, built by enabling CONFIG_INFINIBAND_USER_VERBS,
4 enables direct userspace access to IB hardware via "verbs," as
5 described in chapter 11 of the InfiniBand Architecture Specification.
6
7 To use the verbs, the libibverbs library, available from
8 <http://openib.org/>, is required. libibverbs contains a
9 device-independent API for using the ib_uverbs interface.
10 libibverbs also requires appropriate device-dependent kernel and
11 userspace driver for your InfiniBand hardware. For example, to use
12 a Mellanox HCA, you will need the ib_mthca kernel module and the
13 libmthca userspace driver be installed.
14
15User-kernel communication
16
17 Userspace communicates with the kernel for slow path, resource
18 management operations via the /dev/infiniband/uverbsN character
19 devices. Fast path operations are typically performed by writing
20 directly to hardware registers mmap()ed into userspace, with no
21 system call or context switch into the kernel.
22
23 Commands are sent to the kernel via write()s on these device files.
24 The ABI is defined in drivers/infiniband/include/ib_user_verbs.h.
25 The structs for commands that require a response from the kernel
26 contain a 64-bit field used to pass a pointer to an output buffer.
27 Status is returned to userspace as the return value of the write()
28 system call.
29
30Resource management
31
32 Since creation and destruction of all IB resources is done by
33 commands passed through a file descriptor, the kernel can keep track
34 of which resources are attached to a given userspace context. The
35 ib_uverbs module maintains idr tables that are used to translate
36 between kernel pointers and opaque userspace handles, so that kernel
37 pointers are never exposed to userspace and userspace cannot trick
38 the kernel into following a bogus pointer.
39
40 This also allows the kernel to clean up when a process exits and
41 prevent one process from touching another process's resources.
42
43Memory pinning
44
45 Direct userspace I/O requires that memory regions that are potential
46 I/O targets be kept resident at the same physical address. The
47 ib_uverbs module manages pinning and unpinning memory regions via
48 get_user_pages() and put_page() calls. It also accounts for the
49 amount of memory pinned in the process's locked_vm, and checks that
50 unprivileged processes do not exceed their RLIMIT_MEMLOCK limit.
51
52 Pages that are pinned multiple times are counted each time they are
53 pinned, so the value of locked_vm may be an overestimate of the
54 number of pages pinned by a process.
55
56/dev files
57
58 To create the appropriate character device files automatically with
59 udev, a rule like
60
61 KERNEL="uverbs*", NAME="infiniband/%k"
62
63 can be used. This will create device nodes named
64
65 /dev/infiniband/uverbs0
66
67 and so on. Since the InfiniBand userspace verbs should be safe for
68 use by non-privileged processes, it may be useful to add an
69 appropriate MODE or GROUP to the udev rule.
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt
index 881a37e3eeb0..7a4a5036d123 100644
--- a/Documentation/power/video.txt
+++ b/Documentation/power/video.txt
@@ -117,6 +117,7 @@ IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4)
117Medion MD4220 ??? (*) 117Medion MD4220 ??? (*)
118Samsung P35 vbetool needed (6) 118Samsung P35 vbetool needed (6)
119Sharp PC-AR10 (ATI rage) none (1) 119Sharp PC-AR10 (ATI rage) none (1)
120Sony Vaio PCG-C1VRX/K s3_bios (2)
120Sony Vaio PCG-F403 ??? (*) 121Sony Vaio PCG-F403 ??? (*)
121Sony Vaio PCG-N505SN ??? (*) 122Sony Vaio PCG-N505SN ??? (*)
122Sony Vaio vgn-s260 X or boot-radeon can init it (5) 123Sony Vaio vgn-s260 X or boot-radeon can init it (5)
diff --git a/MAINTAINERS b/MAINTAINERS
index 302b31960008..37fb1e2ec687 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -370,6 +370,10 @@ W: http://www.thekelleys.org.uk/atmel
370W: http://atmelwlandriver.sourceforge.net/ 370W: http://atmelwlandriver.sourceforge.net/
371S: Maintained 371S: Maintained
372 372
373AUDIT SUBSYSTEM
374L: linux-audit@redhat.com (subscribers-only)
375S: Maintained
376
373AX.25 NETWORK LAYER 377AX.25 NETWORK LAYER
374P: Ralf Baechle 378P: Ralf Baechle
375M: ralf@linux-mips.org 379M: ralf@linux-mips.org
@@ -1803,8 +1807,9 @@ M: greg@kroah.com
1803S: Maintained 1807S: Maintained
1804 1808
1805PCMCIA SUBSYSTEM 1809PCMCIA SUBSYSTEM
1810P: Linux PCMCIA Team
1806L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia 1811L: http://lists.infradead.org/mailman/listinfo/linux-pcmcia
1807S: Unmaintained 1812S: Maintained
1808 1813
1809PCNET32 NETWORK DRIVER 1814PCNET32 NETWORK DRIVER
1810P: Thomas Bogendörfer 1815P: Thomas Bogendörfer
diff --git a/Makefile b/Makefile
index 278d50992c71..9cf07e7b9f88 100644
--- a/Makefile
+++ b/Makefile
@@ -792,6 +792,9 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
792 $(Q)$(MAKE) $(build)=$(@D) $@ 792 $(Q)$(MAKE) $(build)=$(@D) $@
793%.o: %.c scripts FORCE 793%.o: %.c scripts FORCE
794 $(Q)$(MAKE) $(build)=$(@D) $@ 794 $(Q)$(MAKE) $(build)=$(@D) $@
795%.ko: scripts FORCE
796 $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) $(@:.ko=.o)
797 $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
795%/: scripts prepare FORCE 798%/: scripts prepare FORCE
796 $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) 799 $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D)
797%.lst: %.c scripts FORCE 800%.lst: %.c scripts FORCE
@@ -1033,6 +1036,7 @@ help:
1033 @echo ' modules_install - Install all modules' 1036 @echo ' modules_install - Install all modules'
1034 @echo ' dir/ - Build all files in dir and below' 1037 @echo ' dir/ - Build all files in dir and below'
1035 @echo ' dir/file.[ois] - Build specified target only' 1038 @echo ' dir/file.[ois] - Build specified target only'
1039 @echo ' dir/file.ko - Build module including final link'
1036 @echo ' rpm - Build a kernel as an RPM package' 1040 @echo ' rpm - Build a kernel as an RPM package'
1037 @echo ' tags/TAGS - Generate tags file for editors' 1041 @echo ' tags/TAGS - Generate tags file for editors'
1038 @echo ' cscope - Generate cscope index' 1042 @echo ' cscope - Generate cscope index'
@@ -1149,7 +1153,7 @@ endif # KBUILD_EXTMOD
1149#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file. 1153#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file.
1150#Adding $(srctree) adds about 20M on i386 to the size of the output file! 1154#Adding $(srctree) adds about 20M on i386 to the size of the output file!
1151 1155
1152ifeq ($(KBUILD_OUTPUT),) 1156ifeq ($(src),$(obj))
1153__srctree = 1157__srctree =
1154else 1158else
1155__srctree = $(srctree)/ 1159__srctree = $(srctree)/
diff --git a/arch/frv/defconfig b/arch/frv/defconfig
new file mode 100644
index 000000000000..b6e4ca5efb59
--- /dev/null
+++ b/arch/frv/defconfig
@@ -0,0 +1,627 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.11.8
4# Fri May 13 17:16:03 2005
5#
6CONFIG_FRV=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_FIND_NEXT_BIT=y
10# CONFIG_GENERIC_CALIBRATE_DELAY is not set
11# CONFIG_GENERIC_HARDIRQS is not set
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25CONFIG_SWAP=y
26CONFIG_SYSVIPC=y
27CONFIG_POSIX_MQUEUE=y
28# CONFIG_BSD_PROCESS_ACCT is not set
29CONFIG_SYSCTL=y
30# CONFIG_AUDIT is not set
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_PRINTK=y
39CONFIG_BUG=y
40CONFIG_BASE_FULL=y
41CONFIG_FUTEX=y
42CONFIG_EPOLL=y
43# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
44CONFIG_SHMEM=y
45CONFIG_CC_ALIGN_FUNCTIONS=0
46CONFIG_CC_ALIGN_LABELS=0
47CONFIG_CC_ALIGN_LOOPS=0
48CONFIG_CC_ALIGN_JUMPS=0
49# CONFIG_TINY_SHMEM is not set
50CONFIG_BASE_SMALL=0
51
52#
53# Loadable module support
54#
55# CONFIG_MODULES is not set
56
57#
58# Fujitsu FR-V system setup
59#
60CONFIG_MMU=y
61CONFIG_FRV_OUTOFLINE_ATOMIC_OPS=y
62CONFIG_HIGHMEM=y
63CONFIG_HIGHPTE=y
64CONFIG_SELECT_MEMORY_MODEL=y
65CONFIG_FLATMEM_MANUAL=y
66# CONFIG_DISCONTIGMEM_MANUAL is not set
67# CONFIG_SPARSEMEM_MANUAL is not set
68CONFIG_FLATMEM=y
69CONFIG_FLAT_NODE_MEM_MAP=y
70# CONFIG_FRV_DEFL_CACHE_WBACK is not set
71# CONFIG_FRV_DEFL_CACHE_WBEHIND is not set
72CONFIG_FRV_DEFL_CACHE_WTHRU=y
73# CONFIG_FRV_DEFL_CACHE_DISABLED is not set
74
75#
76# CPU core support
77#
78CONFIG_CPU_FR451=y
79CONFIG_CPU_FR451_COMPILE=y
80CONFIG_FRV_L1_CACHE_SHIFT=5
81CONFIG_MB93091_VDK=y
82# CONFIG_MB93093_PDK is not set
83CONFIG_MB93090_MB00=y
84# CONFIG_MB93091_NO_MB is not set
85# CONFIG_GPREL_DATA_8 is not set
86CONFIG_GPREL_DATA_4=y
87# CONFIG_GPREL_DATA_NONE is not set
88CONFIG_PCI=y
89# CONFIG_PCI_LEGACY_PROC is not set
90# CONFIG_PCI_NAMES is not set
91# CONFIG_PCI_DEBUG is not set
92# CONFIG_PCMCIA is not set
93
94#
95# Power management options
96#
97# CONFIG_PM is not set
98
99#
100# Executable formats
101#
102# CONFIG_BINFMT_ELF is not set
103CONFIG_BINFMT_ELF_FDPIC=y
104# CONFIG_BINFMT_MISC is not set
105
106#
107# Device Drivers
108#
109
110#
111# Generic Driver Options
112#
113# CONFIG_STANDALONE is not set
114# CONFIG_PREVENT_FIRMWARE_BUILD is not set
115# CONFIG_FW_LOADER is not set
116# CONFIG_DEBUG_DRIVER is not set
117
118#
119# Connector - unified userspace <-> kernelspace linker
120#
121# CONFIG_CONNECTOR is not set
122# CONFIG_FORK_CONNECTOR is not set
123
124#
125# Memory Technology Devices (MTD)
126#
127# CONFIG_MTD is not set
128
129#
130# Parallel port support
131#
132# CONFIG_PARPORT is not set
133
134#
135# Plug and Play support
136#
137
138#
139# Block devices
140#
141# CONFIG_BLK_DEV_FD is not set
142# CONFIG_BLK_CPQ_DA is not set
143# CONFIG_BLK_CPQ_CISS_DA is not set
144# CONFIG_BLK_DEV_DAC960 is not set
145# CONFIG_BLK_DEV_UMEM is not set
146# CONFIG_BLK_DEV_COW_COMMON is not set
147# CONFIG_BLK_DEV_LOOP is not set
148# CONFIG_BLK_DEV_NBD is not set
149# CONFIG_BLK_DEV_SX8 is not set
150# CONFIG_BLK_DEV_RAM is not set
151CONFIG_BLK_DEV_RAM_COUNT=16
152CONFIG_INITRAMFS_SOURCE=""
153# CONFIG_CDROM_PKTCDVD is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159CONFIG_IOSCHED_AS=y
160CONFIG_IOSCHED_DEADLINE=y
161CONFIG_IOSCHED_CFQ=y
162# CONFIG_ATA_OVER_ETH is not set
163
164#
165# ATA/ATAPI/MFM/RLL support
166#
167# CONFIG_IDE is not set
168
169#
170# SCSI device support
171#
172# CONFIG_SCSI is not set
173
174#
175# Multi-device support (RAID and LVM)
176#
177# CONFIG_MD is not set
178
179#
180# Fusion MPT device support
181#
182# CONFIG_FUSION is not set
183
184#
185# IEEE 1394 (FireWire) support
186#
187# CONFIG_IEEE1394 is not set
188
189#
190# I2O device support
191#
192# CONFIG_I2O is not set
193
194#
195# Networking support
196#
197CONFIG_NET=y
198
199#
200# Networking options
201#
202CONFIG_PACKET=y
203# CONFIG_PACKET_MMAP is not set
204CONFIG_UNIX=y
205# CONFIG_NET_KEY is not set
206CONFIG_INET=y
207# CONFIG_IP_MULTICAST is not set
208# CONFIG_IP_ADVANCED_ROUTER is not set
209CONFIG_IP_PNP=y
210# CONFIG_IP_PNP_DHCP is not set
211# CONFIG_IP_PNP_BOOTP is not set
212# CONFIG_IP_PNP_RARP is not set
213# CONFIG_NET_IPIP is not set
214# CONFIG_NET_IPGRE is not set
215# CONFIG_ARPD is not set
216# CONFIG_SYN_COOKIES is not set
217# CONFIG_INET_AH is not set
218# CONFIG_INET_ESP is not set
219# CONFIG_INET_IPCOMP is not set
220# CONFIG_INET_TUNNEL is not set
221# CONFIG_IP_TCPDIAG is not set
222# CONFIG_IP_TCPDIAG_IPV6 is not set
223# CONFIG_IPV6 is not set
224# CONFIG_NETFILTER is not set
225
226#
227# SCTP Configuration (EXPERIMENTAL)
228#
229# CONFIG_IP_SCTP is not set
230# CONFIG_ATM is not set
231# CONFIG_BRIDGE is not set
232# CONFIG_VLAN_8021Q is not set
233# CONFIG_DECNET is not set
234# CONFIG_LLC2 is not set
235# CONFIG_IPX is not set
236# CONFIG_ATALK is not set
237# CONFIG_X25 is not set
238# CONFIG_LAPB is not set
239# CONFIG_NET_DIVERT is not set
240# CONFIG_ECONET is not set
241# CONFIG_WAN_ROUTER is not set
242
243#
244# QoS and/or fair queueing
245#
246# CONFIG_NET_SCHED is not set
247# CONFIG_NET_CLS_ROUTE is not set
248
249#
250# Network testing
251#
252# CONFIG_NET_PKTGEN is not set
253# CONFIG_KGDBOE is not set
254# CONFIG_NETPOLL is not set
255# CONFIG_NETPOLL_RX is not set
256# CONFIG_NETPOLL_TRAP is not set
257# CONFIG_NET_POLL_CONTROLLER is not set
258# CONFIG_HAMRADIO is not set
259# CONFIG_IRDA is not set
260# CONFIG_BT is not set
261# CONFIG_IEEE80211 is not set
262CONFIG_NETDEVICES=y
263# CONFIG_DUMMY is not set
264# CONFIG_BONDING is not set
265# CONFIG_EQUALIZER is not set
266# CONFIG_TUN is not set
267
268#
269# ARCnet devices
270#
271# CONFIG_ARCNET is not set
272
273#
274# Ethernet (10 or 100Mbit)
275#
276CONFIG_NET_ETHERNET=y
277CONFIG_MII=y
278# CONFIG_HAPPYMEAL is not set
279# CONFIG_SUNGEM is not set
280# CONFIG_NET_VENDOR_3COM is not set
281
282#
283# Tulip family network device support
284#
285# CONFIG_NET_TULIP is not set
286# CONFIG_HP100 is not set
287CONFIG_NET_PCI=y
288# CONFIG_PCNET32 is not set
289# CONFIG_AMD8111_ETH is not set
290# CONFIG_ADAPTEC_STARFIRE is not set
291# CONFIG_B44 is not set
292# CONFIG_FORCEDETH is not set
293# CONFIG_DGRS is not set
294# CONFIG_EEPRO100 is not set
295# CONFIG_E100 is not set
296# CONFIG_FEALNX is not set
297# CONFIG_NATSEMI is not set
298CONFIG_NE2K_PCI=y
299# CONFIG_8139CP is not set
300# CONFIG_8139TOO is not set
301# CONFIG_SIS900 is not set
302# CONFIG_EPIC100 is not set
303# CONFIG_SUNDANCE is not set
304# CONFIG_TLAN is not set
305# CONFIG_VIA_RHINE is not set
306
307#
308# Ethernet (1000 Mbit)
309#
310# CONFIG_ACENIC is not set
311# CONFIG_DL2K is not set
312# CONFIG_E1000 is not set
313# CONFIG_NS83820 is not set
314# CONFIG_HAMACHI is not set
315# CONFIG_YELLOWFIN is not set
316# CONFIG_R8169 is not set
317# CONFIG_SKGE is not set
318# CONFIG_SK98LIN is not set
319# CONFIG_VIA_VELOCITY is not set
320# CONFIG_TIGON3 is not set
321
322#
323# Ethernet (10000 Mbit)
324#
325# CONFIG_CHELSIO_T1 is not set
326# CONFIG_IXGB is not set
327# CONFIG_S2IO is not set
328
329#
330# Token Ring devices
331#
332# CONFIG_TR is not set
333
334#
335# Wireless LAN (non-hamradio)
336#
337# CONFIG_NET_RADIO is not set
338
339#
340# Wan interfaces
341#
342# CONFIG_WAN is not set
343# CONFIG_FDDI is not set
344# CONFIG_HIPPI is not set
345# CONFIG_PPP is not set
346# CONFIG_SLIP is not set
347# CONFIG_SHAPER is not set
348# CONFIG_NETCONSOLE is not set
349
350#
351# ISDN subsystem
352#
353# CONFIG_ISDN is not set
354
355#
356# Telephony Support
357#
358# CONFIG_PHONE is not set
359
360#
361# Input device support
362#
363# CONFIG_INPUT is not set
364
365#
366# Hardware I/O ports
367#
368# CONFIG_SERIO is not set
369# CONFIG_GAMEPORT is not set
370
371#
372# Character devices
373#
374# CONFIG_VT is not set
375# CONFIG_SERIAL_NONSTANDARD is not set
376
377#
378# Serial drivers
379#
380CONFIG_SERIAL_8250=y
381CONFIG_SERIAL_8250_CONSOLE=y
382CONFIG_SERIAL_8250_NR_UARTS=1
383CONFIG_SERIAL_8250_EXTENDED=y
384# CONFIG_SERIAL_8250_MANY_PORTS is not set
385CONFIG_SERIAL_8250_SHARE_IRQ=y
386# CONFIG_SERIAL_8250_DETECT_IRQ is not set
387# CONFIG_SERIAL_8250_MULTIPORT is not set
388# CONFIG_SERIAL_8250_RSA is not set
389
390#
391# Non-8250 serial port support
392#
393CONFIG_SERIAL_CORE=y
394CONFIG_SERIAL_CORE_CONSOLE=y
395# CONFIG_SERIAL_JSM is not set
396CONFIG_UNIX98_PTYS=y
397# CONFIG_LEGACY_PTYS is not set
398
399#
400# IPMI
401#
402# CONFIG_IPMI_HANDLER is not set
403
404#
405# Watchdog Cards
406#
407# CONFIG_WATCHDOG is not set
408# CONFIG_RTC is not set
409# CONFIG_GEN_RTC is not set
410# CONFIG_DTLK is not set
411# CONFIG_R3964 is not set
412# CONFIG_APPLICOM is not set
413
414#
415# Ftape, the floppy tape device driver
416#
417# CONFIG_DRM is not set
418# CONFIG_RAW_DRIVER is not set
419
420#
421# TPM devices
422#
423# CONFIG_TCG_TPM is not set
424
425#
426# I2C support
427#
428# CONFIG_I2C is not set
429
430#
431# Dallas's 1-wire bus
432#
433# CONFIG_W1 is not set
434
435#
436# Misc devices
437#
438
439#
440# Multimedia devices
441#
442# CONFIG_VIDEO_DEV is not set
443
444#
445# Digital Video Broadcasting Devices
446#
447# CONFIG_DVB is not set
448
449#
450# Graphics support
451#
452# CONFIG_FB is not set
453
454#
455# Sound
456#
457# CONFIG_SOUND is not set
458
459#
460# USB support
461#
462CONFIG_USB_ARCH_HAS_HCD=y
463CONFIG_USB_ARCH_HAS_OHCI=y
464# CONFIG_USB is not set
465
466#
467# USB Gadget Support
468#
469# CONFIG_USB_GADGET is not set
470
471#
472# MMC/SD Card support
473#
474# CONFIG_MMC is not set
475
476#
477# InfiniBand support
478#
479# CONFIG_INFINIBAND is not set
480
481#
482# File systems
483#
484# CONFIG_EXT2_FS is not set
485# CONFIG_EXT3_FS is not set
486# CONFIG_JBD is not set
487# CONFIG_REISER4_FS is not set
488# CONFIG_REISERFS_FS is not set
489# CONFIG_JFS_FS is not set
490
491#
492# XFS support
493#
494# CONFIG_XFS_FS is not set
495# CONFIG_MINIX_FS is not set
496# CONFIG_ROMFS_FS is not set
497CONFIG_INOTIFY=y
498# CONFIG_QUOTA is not set
499CONFIG_DNOTIFY=y
500# CONFIG_AUTOFS_FS is not set
501# CONFIG_AUTOFS4_FS is not set
502
503#
504# Caches
505#
506# CONFIG_FSCACHE is not set
507# CONFIG_FUSE_FS is not set
508
509#
510# CD-ROM/DVD Filesystems
511#
512# CONFIG_ISO9660_FS is not set
513# CONFIG_UDF_FS is not set
514
515#
516# DOS/FAT/NT Filesystems
517#
518# CONFIG_MSDOS_FS is not set
519# CONFIG_VFAT_FS is not set
520# CONFIG_NTFS_FS is not set
521
522#
523# Pseudo filesystems
524#
525CONFIG_PROC_FS=y
526# CONFIG_PROC_KCORE is not set
527CONFIG_SYSFS=y
528# CONFIG_DEVFS_FS is not set
529# CONFIG_DEVPTS_FS_XATTR is not set
530CONFIG_TMPFS=y
531# CONFIG_TMPFS_XATTR is not set
532# CONFIG_HUGETLB_PAGE is not set
533CONFIG_RAMFS=y
534# CONFIG_RELAYFS_FS is not set
535
536#
537# Miscellaneous filesystems
538#
539# CONFIG_ADFS_FS is not set
540# CONFIG_AFFS_FS is not set
541# CONFIG_HFS_FS is not set
542# CONFIG_HFSPLUS_FS is not set
543# CONFIG_BEFS_FS is not set
544# CONFIG_BFS_FS is not set
545# CONFIG_EFS_FS is not set
546# CONFIG_CRAMFS is not set
547# CONFIG_VXFS_FS is not set
548# CONFIG_HPFS_FS is not set
549# CONFIG_QNX4FS_FS is not set
550# CONFIG_SYSV_FS is not set
551# CONFIG_UFS_FS is not set
552
553#
554# Network File Systems
555#
556CONFIG_NFS_FS=y
557# CONFIG_NFS_V3 is not set
558# CONFIG_NFS_V4 is not set
559# CONFIG_NFS_DIRECTIO is not set
560# CONFIG_NFSD is not set
561CONFIG_ROOT_NFS=y
562CONFIG_LOCKD=y
563CONFIG_NFS_COMMON=y
564CONFIG_SUNRPC=y
565# CONFIG_RPCSEC_GSS_KRB5 is not set
566# CONFIG_RPCSEC_GSS_SPKM3 is not set
567# CONFIG_SMB_FS is not set
568# CONFIG_CIFS is not set
569# CONFIG_NCP_FS is not set
570# CONFIG_CODA_FS is not set
571# CONFIG_AFS_FS is not set
572
573#
574# Partition Types
575#
576# CONFIG_PARTITION_ADVANCED is not set
577CONFIG_MSDOS_PARTITION=y
578
579#
580# Native Language Support
581#
582# CONFIG_NLS is not set
583
584#
585# Kernel hacking
586#
587# CONFIG_PRINTK_TIME is not set
588CONFIG_DEBUG_KERNEL=y
589# CONFIG_MAGIC_SYSRQ is not set
590CONFIG_LOG_BUF_SHIFT=14
591CONFIG_DETECT_SOFTLOCKUP=y
592# CONFIG_SCHEDSTATS is not set
593# CONFIG_DEBUG_SLAB is not set
594# CONFIG_DEBUG_SPINLOCK is not set
595# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
596# CONFIG_DEBUG_KOBJECT is not set
597# CONFIG_DEBUG_HIGHMEM is not set
598# CONFIG_DEBUG_BUGVERBOSE is not set
599# CONFIG_DEBUG_INFO is not set
600# CONFIG_DEBUG_FS is not set
601# CONFIG_FRAME_POINTER is not set
602# CONFIG_EARLY_PRINTK is not set
603CONFIG_DEBUG_STACKOVERFLOW=y
604# CONFIG_DEBUG_PAGEALLOC is not set
605# CONFIG_GDBSTUB is not set
606
607#
608# Security options
609#
610# CONFIG_KEYS is not set
611# CONFIG_SECURITY is not set
612
613#
614# Cryptographic options
615#
616# CONFIG_CRYPTO is not set
617
618#
619# Hardware crypto devices
620#
621
622#
623# Library routines
624#
625# CONFIG_CRC_CCITT is not set
626CONFIG_CRC32=y
627# CONFIG_LIBCRC32C is not set
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 2203a9d20212..4553ffd94b1f 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -435,6 +435,11 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
435 if (c == &boot_cpu_data) 435 if (c == &boot_cpu_data)
436 sysenter_setup(); 436 sysenter_setup();
437 enable_sep_cpu(); 437 enable_sep_cpu();
438
439 if (c == &boot_cpu_data)
440 mtrr_bp_init();
441 else
442 mtrr_ap_init();
438} 443}
439 444
440#ifdef CONFIG_X86_HT 445#ifdef CONFIG_X86_HT
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index 96a75d045835..a2c33c1a46c5 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -25,7 +25,7 @@ extern int trap_init_f00f_bug(void);
25/* 25/*
26 * Alignment at which movsl is preferred for bulk memory copies. 26 * Alignment at which movsl is preferred for bulk memory copies.
27 */ 27 */
28struct movsl_mask movsl_mask; 28struct movsl_mask movsl_mask __read_mostly;
29#endif 29#endif
30 30
31void __devinit early_intel_workaround(struct cpuinfo_x86 *c) 31void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
index 64d91f73a0a4..169ac8e0db68 100644
--- a/arch/i386/kernel/cpu/mtrr/generic.c
+++ b/arch/i386/kernel/cpu/mtrr/generic.c
@@ -67,13 +67,6 @@ void __init get_mtrr_state(void)
67 mtrr_state.enabled = (lo & 0xc00) >> 10; 67 mtrr_state.enabled = (lo & 0xc00) >> 10;
68} 68}
69 69
70/* Free resources associated with a struct mtrr_state */
71void __init finalize_mtrr_state(void)
72{
73 kfree(mtrr_state.var_ranges);
74 mtrr_state.var_ranges = NULL;
75}
76
77/* Some BIOS's are fucked and don't set all MTRRs the same! */ 70/* Some BIOS's are fucked and don't set all MTRRs the same! */
78void __init mtrr_state_warn(void) 71void __init mtrr_state_warn(void)
79{ 72{
@@ -334,6 +327,9 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
334*/ 327*/
335{ 328{
336 unsigned long flags; 329 unsigned long flags;
330 struct mtrr_var_range *vr;
331
332 vr = &mtrr_state.var_ranges[reg];
337 333
338 local_irq_save(flags); 334 local_irq_save(flags);
339 prepare_set(); 335 prepare_set();
@@ -342,11 +338,15 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
342 /* The invalid bit is kept in the mask, so we simply clear the 338 /* The invalid bit is kept in the mask, so we simply clear the
343 relevant mask register to disable a range. */ 339 relevant mask register to disable a range. */
344 mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0); 340 mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
341 memset(vr, 0, sizeof(struct mtrr_var_range));
345 } else { 342 } else {
346 mtrr_wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type, 343 vr->base_lo = base << PAGE_SHIFT | type;
347 (base & size_and_mask) >> (32 - PAGE_SHIFT)); 344 vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
348 mtrr_wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800, 345 vr->mask_lo = -size << PAGE_SHIFT | 0x800;
349 (-size & size_and_mask) >> (32 - PAGE_SHIFT)); 346 vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
347
348 mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi);
349 mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi);
350 } 350 }
351 351
352 post_set(); 352 post_set();
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index d66b09e0c820..764cac64e211 100644
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -332,6 +332,8 @@ int mtrr_add_page(unsigned long base, unsigned long size,
332 332
333 error = -EINVAL; 333 error = -EINVAL;
334 334
335 /* No CPU hotplug when we change MTRR entries */
336 lock_cpu_hotplug();
335 /* Search for existing MTRR */ 337 /* Search for existing MTRR */
336 down(&main_lock); 338 down(&main_lock);
337 for (i = 0; i < num_var_ranges; ++i) { 339 for (i = 0; i < num_var_ranges; ++i) {
@@ -372,6 +374,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
372 error = i; 374 error = i;
373 out: 375 out:
374 up(&main_lock); 376 up(&main_lock);
377 unlock_cpu_hotplug();
375 return error; 378 return error;
376} 379}
377 380
@@ -461,6 +464,8 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
461 return -ENXIO; 464 return -ENXIO;
462 465
463 max = num_var_ranges; 466 max = num_var_ranges;
467 /* No CPU hotplug when we change MTRR entries */
468 lock_cpu_hotplug();
464 down(&main_lock); 469 down(&main_lock);
465 if (reg < 0) { 470 if (reg < 0) {
466 /* Search for existing MTRR */ 471 /* Search for existing MTRR */
@@ -501,6 +506,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
501 error = reg; 506 error = reg;
502 out: 507 out:
503 up(&main_lock); 508 up(&main_lock);
509 unlock_cpu_hotplug();
504 return error; 510 return error;
505} 511}
506/** 512/**
@@ -544,21 +550,9 @@ static void __init init_ifs(void)
544 centaur_init_mtrr(); 550 centaur_init_mtrr();
545} 551}
546 552
547static void __init init_other_cpus(void) 553/* The suspend/resume methods are only for CPU without MTRR. CPU using generic
548{ 554 * MTRR driver doesn't require this
549 if (use_intel()) 555 */
550 get_mtrr_state();
551
552 /* bring up the other processors */
553 set_mtrr(~0U,0,0,0);
554
555 if (use_intel()) {
556 finalize_mtrr_state();
557 mtrr_state_warn();
558 }
559}
560
561
562struct mtrr_value { 556struct mtrr_value {
563 mtrr_type ltype; 557 mtrr_type ltype;
564 unsigned long lbase; 558 unsigned long lbase;
@@ -611,13 +605,13 @@ static struct sysdev_driver mtrr_sysdev_driver = {
611 605
612 606
613/** 607/**
614 * mtrr_init - initialize mtrrs on the boot CPU 608 * mtrr_bp_init - initialize mtrrs on the boot CPU
615 * 609 *
616 * This needs to be called early; before any of the other CPUs are 610 * This needs to be called early; before any of the other CPUs are
617 * initialized (i.e. before smp_init()). 611 * initialized (i.e. before smp_init()).
618 * 612 *
619 */ 613 */
620static int __init mtrr_init(void) 614void __init mtrr_bp_init(void)
621{ 615{
622 init_ifs(); 616 init_ifs();
623 617
@@ -674,12 +668,48 @@ static int __init mtrr_init(void)
674 if (mtrr_if) { 668 if (mtrr_if) {
675 set_num_var_ranges(); 669 set_num_var_ranges();
676 init_table(); 670 init_table();
677 init_other_cpus(); 671 if (use_intel())
678 672 get_mtrr_state();
679 return sysdev_driver_register(&cpu_sysdev_class,
680 &mtrr_sysdev_driver);
681 } 673 }
682 return -ENXIO;
683} 674}
684 675
685subsys_initcall(mtrr_init); 676void mtrr_ap_init(void)
677{
678 unsigned long flags;
679
680 if (!mtrr_if || !use_intel())
681 return;
682 /*
683 * Ideally we should hold main_lock here to avoid mtrr entries changed,
684 * but this routine will be called in cpu boot time, holding the lock
685 * breaks it. This routine is called in two cases: 1.very earily time
686 * of software resume, when there absolutely isn't mtrr entry changes;
687 * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to
688 * prevent mtrr entry changes
689 */
690 local_irq_save(flags);
691
692 mtrr_if->set_all();
693
694 local_irq_restore(flags);
695}
696
697static int __init mtrr_init_finialize(void)
698{
699 if (!mtrr_if)
700 return 0;
701 if (use_intel())
702 mtrr_state_warn();
703 else {
704 /* The CPUs haven't MTRR and seemes not support SMP. They have
705 * specific drivers, we use a tricky method to support
706 * suspend/resume for them.
707 * TBD: is there any system with such CPU which supports
708 * suspend/resume? if no, we should remove the code.
709 */
710 sysdev_driver_register(&cpu_sysdev_class,
711 &mtrr_sysdev_driver);
712 }
713 return 0;
714}
715subsys_initcall(mtrr_init_finialize);
diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h
index de1351245599..99c9f2682041 100644
--- a/arch/i386/kernel/cpu/mtrr/mtrr.h
+++ b/arch/i386/kernel/cpu/mtrr/mtrr.h
@@ -91,7 +91,6 @@ extern struct mtrr_ops * mtrr_if;
91 91
92extern unsigned int num_var_ranges; 92extern unsigned int num_var_ranges;
93 93
94void finalize_mtrr_state(void);
95void mtrr_state_warn(void); 94void mtrr_state_warn(void);
96char *mtrr_attrib_to_str(int x); 95char *mtrr_attrib_to_str(int x);
97void mtrr_wrmsr(unsigned, unsigned, unsigned); 96void mtrr_wrmsr(unsigned, unsigned, unsigned);
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index d66bf489a2e9..8ac8e9fd5614 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -68,21 +68,21 @@ EXPORT_SYMBOL(smp_num_siblings);
68#endif 68#endif
69 69
70/* Package ID of each logical CPU */ 70/* Package ID of each logical CPU */
71int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; 71int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
72EXPORT_SYMBOL(phys_proc_id); 72EXPORT_SYMBOL(phys_proc_id);
73 73
74/* Core ID of each logical CPU */ 74/* Core ID of each logical CPU */
75int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID}; 75int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
76EXPORT_SYMBOL(cpu_core_id); 76EXPORT_SYMBOL(cpu_core_id);
77 77
78cpumask_t cpu_sibling_map[NR_CPUS]; 78cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
79EXPORT_SYMBOL(cpu_sibling_map); 79EXPORT_SYMBOL(cpu_sibling_map);
80 80
81cpumask_t cpu_core_map[NR_CPUS]; 81cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
82EXPORT_SYMBOL(cpu_core_map); 82EXPORT_SYMBOL(cpu_core_map);
83 83
84/* bitmap of online cpus */ 84/* bitmap of online cpus */
85cpumask_t cpu_online_map; 85cpumask_t cpu_online_map __read_mostly;
86EXPORT_SYMBOL(cpu_online_map); 86EXPORT_SYMBOL(cpu_online_map);
87 87
88cpumask_t cpu_callin_map; 88cpumask_t cpu_callin_map;
@@ -100,7 +100,7 @@ static int __devinitdata tsc_sync_disabled;
100struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 100struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
101EXPORT_SYMBOL(cpu_data); 101EXPORT_SYMBOL(cpu_data);
102 102
103u8 x86_cpu_to_apicid[NR_CPUS] = 103u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
104 { [0 ... NR_CPUS-1] = 0xff }; 104 { [0 ... NR_CPUS-1] = 0xff };
105EXPORT_SYMBOL(x86_cpu_to_apicid); 105EXPORT_SYMBOL(x86_cpu_to_apicid);
106 106
@@ -550,10 +550,10 @@ extern struct {
550#ifdef CONFIG_NUMA 550#ifdef CONFIG_NUMA
551 551
552/* which logical CPUs are on which nodes */ 552/* which logical CPUs are on which nodes */
553cpumask_t node_2_cpu_mask[MAX_NUMNODES] = 553cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly =
554 { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; 554 { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
555/* which node each logical CPU is on */ 555/* which node each logical CPU is on */
556int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 }; 556int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
557EXPORT_SYMBOL(cpu_2_node); 557EXPORT_SYMBOL(cpu_2_node);
558 558
559/* set up a mapping between cpu and node. */ 559/* set up a mapping between cpu and node. */
@@ -581,7 +581,7 @@ static inline void unmap_cpu_to_node(int cpu)
581 581
582#endif /* CONFIG_NUMA */ 582#endif /* CONFIG_NUMA */
583 583
584u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; 584u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
585 585
586static void map_cpu_to_logical_apicid(void) 586static void map_cpu_to_logical_apicid(void)
587{ 587{
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 2854c357377f..0ee9dee8af06 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -91,7 +91,7 @@ EXPORT_SYMBOL(rtc_lock);
91DEFINE_SPINLOCK(i8253_lock); 91DEFINE_SPINLOCK(i8253_lock);
92EXPORT_SYMBOL(i8253_lock); 92EXPORT_SYMBOL(i8253_lock);
93 93
94struct timer_opts *cur_timer = &timer_none; 94struct timer_opts *cur_timer __read_mostly = &timer_none;
95 95
96/* 96/*
97 * This is a special lock that is owned by the CPU and holds the index 97 * This is a special lock that is owned by the CPU and holds the index
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
index d766e0963ac1..ef8dac5dd33b 100644
--- a/arch/i386/kernel/timers/timer_hpet.c
+++ b/arch/i386/kernel/timers/timer_hpet.c
@@ -18,7 +18,7 @@
18#include "mach_timer.h" 18#include "mach_timer.h"
19#include <asm/hpet.h> 19#include <asm/hpet.h>
20 20
21static unsigned long hpet_usec_quotient; /* convert hpet clks to usec */ 21static unsigned long __read_mostly hpet_usec_quotient; /* convert hpet clks to usec */
22static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */ 22static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */
23static unsigned long hpet_last; /* hpet counter value at last tick*/ 23static unsigned long hpet_last; /* hpet counter value at last tick*/
24static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ 24static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
@@ -180,7 +180,7 @@ static int __init init_hpet(char* override)
180/************************************************************/ 180/************************************************************/
181 181
182/* tsc timer_opts struct */ 182/* tsc timer_opts struct */
183static struct timer_opts timer_hpet = { 183static struct timer_opts timer_hpet __read_mostly = {
184 .name = "hpet", 184 .name = "hpet",
185 .mark_offset = mark_offset_hpet, 185 .mark_offset = mark_offset_hpet,
186 .get_offset = get_offset_hpet, 186 .get_offset = get_offset_hpet,
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 7e01a528a83a..761972f8cb6c 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -57,6 +57,9 @@ SECTIONS
57 *(.data.cacheline_aligned) 57 *(.data.cacheline_aligned)
58 } 58 }
59 59
60 /* rarely changed data like cpu maps */
61 . = ALIGN(32);
62 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
60 _edata = .; /* End of data section */ 63 _edata = .; /* End of data section */
61 64
62 . = ALIGN(THREAD_SIZE); /* init_task */ 65 . = ALIGN(THREAD_SIZE); /* init_task */
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index 6b25afc933b6..f379b8d67558 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -228,7 +228,8 @@ EXPORT_SYMBOL(ioremap_nocache);
228void iounmap(volatile void __iomem *addr) 228void iounmap(volatile void __iomem *addr)
229{ 229{
230 struct vm_struct *p; 230 struct vm_struct *p;
231 if ((void __force *) addr <= high_memory) 231
232 if ((void __force *)addr <= high_memory)
232 return; 233 return;
233 234
234 /* 235 /*
@@ -241,9 +242,10 @@ void iounmap(volatile void __iomem *addr)
241 return; 242 return;
242 243
243 write_lock(&vmlist_lock); 244 write_lock(&vmlist_lock);
244 p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); 245 p = __remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
245 if (!p) { 246 if (!p) {
246 printk(KERN_WARNING "iounmap: bad address %p\n", addr); 247 printk(KERN_WARNING "iounmap: bad address %p\n", addr);
248 dump_stack();
247 goto out_unlock; 249 goto out_unlock;
248 } 250 }
249 251
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index 0e6b45b61251..c547c1af6fa1 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -137,6 +137,7 @@ void __restore_processor_state(struct saved_context *ctxt)
137 137
138 fix_processor_context(); 138 fix_processor_context();
139 do_fpu_end(); 139 do_fpu_end();
140 mtrr_ap_init();
140} 141}
141 142
142void restore_processor_state(void) 143void restore_processor_state(void)
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c
index b014e2c1e524..a146b24a556b 100644
--- a/arch/m32r/kernel/setup_m32700ut.c
+++ b/arch/m32r/kernel/setup_m32700ut.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * Setup routines for Renesas M32700UT Board 4 * Setup routines for Renesas M32700UT Board
5 * 5 *
6 * Copyright (c) 2002 Hiroyuki Kondo, Hirokazu Takata, 6 * Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto, Takeo Takahashi 7 * Hitoshi Yamamoto, Takeo Takahashi
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General 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 this 10 * Public License. See the file "COPYING" in the main directory of this
@@ -435,7 +435,7 @@ void __init init_IRQ(void)
435 icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; 435 icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
436 enable_m32700ut_irq(M32R_IRQ_INT2); 436 enable_m32700ut_irq(M32R_IRQ_INT2);
437 437
438//#if defined(CONFIG_VIDEO_M32R_AR) 438#if defined(CONFIG_VIDEO_M32R_AR)
439 /* 439 /*
440 * INT3# is used for AR 440 * INT3# is used for AR
441 */ 441 */
@@ -445,9 +445,11 @@ void __init init_IRQ(void)
445 irq_desc[M32R_IRQ_INT3].depth = 1; 445 irq_desc[M32R_IRQ_INT3].depth = 1;
446 icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; 446 icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
447 disable_m32700ut_irq(M32R_IRQ_INT3); 447 disable_m32700ut_irq(M32R_IRQ_INT3);
448//#endif /* CONFIG_VIDEO_M32R_AR */ 448#endif /* CONFIG_VIDEO_M32R_AR */
449} 449}
450 450
451#if defined(CONFIG_SMC91X)
452
451#define LAN_IOSTART 0x300 453#define LAN_IOSTART 0x300
452#define LAN_IOEND 0x320 454#define LAN_IOEND 0x320
453static struct resource smc91x_resources[] = { 455static struct resource smc91x_resources[] = {
@@ -469,10 +471,55 @@ static struct platform_device smc91x_device = {
469 .num_resources = ARRAY_SIZE(smc91x_resources), 471 .num_resources = ARRAY_SIZE(smc91x_resources),
470 .resource = smc91x_resources, 472 .resource = smc91x_resources,
471}; 473};
474#endif
475
476#if defined(CONFIG_FB_S1D13XXX)
477
478#include <video/s1d13xxxfb.h>
479#include <asm/s1d13806.h>
480
481static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
482 .initregs = s1d13xxxfb_initregs,
483 .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
484 .platform_init_video = NULL,
485#ifdef CONFIG_PM
486 .platform_suspend_video = NULL,
487 .platform_resume_video = NULL,
488#endif
489};
490
491static struct resource s1d13xxxfb_resources[] = {
492 [0] = {
493 .start = 0x10600000UL,
494 .end = 0x1073FFFFUL,
495 .flags = IORESOURCE_MEM,
496 },
497 [1] = {
498 .start = 0x10400000UL,
499 .end = 0x104001FFUL,
500 .flags = IORESOURCE_MEM,
501 }
502};
503
504static struct platform_device s1d13xxxfb_device = {
505 .name = S1D_DEVICENAME,
506 .id = 0,
507 .dev = {
508 .platform_data = &s1d13xxxfb_data,
509 },
510 .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
511 .resource = s1d13xxxfb_resources,
512};
513#endif
472 514
473static int __init platform_init(void) 515static int __init platform_init(void)
474{ 516{
517#if defined(CONFIG_SMC91X)
475 platform_device_register(&smc91x_device); 518 platform_device_register(&smc91x_device);
519#endif
520#if defined(CONFIG_FB_S1D13XXX)
521 platform_device_register(&s1d13xxxfb_device);
522#endif
476 return 0; 523 return 0;
477} 524}
478arch_initcall(platform_init); 525arch_initcall(platform_init);
diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c
index aaf8e569b930..4e709809efc5 100644
--- a/arch/m32r/kernel/setup_mappi.c
+++ b/arch/m32r/kernel/setup_mappi.c
@@ -3,14 +3,15 @@
3 * 3 *
4 * Setup routines for Renesas MAPPI Board 4 * Setup routines for Renesas MAPPI Board
5 * 5 *
6 * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, 6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto 7 * Hitoshi Yamamoto
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/device.h>
14 15
15#include <asm/system.h> 16#include <asm/system.h>
16#include <asm/m32r.h> 17#include <asm/m32r.h>
@@ -158,3 +159,49 @@ void __init init_IRQ(void)
158 disable_mappi_irq(M32R_IRQ_INT2); 159 disable_mappi_irq(M32R_IRQ_INT2);
159#endif /* CONFIG_M32RPCC */ 160#endif /* CONFIG_M32RPCC */
160} 161}
162
163#if defined(CONFIG_FB_S1D13XXX)
164
165#include <video/s1d13xxxfb.h>
166#include <asm/s1d13806.h>
167
168static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
169 .initregs = s1d13xxxfb_initregs,
170 .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
171 .platform_init_video = NULL,
172#ifdef CONFIG_PM
173 .platform_suspend_video = NULL,
174 .platform_resume_video = NULL,
175#endif
176};
177
178static struct resource s1d13xxxfb_resources[] = {
179 [0] = {
180 .start = 0x10200000UL,
181 .end = 0x1033FFFFUL,
182 .flags = IORESOURCE_MEM,
183 },
184 [1] = {
185 .start = 0x10000000UL,
186 .end = 0x100001FFUL,
187 .flags = IORESOURCE_MEM,
188 }
189};
190
191static struct platform_device s1d13xxxfb_device = {
192 .name = S1D_DEVICENAME,
193 .id = 0,
194 .dev = {
195 .platform_data = &s1d13xxxfb_data,
196 },
197 .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
198 .resource = s1d13xxxfb_resources,
199};
200
201static int __init platform_init(void)
202{
203 platform_device_register(&s1d13xxxfb_device);
204 return 0;
205}
206arch_initcall(platform_init);
207#endif
diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c
index 38d5e9a41427..a1d801598aa4 100644
--- a/arch/m32r/kernel/setup_mappi2.c
+++ b/arch/m32r/kernel/setup_mappi2.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * Setup routines for Renesas MAPPI-II(M3A-ZA36) Board 4 * Setup routines for Renesas MAPPI-II(M3A-ZA36) Board
5 * 5 *
6 * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, 6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto, Mamoru Sakugawa 7 * Hitoshi Yamamoto, Mamoru Sakugawa
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c
index 3d60a85aaec5..a76412e883e8 100644
--- a/arch/m32r/kernel/setup_mappi3.c
+++ b/arch/m32r/kernel/setup_mappi3.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * Setup routines for Renesas MAPPI-III(M3A-2170) Board 4 * Setup routines for Renesas MAPPI-III(M3A-2170) Board
5 * 5 *
6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, 6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto, Mamoru Sakugawa 7 * Hitoshi Yamamoto, Mamoru Sakugawa
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
@@ -178,6 +178,8 @@ void __init init_IRQ(void)
178#endif /* CONFIG_M32R_CFC */ 178#endif /* CONFIG_M32R_CFC */
179} 179}
180 180
181#if defined(CONFIG_SMC91X)
182
181#define LAN_IOSTART 0x300 183#define LAN_IOSTART 0x300
182#define LAN_IOEND 0x320 184#define LAN_IOEND 0x320
183static struct resource smc91x_resources[] = { 185static struct resource smc91x_resources[] = {
@@ -200,9 +202,55 @@ static struct platform_device smc91x_device = {
200 .resource = smc91x_resources, 202 .resource = smc91x_resources,
201}; 203};
202 204
205#endif
206
207#if defined(CONFIG_FB_S1D13XXX)
208
209#include <video/s1d13xxxfb.h>
210#include <asm/s1d13806.h>
211
212static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
213 .initregs = s1d13xxxfb_initregs,
214 .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
215 .platform_init_video = NULL,
216#ifdef CONFIG_PM
217 .platform_suspend_video = NULL,
218 .platform_resume_video = NULL,
219#endif
220};
221
222static struct resource s1d13xxxfb_resources[] = {
223 [0] = {
224 .start = 0x1d600000UL,
225 .end = 0x1d73FFFFUL,
226 .flags = IORESOURCE_MEM,
227 },
228 [1] = {
229 .start = 0x1d400000UL,
230 .end = 0x1d4001FFUL,
231 .flags = IORESOURCE_MEM,
232 }
233};
234
235static struct platform_device s1d13xxxfb_device = {
236 .name = S1D_DEVICENAME,
237 .id = 0,
238 .dev = {
239 .platform_data = &s1d13xxxfb_data,
240 },
241 .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
242 .resource = s1d13xxxfb_resources,
243};
244#endif
245
203static int __init platform_init(void) 246static int __init platform_init(void)
204{ 247{
248#if defined(CONFIG_SMC91X)
205 platform_device_register(&smc91x_device); 249 platform_device_register(&smc91x_device);
250#endif
251#if defined(CONFIG_FB_S1D13XXX)
252 platform_device_register(&s1d13xxxfb_device);
253#endif
206 return 0; 254 return 0;
207} 255}
208arch_initcall(platform_init); 256arch_initcall(platform_init);
diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c
index d656640badc9..45add5b76f19 100644
--- a/arch/m32r/kernel/setup_oaks32r.c
+++ b/arch/m32r/kernel/setup_oaks32r.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * Setup routines for OAKS32R Board 4 * Setup routines for OAKS32R Board
5 * 5 *
6 * Copyright (c) 2002-2004 Hiroyuki Kondo, Hirokazu Takata, 6 * Copyright (c) 2002-2005 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto, Mamoru Sakugawa 7 * Hitoshi Yamamoto, Mamoru Sakugawa
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
@@ -139,5 +139,4 @@ void __init init_IRQ(void)
139 icu_data[M32R_IRQ_SIO1_S].icucr = 0; 139 icu_data[M32R_IRQ_SIO1_S].icucr = 0;
140 disable_oaks32r_irq(M32R_IRQ_SIO1_S); 140 disable_oaks32r_irq(M32R_IRQ_SIO1_S);
141#endif /* CONFIG_SERIAL_M32R_SIO */ 141#endif /* CONFIG_SERIAL_M32R_SIO */
142
143} 142}
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c
index 86f4cf2a86c3..f0301f58bcce 100644
--- a/arch/m32r/kernel/setup_opsput.c
+++ b/arch/m32r/kernel/setup_opsput.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Setup routines for Renesas OPSPUT Board 4 * Setup routines for Renesas OPSPUT Board
5 * 5 *
6 * Copyright (c) 2002-2004 6 * Copyright (c) 2002-2005
7 * Hiroyuki Kondo, Hirokazu Takata, 7 * Hiroyuki Kondo, Hirokazu Takata,
8 * Hitoshi Yamamoto, Takeo Takahashi, Mamoru Sakugawa 8 * Hitoshi Yamamoto, Takeo Takahashi, Mamoru Sakugawa
9 * 9 *
@@ -439,7 +439,7 @@ void __init init_IRQ(void)
439 icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; 439 icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
440 enable_opsput_irq(M32R_IRQ_INT2); 440 enable_opsput_irq(M32R_IRQ_INT2);
441 441
442//#if defined(CONFIG_VIDEO_M32R_AR) 442#if defined(CONFIG_VIDEO_M32R_AR)
443 /* 443 /*
444 * INT3# is used for AR 444 * INT3# is used for AR
445 */ 445 */
@@ -449,9 +449,11 @@ void __init init_IRQ(void)
449 irq_desc[M32R_IRQ_INT3].depth = 1; 449 irq_desc[M32R_IRQ_INT3].depth = 1;
450 icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; 450 icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
451 disable_opsput_irq(M32R_IRQ_INT3); 451 disable_opsput_irq(M32R_IRQ_INT3);
452//#endif /* CONFIG_VIDEO_M32R_AR */ 452#endif /* CONFIG_VIDEO_M32R_AR */
453} 453}
454 454
455#if defined(CONFIG_SMC91X)
456
455#define LAN_IOSTART 0x300 457#define LAN_IOSTART 0x300
456#define LAN_IOEND 0x320 458#define LAN_IOEND 0x320
457static struct resource smc91x_resources[] = { 459static struct resource smc91x_resources[] = {
@@ -473,10 +475,55 @@ static struct platform_device smc91x_device = {
473 .num_resources = ARRAY_SIZE(smc91x_resources), 475 .num_resources = ARRAY_SIZE(smc91x_resources),
474 .resource = smc91x_resources, 476 .resource = smc91x_resources,
475}; 477};
478#endif
479
480#if defined(CONFIG_FB_S1D13XXX)
481
482#include <video/s1d13xxxfb.h>
483#include <asm/s1d13806.h>
484
485static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
486 .initregs = s1d13xxxfb_initregs,
487 .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
488 .platform_init_video = NULL,
489#ifdef CONFIG_PM
490 .platform_suspend_video = NULL,
491 .platform_resume_video = NULL,
492#endif
493};
494
495static struct resource s1d13xxxfb_resources[] = {
496 [0] = {
497 .start = 0x10600000UL,
498 .end = 0x1073FFFFUL,
499 .flags = IORESOURCE_MEM,
500 },
501 [1] = {
502 .start = 0x10400000UL,
503 .end = 0x104001FFUL,
504 .flags = IORESOURCE_MEM,
505 }
506};
507
508static struct platform_device s1d13xxxfb_device = {
509 .name = S1D_DEVICENAME,
510 .id = 0,
511 .dev = {
512 .platform_data = &s1d13xxxfb_data,
513 },
514 .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
515 .resource = s1d13xxxfb_resources,
516};
517#endif
476 518
477static int __init platform_init(void) 519static int __init platform_init(void)
478{ 520{
521#if defined(CONFIG_SMC91X)
479 platform_device_register(&smc91x_device); 522 platform_device_register(&smc91x_device);
523#endif
524#if defined(CONFIG_FB_S1D13XXX)
525 platform_device_register(&s1d13xxxfb_device);
526#endif
480 return 0; 527 return 0;
481} 528}
482arch_initcall(platform_init); 529arch_initcall(platform_init);
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index 5fdd4f607a40..c0605244edda 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct device_node *np)
452 return offset; 452 return offset;
453} 453}
454 454
455static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) 455static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
456{ 456{
457 /* Ok, this could be made a bit smarter, but let's be robust for now. We 457 /* Ok, this could be made a bit smarter, but let's be robust for now. We
458 * always force a speed change to high speed before sleep, to make sure 458 * always force a speed change to high speed before sleep, to make sure
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
index 1d162c7c59df..8d4c46f6f0b6 100644
--- a/arch/ppc64/kernel/cputable.c
+++ b/arch/ppc64/kernel/cputable.c
@@ -49,160 +49,219 @@ extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
49#endif 49#endif
50 50
51struct cpu_spec cpu_specs[] = { 51struct cpu_spec cpu_specs[] = {
52 { /* Power3 */ 52 { /* Power3 */
53 0xffff0000, 0x00400000, "POWER3 (630)", 53 .pvr_mask = 0xffff0000,
54 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 54 .pvr_value = 0x00400000,
55 CPU_FTR_IABR | CPU_FTR_PMC8, 55 .cpu_name = "POWER3 (630)",
56 COMMON_USER_PPC64, 56 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
57 128, 128, 57 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
58 __setup_cpu_power3, 58 CPU_FTR_PMC8,
59 COMMON_PPC64_FW 59 .cpu_user_features = COMMON_USER_PPC64,
60 }, 60 .icache_bsize = 128,
61 { /* Power3+ */ 61 .dcache_bsize = 128,
62 0xffff0000, 0x00410000, "POWER3 (630+)", 62 .cpu_setup = __setup_cpu_power3,
63 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 63 .firmware_features = COMMON_PPC64_FW,
64 CPU_FTR_IABR | CPU_FTR_PMC8, 64 },
65 COMMON_USER_PPC64, 65 { /* Power3+ */
66 128, 128, 66 .pvr_mask = 0xffff0000,
67 __setup_cpu_power3, 67 .pvr_value = 0x00410000,
68 COMMON_PPC64_FW 68 .cpu_name = "POWER3 (630+)",
69 }, 69 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
70 { /* Northstar */ 70 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
71 0xffff0000, 0x00330000, "RS64-II (northstar)", 71 CPU_FTR_PMC8,
72 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 72 .cpu_user_features = COMMON_USER_PPC64,
73 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 73 .icache_bsize = 128,
74 COMMON_USER_PPC64, 74 .dcache_bsize = 128,
75 128, 128, 75 .cpu_setup = __setup_cpu_power3,
76 __setup_cpu_power3, 76 .firmware_features = COMMON_PPC64_FW,
77 COMMON_PPC64_FW 77 },
78 }, 78 { /* Northstar */
79 { /* Pulsar */ 79 .pvr_mask = 0xffff0000,
80 0xffff0000, 0x00340000, "RS64-III (pulsar)", 80 .pvr_value = 0x00330000,
81 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 81 .cpu_name = "RS64-II (northstar)",
82 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 82 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
83 COMMON_USER_PPC64, 83 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
84 128, 128, 84 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
85 __setup_cpu_power3, 85 .cpu_user_features = COMMON_USER_PPC64,
86 COMMON_PPC64_FW 86 .icache_bsize = 128,
87 }, 87 .dcache_bsize = 128,
88 { /* I-star */ 88 .cpu_setup = __setup_cpu_power3,
89 0xffff0000, 0x00360000, "RS64-III (icestar)", 89 .firmware_features = COMMON_PPC64_FW,
90 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 90 },
91 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 91 { /* Pulsar */
92 COMMON_USER_PPC64, 92 .pvr_mask = 0xffff0000,
93 128, 128, 93 .pvr_value = 0x00340000,
94 __setup_cpu_power3, 94 .cpu_name = "RS64-III (pulsar)",
95 COMMON_PPC64_FW 95 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
96 }, 96 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
97 { /* S-star */ 97 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
98 0xffff0000, 0x00370000, "RS64-IV (sstar)", 98 .cpu_user_features = COMMON_USER_PPC64,
99 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 99 .icache_bsize = 128,
100 CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 100 .dcache_bsize = 128,
101 COMMON_USER_PPC64, 101 .cpu_setup = __setup_cpu_power3,
102 128, 128, 102 .firmware_features = COMMON_PPC64_FW,
103 __setup_cpu_power3, 103 },
104 COMMON_PPC64_FW 104 { /* I-star */
105 }, 105 .pvr_mask = 0xffff0000,
106 { /* Power4 */ 106 .pvr_value = 0x00360000,
107 0xffff0000, 0x00350000, "POWER4 (gp)", 107 .cpu_name = "RS64-III (icestar)",
108 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 108 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
109 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 109 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
110 COMMON_USER_PPC64, 110 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
111 128, 128, 111 .cpu_user_features = COMMON_USER_PPC64,
112 __setup_cpu_power4, 112 .icache_bsize = 128,
113 COMMON_PPC64_FW 113 .dcache_bsize = 128,
114 }, 114 .cpu_setup = __setup_cpu_power3,
115 { /* Power4+ */ 115 .firmware_features = COMMON_PPC64_FW,
116 0xffff0000, 0x00380000, "POWER4+ (gq)", 116 },
117 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 117 { /* S-star */
118 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 118 .pvr_mask = 0xffff0000,
119 COMMON_USER_PPC64, 119 .pvr_value = 0x00370000,
120 128, 128, 120 .cpu_name = "RS64-IV (sstar)",
121 __setup_cpu_power4, 121 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
122 COMMON_PPC64_FW 122 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
123 }, 123 CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
124 { /* PPC970 */ 124 .cpu_user_features = COMMON_USER_PPC64,
125 0xffff0000, 0x00390000, "PPC970", 125 .icache_bsize = 128,
126 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 126 .dcache_bsize = 128,
127 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | 127 .cpu_setup = __setup_cpu_power3,
128 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 128 .firmware_features = COMMON_PPC64_FW,
129 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 129 },
130 128, 128, 130 { /* Power4 */
131 __setup_cpu_ppc970, 131 .pvr_mask = 0xffff0000,
132 COMMON_PPC64_FW 132 .pvr_value = 0x00350000,
133 }, 133 .cpu_name = "POWER4 (gp)",
134 { /* PPC970FX */ 134 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
135 0xffff0000, 0x003c0000, "PPC970FX", 135 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
136 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 136 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
137 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | 137 .cpu_user_features = COMMON_USER_PPC64,
138 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA, 138 .icache_bsize = 128,
139 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 139 .dcache_bsize = 128,
140 128, 128, 140 .cpu_setup = __setup_cpu_power4,
141 __setup_cpu_ppc970, 141 .firmware_features = COMMON_PPC64_FW,
142 COMMON_PPC64_FW 142 },
143 }, 143 { /* Power4+ */
144 { /* Power5 */ 144 .pvr_mask = 0xffff0000,
145 0xffff0000, 0x003a0000, "POWER5 (gr)", 145 .pvr_value = 0x00380000,
146 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 146 .cpu_name = "POWER4+ (gq)",
147 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | 147 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
148 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | 148 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
149 CPU_FTR_MMCRA_SIHV, 149 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
150 COMMON_USER_PPC64, 150 .cpu_user_features = COMMON_USER_PPC64,
151 128, 128, 151 .icache_bsize = 128,
152 __setup_cpu_power4, 152 .dcache_bsize = 128,
153 COMMON_PPC64_FW 153 .cpu_setup = __setup_cpu_power4,
154 }, 154 .firmware_features = COMMON_PPC64_FW,
155 { /* Power5 */ 155 },
156 0xffff0000, 0x003b0000, "POWER5 (gs)", 156 { /* PPC970 */
157 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 157 .pvr_mask = 0xffff0000,
158 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT | 158 .pvr_value = 0x00390000,
159 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | 159 .cpu_name = "PPC970",
160 CPU_FTR_MMCRA_SIHV, 160 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
161 COMMON_USER_PPC64, 161 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
162 128, 128, 162 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
163 __setup_cpu_power4, 163 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
164 COMMON_PPC64_FW 164 .cpu_user_features = COMMON_USER_PPC64 |
165 }, 165 PPC_FEATURE_HAS_ALTIVEC_COMP,
166 { /* BE DD1.x */ 166 .icache_bsize = 128,
167 0xffff0000, 0x00700000, "Broadband Engine", 167 .dcache_bsize = 128,
168 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 168 .cpu_setup = __setup_cpu_ppc970,
169 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | 169 .firmware_features = COMMON_PPC64_FW,
170 CPU_FTR_SMT, 170 },
171 COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP, 171 { /* PPC970FX */
172 128, 128, 172 .pvr_mask = 0xffff0000,
173 __setup_cpu_be, 173 .pvr_value = 0x003c0000,
174 COMMON_PPC64_FW 174 .cpu_name = "PPC970FX",
175 }, 175 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
176 { /* default match */ 176 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
177 0x00000000, 0x00000000, "POWER4 (compatible)", 177 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
178 CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | 178 CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
179 CPU_FTR_PPCAS_ARCH_V2, 179 .cpu_user_features = COMMON_USER_PPC64 |
180 COMMON_USER_PPC64, 180 PPC_FEATURE_HAS_ALTIVEC_COMP,
181 128, 128, 181 .icache_bsize = 128,
182 __setup_cpu_power4, 182 .dcache_bsize = 128,
183 COMMON_PPC64_FW 183 .cpu_setup = __setup_cpu_ppc970,
184 } 184 .firmware_features = COMMON_PPC64_FW,
185 },
186 { /* Power5 */
187 .pvr_mask = 0xffff0000,
188 .pvr_value = 0x003a0000,
189 .cpu_name = "POWER5 (gr)",
190 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
191 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
192 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
193 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
194 CPU_FTR_MMCRA_SIHV,
195 .cpu_user_features = COMMON_USER_PPC64,
196 .icache_bsize = 128,
197 .dcache_bsize = 128,
198 .cpu_setup = __setup_cpu_power4,
199 .firmware_features = COMMON_PPC64_FW,
200 },
201 { /* Power5 */
202 .pvr_mask = 0xffff0000,
203 .pvr_value = 0x003b0000,
204 .cpu_name = "POWER5 (gs)",
205 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
206 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
207 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
208 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
209 CPU_FTR_MMCRA_SIHV,
210 .cpu_user_features = COMMON_USER_PPC64,
211 .icache_bsize = 128,
212 .dcache_bsize = 128,
213 .cpu_setup = __setup_cpu_power4,
214 .firmware_features = COMMON_PPC64_FW,
215 },
216 { /* BE DD1.x */
217 .pvr_mask = 0xffff0000,
218 .pvr_value = 0x00700000,
219 .cpu_name = "Broadband Engine",
220 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
221 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
222 CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
223 CPU_FTR_SMT,
224 .cpu_user_features = COMMON_USER_PPC64 |
225 PPC_FEATURE_HAS_ALTIVEC_COMP,
226 .icache_bsize = 128,
227 .dcache_bsize = 128,
228 .cpu_setup = __setup_cpu_be,
229 .firmware_features = COMMON_PPC64_FW,
230 },
231 { /* default match */
232 .pvr_mask = 0x00000000,
233 .pvr_value = 0x00000000,
234 .cpu_name = "POWER4 (compatible)",
235 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
236 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
237 CPU_FTR_PPCAS_ARCH_V2,
238 .cpu_user_features = COMMON_USER_PPC64,
239 .icache_bsize = 128,
240 .dcache_bsize = 128,
241 .cpu_setup = __setup_cpu_power4,
242 .firmware_features = COMMON_PPC64_FW,
243 }
185}; 244};
186 245
187firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = { 246firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
188 {FW_FEATURE_PFT, "hcall-pft"}, 247 {FW_FEATURE_PFT, "hcall-pft"},
189 {FW_FEATURE_TCE, "hcall-tce"}, 248 {FW_FEATURE_TCE, "hcall-tce"},
190 {FW_FEATURE_SPRG0, "hcall-sprg0"}, 249 {FW_FEATURE_SPRG0, "hcall-sprg0"},
191 {FW_FEATURE_DABR, "hcall-dabr"}, 250 {FW_FEATURE_DABR, "hcall-dabr"},
192 {FW_FEATURE_COPY, "hcall-copy"}, 251 {FW_FEATURE_COPY, "hcall-copy"},
193 {FW_FEATURE_ASR, "hcall-asr"}, 252 {FW_FEATURE_ASR, "hcall-asr"},
194 {FW_FEATURE_DEBUG, "hcall-debug"}, 253 {FW_FEATURE_DEBUG, "hcall-debug"},
195 {FW_FEATURE_PERF, "hcall-perf"}, 254 {FW_FEATURE_PERF, "hcall-perf"},
196 {FW_FEATURE_DUMP, "hcall-dump"}, 255 {FW_FEATURE_DUMP, "hcall-dump"},
197 {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, 256 {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
198 {FW_FEATURE_MIGRATE, "hcall-migrate"}, 257 {FW_FEATURE_MIGRATE, "hcall-migrate"},
199 {FW_FEATURE_PERFMON, "hcall-perfmon"}, 258 {FW_FEATURE_PERFMON, "hcall-perfmon"},
200 {FW_FEATURE_CRQ, "hcall-crq"}, 259 {FW_FEATURE_CRQ, "hcall-crq"},
201 {FW_FEATURE_VIO, "hcall-vio"}, 260 {FW_FEATURE_VIO, "hcall-vio"},
202 {FW_FEATURE_RDMA, "hcall-rdma"}, 261 {FW_FEATURE_RDMA, "hcall-rdma"},
203 {FW_FEATURE_LLAN, "hcall-lLAN"}, 262 {FW_FEATURE_LLAN, "hcall-lLAN"},
204 {FW_FEATURE_BULK, "hcall-bulk"}, 263 {FW_FEATURE_BULK, "hcall-bulk"},
205 {FW_FEATURE_XDABR, "hcall-xdabr"}, 264 {FW_FEATURE_XDABR, "hcall-xdabr"},
206 {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, 265 {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
207 {FW_FEATURE_SPLPAR, "hcall-splpar"}, 266 {FW_FEATURE_SPLPAR, "hcall-splpar"},
208}; 267};
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
index 675c2708588f..93ebcac0d5a2 100644
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -308,6 +308,7 @@ exception_marker:
308label##_pSeries: \ 308label##_pSeries: \
309 HMT_MEDIUM; \ 309 HMT_MEDIUM; \
310 mtspr SPRG1,r13; /* save r13 */ \ 310 mtspr SPRG1,r13; /* save r13 */ \
311 RUNLATCH_ON(r13); \
311 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 312 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
312 313
313#define STD_EXCEPTION_ISERIES(n, label, area) \ 314#define STD_EXCEPTION_ISERIES(n, label, area) \
@@ -315,6 +316,7 @@ label##_pSeries: \
315label##_iSeries: \ 316label##_iSeries: \
316 HMT_MEDIUM; \ 317 HMT_MEDIUM; \
317 mtspr SPRG1,r13; /* save r13 */ \ 318 mtspr SPRG1,r13; /* save r13 */ \
319 RUNLATCH_ON(r13); \
318 EXCEPTION_PROLOG_ISERIES_1(area); \ 320 EXCEPTION_PROLOG_ISERIES_1(area); \
319 EXCEPTION_PROLOG_ISERIES_2; \ 321 EXCEPTION_PROLOG_ISERIES_2; \
320 b label##_common 322 b label##_common
@@ -324,6 +326,7 @@ label##_iSeries: \
324label##_iSeries: \ 326label##_iSeries: \
325 HMT_MEDIUM; \ 327 HMT_MEDIUM; \
326 mtspr SPRG1,r13; /* save r13 */ \ 328 mtspr SPRG1,r13; /* save r13 */ \
329 RUNLATCH_ON(r13); \
327 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ 330 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
328 lbz r10,PACAPROCENABLED(r13); \ 331 lbz r10,PACAPROCENABLED(r13); \
329 cmpwi 0,r10,0; \ 332 cmpwi 0,r10,0; \
@@ -393,6 +396,7 @@ __start_interrupts:
393_machine_check_pSeries: 396_machine_check_pSeries:
394 HMT_MEDIUM 397 HMT_MEDIUM
395 mtspr SPRG1,r13 /* save r13 */ 398 mtspr SPRG1,r13 /* save r13 */
399 RUNLATCH_ON(r13)
396 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) 400 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
397 401
398 . = 0x300 402 . = 0x300
@@ -419,6 +423,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
419data_access_slb_pSeries: 423data_access_slb_pSeries:
420 HMT_MEDIUM 424 HMT_MEDIUM
421 mtspr SPRG1,r13 425 mtspr SPRG1,r13
426 RUNLATCH_ON(r13)
422 mfspr r13,SPRG3 /* get paca address into r13 */ 427 mfspr r13,SPRG3 /* get paca address into r13 */
423 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ 428 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
424 std r10,PACA_EXSLB+EX_R10(r13) 429 std r10,PACA_EXSLB+EX_R10(r13)
@@ -439,6 +444,7 @@ data_access_slb_pSeries:
439instruction_access_slb_pSeries: 444instruction_access_slb_pSeries:
440 HMT_MEDIUM 445 HMT_MEDIUM
441 mtspr SPRG1,r13 446 mtspr SPRG1,r13
447 RUNLATCH_ON(r13)
442 mfspr r13,SPRG3 /* get paca address into r13 */ 448 mfspr r13,SPRG3 /* get paca address into r13 */
443 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */ 449 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
444 std r10,PACA_EXSLB+EX_R10(r13) 450 std r10,PACA_EXSLB+EX_R10(r13)
@@ -464,6 +470,7 @@ instruction_access_slb_pSeries:
464 .globl system_call_pSeries 470 .globl system_call_pSeries
465system_call_pSeries: 471system_call_pSeries:
466 HMT_MEDIUM 472 HMT_MEDIUM
473 RUNLATCH_ON(r9)
467 mr r9,r13 474 mr r9,r13
468 mfmsr r10 475 mfmsr r10
469 mfspr r13,SPRG3 476 mfspr r13,SPRG3
@@ -707,11 +714,13 @@ fwnmi_data_area:
707system_reset_fwnmi: 714system_reset_fwnmi:
708 HMT_MEDIUM 715 HMT_MEDIUM
709 mtspr SPRG1,r13 /* save r13 */ 716 mtspr SPRG1,r13 /* save r13 */
717 RUNLATCH_ON(r13)
710 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) 718 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
711 .globl machine_check_fwnmi 719 .globl machine_check_fwnmi
712machine_check_fwnmi: 720machine_check_fwnmi:
713 HMT_MEDIUM 721 HMT_MEDIUM
714 mtspr SPRG1,r13 /* save r13 */ 722 mtspr SPRG1,r13 /* save r13 */
723 RUNLATCH_ON(r13)
715 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) 724 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
716 725
717 /* 726 /*
@@ -848,6 +857,7 @@ unrecov_fer:
848 .align 7 857 .align 7
849 .globl data_access_common 858 .globl data_access_common
850data_access_common: 859data_access_common:
860 RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
851 mfspr r10,DAR 861 mfspr r10,DAR
852 std r10,PACA_EXGEN+EX_DAR(r13) 862 std r10,PACA_EXGEN+EX_DAR(r13)
853 mfspr r10,DSISR 863 mfspr r10,DSISR
diff --git a/arch/ppc64/kernel/hvconsole.c b/arch/ppc64/kernel/hvconsole.c
index c72fb8ffe974..138e128a3886 100644
--- a/arch/ppc64/kernel/hvconsole.c
+++ b/arch/ppc64/kernel/hvconsole.c
@@ -27,7 +27,6 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <asm/hvcall.h> 28#include <asm/hvcall.h>
29#include <asm/hvconsole.h> 29#include <asm/hvconsole.h>
30#include <asm/prom.h>
31 30
32/** 31/**
33 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper 32 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
@@ -42,29 +41,14 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count)
42 unsigned long got; 41 unsigned long got;
43 42
44 if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, 43 if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got,
45 (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) { 44 (unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
46 /*
47 * Work around a HV bug where it gives us a null
48 * after every \r. -- paulus
49 */
50 if (got > 0) {
51 int i;
52 for (i = 1; i < got; ++i) {
53 if (buf[i] == 0 && buf[i-1] == '\r') {
54 --got;
55 if (i < got)
56 memmove(&buf[i], &buf[i+1],
57 got - i);
58 }
59 }
60 }
61 return got; 45 return got;
62 }
63 return 0; 46 return 0;
64} 47}
65 48
66EXPORT_SYMBOL(hvc_get_chars); 49EXPORT_SYMBOL(hvc_get_chars);
67 50
51
68/** 52/**
69 * hvc_put_chars: send characters to firmware for denoted vterm adapter 53 * hvc_put_chars: send characters to firmware for denoted vterm adapter
70 * @vtermno: The vtermno or unit_address of the adapter from which the data 54 * @vtermno: The vtermno or unit_address of the adapter from which the data
@@ -88,34 +72,3 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
88} 72}
89 73
90EXPORT_SYMBOL(hvc_put_chars); 74EXPORT_SYMBOL(hvc_put_chars);
91
92/*
93 * We hope/assume that the first vty found corresponds to the first console
94 * device.
95 */
96int hvc_find_vtys(void)
97{
98 struct device_node *vty;
99 int num_found = 0;
100
101 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
102 vty = of_find_node_by_name(vty, "vty")) {
103 uint32_t *vtermno;
104
105 /* We have statically defined space for only a certain number of
106 * console adapters. */
107 if (num_found >= MAX_NR_HVC_CONSOLES)
108 break;
109
110 vtermno = (uint32_t *)get_property(vty, "reg", NULL);
111 if (!vtermno)
112 continue;
113
114 if (device_is_compatible(vty, "hvterm1")) {
115 hvc_instantiate(*vtermno, num_found);
116 ++num_found;
117 }
118 }
119
120 return num_found;
121}
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index b3f770f6d402..077c82fc9f3a 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -834,6 +834,92 @@ static int __init iSeries_src_init(void)
834 834
835late_initcall(iSeries_src_init); 835late_initcall(iSeries_src_init);
836 836
837static inline void process_iSeries_events(void)
838{
839 asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
840}
841
842static void yield_shared_processor(void)
843{
844 unsigned long tb;
845
846 HvCall_setEnabledInterrupts(HvCall_MaskIPI |
847 HvCall_MaskLpEvent |
848 HvCall_MaskLpProd |
849 HvCall_MaskTimeout);
850
851 tb = get_tb();
852 /* Compute future tb value when yield should expire */
853 HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
854
855 /*
856 * The decrementer stops during the yield. Force a fake decrementer
857 * here and let the timer_interrupt code sort out the actual time.
858 */
859 get_paca()->lppaca.int_dword.fields.decr_int = 1;
860 process_iSeries_events();
861}
862
863static int iseries_shared_idle(void)
864{
865 while (1) {
866 while (!need_resched() && !hvlpevent_is_pending()) {
867 local_irq_disable();
868 ppc64_runlatch_off();
869
870 /* Recheck with irqs off */
871 if (!need_resched() && !hvlpevent_is_pending())
872 yield_shared_processor();
873
874 HMT_medium();
875 local_irq_enable();
876 }
877
878 ppc64_runlatch_on();
879
880 if (hvlpevent_is_pending())
881 process_iSeries_events();
882
883 schedule();
884 }
885
886 return 0;
887}
888
889static int iseries_dedicated_idle(void)
890{
891 long oldval;
892
893 while (1) {
894 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
895
896 if (!oldval) {
897 set_thread_flag(TIF_POLLING_NRFLAG);
898
899 while (!need_resched()) {
900 ppc64_runlatch_off();
901 HMT_low();
902
903 if (hvlpevent_is_pending()) {
904 HMT_medium();
905 ppc64_runlatch_on();
906 process_iSeries_events();
907 }
908 }
909
910 HMT_medium();
911 clear_thread_flag(TIF_POLLING_NRFLAG);
912 } else {
913 set_need_resched();
914 }
915
916 ppc64_runlatch_on();
917 schedule();
918 }
919
920 return 0;
921}
922
837#ifndef CONFIG_PCI 923#ifndef CONFIG_PCI
838void __init iSeries_init_IRQ(void) { } 924void __init iSeries_init_IRQ(void) { }
839#endif 925#endif
@@ -859,5 +945,13 @@ void __init iSeries_early_setup(void)
859 ppc_md.get_rtc_time = iSeries_get_rtc_time; 945 ppc_md.get_rtc_time = iSeries_get_rtc_time;
860 ppc_md.calibrate_decr = iSeries_calibrate_decr; 946 ppc_md.calibrate_decr = iSeries_calibrate_decr;
861 ppc_md.progress = iSeries_progress; 947 ppc_md.progress = iSeries_progress;
948
949 if (get_paca()->lppaca.shared_proc) {
950 ppc_md.idle_loop = iseries_shared_idle;
951 printk(KERN_INFO "Using shared processor idle loop\n");
952 } else {
953 ppc_md.idle_loop = iseries_dedicated_idle;
954 printk(KERN_INFO "Using dedicated idle loop\n");
955 }
862} 956}
863 957
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index 08952c7e6216..954395d42636 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -20,109 +20,18 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/cpu.h> 22#include <linux/cpu.h>
23#include <linux/module.h>
24#include <linux/sysctl.h> 23#include <linux/sysctl.h>
25#include <linux/smp.h>
26 24
27#include <asm/system.h> 25#include <asm/system.h>
28#include <asm/processor.h> 26#include <asm/processor.h>
29#include <asm/mmu.h>
30#include <asm/cputable.h> 27#include <asm/cputable.h>
31#include <asm/time.h> 28#include <asm/time.h>
32#include <asm/iSeries/HvCall.h>
33#include <asm/iSeries/ItLpQueue.h>
34#include <asm/plpar_wrappers.h>
35#include <asm/systemcfg.h> 29#include <asm/systemcfg.h>
30#include <asm/machdep.h>
36 31
37extern void power4_idle(void); 32extern void power4_idle(void);
38 33
39static int (*idle_loop)(void); 34int default_idle(void)
40
41#ifdef CONFIG_PPC_ISERIES
42static unsigned long maxYieldTime = 0;
43static unsigned long minYieldTime = 0xffffffffffffffffUL;
44
45static inline void process_iSeries_events(void)
46{
47 asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
48}
49
50static void yield_shared_processor(void)
51{
52 unsigned long tb;
53 unsigned long yieldTime;
54
55 HvCall_setEnabledInterrupts(HvCall_MaskIPI |
56 HvCall_MaskLpEvent |
57 HvCall_MaskLpProd |
58 HvCall_MaskTimeout);
59
60 tb = get_tb();
61 /* Compute future tb value when yield should expire */
62 HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
63
64 yieldTime = get_tb() - tb;
65 if (yieldTime > maxYieldTime)
66 maxYieldTime = yieldTime;
67
68 if (yieldTime < minYieldTime)
69 minYieldTime = yieldTime;
70
71 /*
72 * The decrementer stops during the yield. Force a fake decrementer
73 * here and let the timer_interrupt code sort out the actual time.
74 */
75 get_paca()->lppaca.int_dword.fields.decr_int = 1;
76 process_iSeries_events();
77}
78
79static int iSeries_idle(void)
80{
81 struct paca_struct *lpaca;
82 long oldval;
83
84 /* ensure iSeries run light will be out when idle */
85 ppc64_runlatch_off();
86
87 lpaca = get_paca();
88
89 while (1) {
90 if (lpaca->lppaca.shared_proc) {
91 if (hvlpevent_is_pending())
92 process_iSeries_events();
93 if (!need_resched())
94 yield_shared_processor();
95 } else {
96 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
97
98 if (!oldval) {
99 set_thread_flag(TIF_POLLING_NRFLAG);
100
101 while (!need_resched()) {
102 HMT_medium();
103 if (hvlpevent_is_pending())
104 process_iSeries_events();
105 HMT_low();
106 }
107
108 HMT_medium();
109 clear_thread_flag(TIF_POLLING_NRFLAG);
110 } else {
111 set_need_resched();
112 }
113 }
114
115 ppc64_runlatch_on();
116 schedule();
117 ppc64_runlatch_off();
118 }
119
120 return 0;
121}
122
123#else
124
125static int default_idle(void)
126{ 35{
127 long oldval; 36 long oldval;
128 unsigned int cpu = smp_processor_id(); 37 unsigned int cpu = smp_processor_id();
@@ -134,7 +43,8 @@ static int default_idle(void)
134 set_thread_flag(TIF_POLLING_NRFLAG); 43 set_thread_flag(TIF_POLLING_NRFLAG);
135 44
136 while (!need_resched() && !cpu_is_offline(cpu)) { 45 while (!need_resched() && !cpu_is_offline(cpu)) {
137 barrier(); 46 ppc64_runlatch_off();
47
138 /* 48 /*
139 * Go into low thread priority and possibly 49 * Go into low thread priority and possibly
140 * low power mode. 50 * low power mode.
@@ -149,6 +59,7 @@ static int default_idle(void)
149 set_need_resched(); 59 set_need_resched();
150 } 60 }
151 61
62 ppc64_runlatch_on();
152 schedule(); 63 schedule();
153 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 64 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
154 cpu_die(); 65 cpu_die();
@@ -157,127 +68,19 @@ static int default_idle(void)
157 return 0; 68 return 0;
158} 69}
159 70
160#ifdef CONFIG_PPC_PSERIES 71int native_idle(void)
161
162DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
163
164int dedicated_idle(void)
165{ 72{
166 long oldval;
167 struct paca_struct *lpaca = get_paca(), *ppaca;
168 unsigned long start_snooze;
169 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
170 unsigned int cpu = smp_processor_id();
171
172 ppaca = &paca[cpu ^ 1];
173
174 while (1) { 73 while (1) {
175 /* 74 ppc64_runlatch_off();
176 * Indicate to the HV that we are idle. Now would be
177 * a good time to find other work to dispatch.
178 */
179 lpaca->lppaca.idle = 1;
180
181 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
182 if (!oldval) {
183 set_thread_flag(TIF_POLLING_NRFLAG);
184 start_snooze = __get_tb() +
185 *smt_snooze_delay * tb_ticks_per_usec;
186 while (!need_resched() && !cpu_is_offline(cpu)) {
187 /*
188 * Go into low thread priority and possibly
189 * low power mode.
190 */
191 HMT_low();
192 HMT_very_low();
193
194 if (*smt_snooze_delay == 0 ||
195 __get_tb() < start_snooze)
196 continue;
197
198 HMT_medium();
199
200 if (!(ppaca->lppaca.idle)) {
201 local_irq_disable();
202
203 /*
204 * We are about to sleep the thread
205 * and so wont be polling any
206 * more.
207 */
208 clear_thread_flag(TIF_POLLING_NRFLAG);
209
210 /*
211 * SMT dynamic mode. Cede will result
212 * in this thread going dormant, if the
213 * partner thread is still doing work.
214 * Thread wakes up if partner goes idle,
215 * an interrupt is presented, or a prod
216 * occurs. Returning from the cede
217 * enables external interrupts.
218 */
219 if (!need_resched())
220 cede_processor();
221 else
222 local_irq_enable();
223 } else {
224 /*
225 * Give the HV an opportunity at the
226 * processor, since we are not doing
227 * any work.
228 */
229 poll_pending();
230 }
231 }
232
233 clear_thread_flag(TIF_POLLING_NRFLAG);
234 } else {
235 set_need_resched();
236 }
237
238 HMT_medium();
239 lpaca->lppaca.idle = 0;
240 schedule();
241 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
242 cpu_die();
243 }
244 return 0;
245}
246
247static int shared_idle(void)
248{
249 struct paca_struct *lpaca = get_paca();
250 unsigned int cpu = smp_processor_id();
251
252 while (1) {
253 /*
254 * Indicate to the HV that we are idle. Now would be
255 * a good time to find other work to dispatch.
256 */
257 lpaca->lppaca.idle = 1;
258 75
259 while (!need_resched() && !cpu_is_offline(cpu)) { 76 if (!need_resched())
260 local_irq_disable(); 77 power4_idle();
261 78
262 /* 79 if (need_resched()) {
263 * Yield the processor to the hypervisor. We return if 80 ppc64_runlatch_on();
264 * an external interrupt occurs (which are driven prior 81 schedule();
265 * to returning here) or if a prod occurs from another
266 * processor. When returning here, external interrupts
267 * are enabled.
268 *
269 * Check need_resched() again with interrupts disabled
270 * to avoid a race.
271 */
272 if (!need_resched())
273 cede_processor();
274 else
275 local_irq_enable();
276 } 82 }
277 83
278 HMT_medium();
279 lpaca->lppaca.idle = 0;
280 schedule();
281 if (cpu_is_offline(smp_processor_id()) && 84 if (cpu_is_offline(smp_processor_id()) &&
282 system_state == SYSTEM_RUNNING) 85 system_state == SYSTEM_RUNNING)
283 cpu_die(); 86 cpu_die();
@@ -286,29 +89,10 @@ static int shared_idle(void)
286 return 0; 89 return 0;
287} 90}
288 91
289#endif /* CONFIG_PPC_PSERIES */
290
291static int native_idle(void)
292{
293 while(1) {
294 /* check CPU type here */
295 if (!need_resched())
296 power4_idle();
297 if (need_resched())
298 schedule();
299
300 if (cpu_is_offline(raw_smp_processor_id()) &&
301 system_state == SYSTEM_RUNNING)
302 cpu_die();
303 }
304 return 0;
305}
306
307#endif /* CONFIG_PPC_ISERIES */
308
309void cpu_idle(void) 92void cpu_idle(void)
310{ 93{
311 idle_loop(); 94 BUG_ON(NULL == ppc_md.idle_loop);
95 ppc_md.idle_loop();
312} 96}
313 97
314int powersave_nap; 98int powersave_nap;
@@ -342,42 +126,3 @@ register_powersave_nap_sysctl(void)
342} 126}
343__initcall(register_powersave_nap_sysctl); 127__initcall(register_powersave_nap_sysctl);
344#endif 128#endif
345
346int idle_setup(void)
347{
348 /*
349 * Move that junk to each platform specific file, eventually define
350 * a pSeries_idle for shared processor stuff
351 */
352#ifdef CONFIG_PPC_ISERIES
353 idle_loop = iSeries_idle;
354 return 1;
355#else
356 idle_loop = default_idle;
357#endif
358#ifdef CONFIG_PPC_PSERIES
359 if (systemcfg->platform & PLATFORM_PSERIES) {
360 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
361 if (get_paca()->lppaca.shared_proc) {
362 printk(KERN_INFO "Using shared processor idle loop\n");
363 idle_loop = shared_idle;
364 } else {
365 printk(KERN_INFO "Using dedicated idle loop\n");
366 idle_loop = dedicated_idle;
367 }
368 } else {
369 printk(KERN_INFO "Using default idle loop\n");
370 idle_loop = default_idle;
371 }
372 }
373#endif /* CONFIG_PPC_PSERIES */
374#ifndef CONFIG_PPC_ISERIES
375 if (systemcfg->platform == PLATFORM_POWERMAC ||
376 systemcfg->platform == PLATFORM_MAPLE) {
377 printk(KERN_INFO "Using native/NAP idle loop\n");
378 idle_loop = native_idle;
379 }
380#endif /* CONFIG_PPC_ISERIES */
381
382 return 1;
383}
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
index da8900b51f40..bb55b5a56910 100644
--- a/arch/ppc64/kernel/maple_setup.c
+++ b/arch/ppc64/kernel/maple_setup.c
@@ -177,6 +177,8 @@ void __init maple_setup_arch(void)
177#ifdef CONFIG_DUMMY_CONSOLE 177#ifdef CONFIG_DUMMY_CONSOLE
178 conswitchp = &dummy_con; 178 conswitchp = &dummy_con;
179#endif 179#endif
180
181 printk(KERN_INFO "Using native/NAP idle loop\n");
180} 182}
181 183
182/* 184/*
@@ -297,4 +299,5 @@ struct machdep_calls __initdata maple_md = {
297 .get_rtc_time = maple_get_rtc_time, 299 .get_rtc_time = maple_get_rtc_time,
298 .calibrate_decr = generic_calibrate_decr, 300 .calibrate_decr = generic_calibrate_decr,
299 .progress = maple_progress, 301 .progress = maple_progress,
302 .idle_loop = native_idle,
300}; 303};
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index f3dea0c5a88c..59f4f9973818 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -1124,9 +1124,11 @@ _GLOBAL(sys_call_table32)
1124 .llong .compat_sys_mq_getsetattr 1124 .llong .compat_sys_mq_getsetattr
1125 .llong .compat_sys_kexec_load 1125 .llong .compat_sys_kexec_load
1126 .llong .sys32_add_key 1126 .llong .sys32_add_key
1127 .llong .sys32_request_key 1127 .llong .sys32_request_key /* 270 */
1128 .llong .compat_sys_keyctl 1128 .llong .compat_sys_keyctl
1129 .llong .compat_sys_waitid 1129 .llong .compat_sys_waitid
1130 .llong .sys32_ioprio_set
1131 .llong .sys32_ioprio_get
1130 1132
1131 .balign 8 1133 .balign 8
1132_GLOBAL(sys_call_table) 1134_GLOBAL(sys_call_table)
@@ -1403,3 +1405,5 @@ _GLOBAL(sys_call_table)
1403 .llong .sys_request_key /* 270 */ 1405 .llong .sys_request_key /* 270 */
1404 .llong .sys_keyctl 1406 .llong .sys_keyctl
1405 .llong .sys_waitid 1407 .llong .sys_waitid
1408 .llong .sys_ioprio_set
1409 .llong .sys_ioprio_get
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
index 44d9af72d225..5bec956e44a0 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -19,6 +19,7 @@
19#undef DEBUG 19#undef DEBUG
20 20
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/cpu.h>
22#include <linux/errno.h> 23#include <linux/errno.h>
23#include <linux/sched.h> 24#include <linux/sched.h>
24#include <linux/kernel.h> 25#include <linux/kernel.h>
@@ -82,6 +83,9 @@ int fwnmi_active; /* TRUE if an FWNMI handler is present */
82extern void pSeries_system_reset_exception(struct pt_regs *regs); 83extern void pSeries_system_reset_exception(struct pt_regs *regs);
83extern int pSeries_machine_check_exception(struct pt_regs *regs); 84extern int pSeries_machine_check_exception(struct pt_regs *regs);
84 85
86static int pseries_shared_idle(void);
87static int pseries_dedicated_idle(void);
88
85static volatile void __iomem * chrp_int_ack_special; 89static volatile void __iomem * chrp_int_ack_special;
86struct mpic *pSeries_mpic; 90struct mpic *pSeries_mpic;
87 91
@@ -229,6 +233,20 @@ static void __init pSeries_setup_arch(void)
229 233
230 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) 234 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
231 vpa_init(boot_cpuid); 235 vpa_init(boot_cpuid);
236
237 /* Choose an idle loop */
238 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
239 if (get_paca()->lppaca.shared_proc) {
240 printk(KERN_INFO "Using shared processor idle loop\n");
241 ppc_md.idle_loop = pseries_shared_idle;
242 } else {
243 printk(KERN_INFO "Using dedicated idle loop\n");
244 ppc_md.idle_loop = pseries_dedicated_idle;
245 }
246 } else {
247 printk(KERN_INFO "Using default idle loop\n");
248 ppc_md.idle_loop = default_idle;
249 }
232} 250}
233 251
234static int __init pSeries_init_panel(void) 252static int __init pSeries_init_panel(void)
@@ -418,6 +436,144 @@ static int __init pSeries_probe(int platform)
418 return 1; 436 return 1;
419} 437}
420 438
439DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
440
441static inline void dedicated_idle_sleep(unsigned int cpu)
442{
443 struct paca_struct *ppaca = &paca[cpu ^ 1];
444
445 /* Only sleep if the other thread is not idle */
446 if (!(ppaca->lppaca.idle)) {
447 local_irq_disable();
448
449 /*
450 * We are about to sleep the thread and so wont be polling any
451 * more.
452 */
453 clear_thread_flag(TIF_POLLING_NRFLAG);
454
455 /*
456 * SMT dynamic mode. Cede will result in this thread going
457 * dormant, if the partner thread is still doing work. Thread
458 * wakes up if partner goes idle, an interrupt is presented, or
459 * a prod occurs. Returning from the cede enables external
460 * interrupts.
461 */
462 if (!need_resched())
463 cede_processor();
464 else
465 local_irq_enable();
466 } else {
467 /*
468 * Give the HV an opportunity at the processor, since we are
469 * not doing any work.
470 */
471 poll_pending();
472 }
473}
474
475static int pseries_dedicated_idle(void)
476{
477 long oldval;
478 struct paca_struct *lpaca = get_paca();
479 unsigned int cpu = smp_processor_id();
480 unsigned long start_snooze;
481 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
482
483 while (1) {
484 /*
485 * Indicate to the HV that we are idle. Now would be
486 * a good time to find other work to dispatch.
487 */
488 lpaca->lppaca.idle = 1;
489
490 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
491 if (!oldval) {
492 set_thread_flag(TIF_POLLING_NRFLAG);
493
494 start_snooze = __get_tb() +
495 *smt_snooze_delay * tb_ticks_per_usec;
496
497 while (!need_resched() && !cpu_is_offline(cpu)) {
498 ppc64_runlatch_off();
499
500 /*
501 * Go into low thread priority and possibly
502 * low power mode.
503 */
504 HMT_low();
505 HMT_very_low();
506
507 if (*smt_snooze_delay != 0 &&
508 __get_tb() > start_snooze) {
509 HMT_medium();
510 dedicated_idle_sleep(cpu);
511 }
512
513 }
514
515 HMT_medium();
516 clear_thread_flag(TIF_POLLING_NRFLAG);
517 } else {
518 set_need_resched();
519 }
520
521 lpaca->lppaca.idle = 0;
522 ppc64_runlatch_on();
523
524 schedule();
525
526 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
527 cpu_die();
528 }
529}
530
531static int pseries_shared_idle(void)
532{
533 struct paca_struct *lpaca = get_paca();
534 unsigned int cpu = smp_processor_id();
535
536 while (1) {
537 /*
538 * Indicate to the HV that we are idle. Now would be
539 * a good time to find other work to dispatch.
540 */
541 lpaca->lppaca.idle = 1;
542
543 while (!need_resched() && !cpu_is_offline(cpu)) {
544 local_irq_disable();
545 ppc64_runlatch_off();
546
547 /*
548 * Yield the processor to the hypervisor. We return if
549 * an external interrupt occurs (which are driven prior
550 * to returning here) or if a prod occurs from another
551 * processor. When returning here, external interrupts
552 * are enabled.
553 *
554 * Check need_resched() again with interrupts disabled
555 * to avoid a race.
556 */
557 if (!need_resched())
558 cede_processor();
559 else
560 local_irq_enable();
561
562 HMT_medium();
563 }
564
565 lpaca->lppaca.idle = 0;
566 ppc64_runlatch_on();
567
568 schedule();
569
570 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
571 cpu_die();
572 }
573
574 return 0;
575}
576
421struct machdep_calls __initdata pSeries_md = { 577struct machdep_calls __initdata pSeries_md = {
422 .probe = pSeries_probe, 578 .probe = pSeries_probe,
423 .setup_arch = pSeries_setup_arch, 579 .setup_arch = pSeries_setup_arch,
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
index 6cf03d387b91..3013cdb5f933 100644
--- a/arch/ppc64/kernel/pmac_setup.c
+++ b/arch/ppc64/kernel/pmac_setup.c
@@ -186,6 +186,8 @@ void __init pmac_setup_arch(void)
186#ifdef CONFIG_DUMMY_CONSOLE 186#ifdef CONFIG_DUMMY_CONSOLE
187 conswitchp = &dummy_con; 187 conswitchp = &dummy_con;
188#endif 188#endif
189
190 printk(KERN_INFO "Using native/NAP idle loop\n");
189} 191}
190 192
191#ifdef CONFIG_SCSI 193#ifdef CONFIG_SCSI
@@ -507,5 +509,6 @@ struct machdep_calls __initdata pmac_md = {
507 .calibrate_decr = pmac_calibrate_decr, 509 .calibrate_decr = pmac_calibrate_decr,
508 .feature_call = pmac_do_feature_call, 510 .feature_call = pmac_do_feature_call,
509 .progress = pmac_progress, 511 .progress = pmac_progress,
510 .check_legacy_ioport = pmac_check_legacy_ioport 512 .check_legacy_ioport = pmac_check_legacy_ioport,
513 .idle_loop = native_idle,
511}; 514};
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index d5e4866e9ac2..d1b33f0b26cb 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -96,7 +96,6 @@ extern void udbg_init_maple_realmode(void);
96extern unsigned long klimit; 96extern unsigned long klimit;
97 97
98extern void mm_init_ppc64(void); 98extern void mm_init_ppc64(void);
99extern int idle_setup(void);
100extern void stab_initialize(unsigned long stab); 99extern void stab_initialize(unsigned long stab);
101extern void htab_initialize(void); 100extern void htab_initialize(void);
102extern void early_init_devtree(void *flat_dt); 101extern void early_init_devtree(void *flat_dt);
@@ -1081,8 +1080,11 @@ void __init setup_arch(char **cmdline_p)
1081 1080
1082 ppc_md.setup_arch(); 1081 ppc_md.setup_arch();
1083 1082
1084 /* Select the correct idle loop for the platform. */ 1083 /* Use the default idle loop if the platform hasn't provided one. */
1085 idle_setup(); 1084 if (NULL == ppc_md.idle_loop) {
1085 ppc_md.idle_loop = default_idle;
1086 printk(KERN_INFO "Using default idle loop\n");
1087 }
1086 1088
1087 paging_init(); 1089 paging_init();
1088 ppc64_boot_msg(0x15, "Setup Done"); 1090 ppc64_boot_msg(0x15, "Setup Done");
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
index 118436e8085a..206619080e66 100644
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -30,47 +30,26 @@
30#include <linux/sem.h> 30#include <linux/sem.h>
31#include <linux/msg.h> 31#include <linux/msg.h>
32#include <linux/shm.h> 32#include <linux/shm.h>
33#include <linux/slab.h>
34#include <linux/uio.h>
35#include <linux/aio.h>
36#include <linux/nfs_fs.h>
37#include <linux/module.h>
38#include <linux/sunrpc/svc.h>
39#include <linux/nfsd/nfsd.h>
40#include <linux/nfsd/cache.h>
41#include <linux/nfsd/xdr.h>
42#include <linux/nfsd/syscall.h>
43#include <linux/poll.h> 33#include <linux/poll.h>
44#include <linux/personality.h> 34#include <linux/personality.h>
45#include <linux/stat.h> 35#include <linux/stat.h>
46#include <linux/filter.h>
47#include <linux/highmem.h>
48#include <linux/highuid.h>
49#include <linux/mman.h> 36#include <linux/mman.h>
50#include <linux/ipv6.h>
51#include <linux/in.h> 37#include <linux/in.h>
52#include <linux/icmpv6.h>
53#include <linux/syscalls.h> 38#include <linux/syscalls.h>
54#include <linux/unistd.h> 39#include <linux/unistd.h>
55#include <linux/sysctl.h> 40#include <linux/sysctl.h>
56#include <linux/binfmts.h> 41#include <linux/binfmts.h>
57#include <linux/dnotify.h>
58#include <linux/security.h> 42#include <linux/security.h>
59#include <linux/compat.h> 43#include <linux/compat.h>
60#include <linux/ptrace.h> 44#include <linux/ptrace.h>
61#include <linux/aio_abi.h>
62#include <linux/elf.h> 45#include <linux/elf.h>
63 46
64#include <net/scm.h>
65#include <net/sock.h>
66
67#include <asm/ptrace.h> 47#include <asm/ptrace.h>
68#include <asm/types.h> 48#include <asm/types.h>
69#include <asm/ipc.h> 49#include <asm/ipc.h>
70#include <asm/uaccess.h> 50#include <asm/uaccess.h>
71#include <asm/unistd.h> 51#include <asm/unistd.h>
72#include <asm/semaphore.h> 52#include <asm/semaphore.h>
73#include <asm/ppcdebug.h>
74#include <asm/time.h> 53#include <asm/time.h>
75#include <asm/mmu_context.h> 54#include <asm/mmu_context.h>
76#include <asm/systemcfg.h> 55#include <asm/systemcfg.h>
@@ -350,8 +329,6 @@ asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
350 return ret; 329 return ret;
351} 330}
352 331
353
354/* These are here just in case some old sparc32 binary calls it. */
355asmlinkage long sys32_pause(void) 332asmlinkage long sys32_pause(void)
356{ 333{
357 current->state = TASK_INTERRUPTIBLE; 334 current->state = TASK_INTERRUPTIBLE;
@@ -360,8 +337,6 @@ asmlinkage long sys32_pause(void)
360 return -ERESTARTNOHAND; 337 return -ERESTARTNOHAND;
361} 338}
362 339
363
364
365static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) 340static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
366{ 341{
367 long usec; 342 long usec;
@@ -847,16 +822,6 @@ asmlinkage long sys32_getpgid(u32 pid)
847} 822}
848 823
849 824
850/* Note: it is necessary to treat which and who as unsigned ints,
851 * with the corresponding cast to a signed int to insure that the
852 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
853 * and the register representation of a signed int (msr in 64-bit mode) is performed.
854 */
855asmlinkage long sys32_getpriority(u32 which, u32 who)
856{
857 return sys_getpriority((int)which, (int)who);
858}
859
860 825
861/* Note: it is necessary to treat pid as an unsigned int, 826/* Note: it is necessary to treat pid as an unsigned int,
862 * with the corresponding cast to a signed int to insure that the 827 * with the corresponding cast to a signed int to insure that the
@@ -1048,6 +1013,11 @@ asmlinkage long sys32_setpgid(u32 pid, u32 pgid)
1048 return sys_setpgid((int)pid, (int)pgid); 1013 return sys_setpgid((int)pid, (int)pgid);
1049} 1014}
1050 1015
1016long sys32_getpriority(u32 which, u32 who)
1017{
1018 /* sign extend which and who */
1019 return sys_getpriority((int)which, (int)who);
1020}
1051 1021
1052long sys32_setpriority(u32 which, u32 who, u32 niceval) 1022long sys32_setpriority(u32 which, u32 who, u32 niceval)
1053{ 1023{
@@ -1055,6 +1025,18 @@ long sys32_setpriority(u32 which, u32 who, u32 niceval)
1055 return sys_setpriority((int)which, (int)who, (int)niceval); 1025 return sys_setpriority((int)which, (int)who, (int)niceval);
1056} 1026}
1057 1027
1028long sys32_ioprio_get(u32 which, u32 who)
1029{
1030 /* sign extend which and who */
1031 return sys_ioprio_get((int)which, (int)who);
1032}
1033
1034long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
1035{
1036 /* sign extend which, who and ioprio */
1037 return sys_ioprio_set((int)which, (int)who, (int)ioprio);
1038}
1039
1058/* Note: it is necessary to treat newmask as an unsigned int, 1040/* Note: it is necessary to treat newmask as an unsigned int,
1059 * with the corresponding cast to a signed int to insure that the 1041 * with the corresponding cast to a signed int to insure that the
1060 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 1042 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -1273,8 +1255,6 @@ long ppc32_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
1273 (u64)len_high << 32 | len_low, advice); 1255 (u64)len_high << 32 | len_low, advice);
1274} 1256}
1275 1257
1276extern asmlinkage long sys_timer_create(clockid_t, sigevent_t __user *, timer_t __user *);
1277
1278long ppc32_timer_create(clockid_t clock, 1258long ppc32_timer_create(clockid_t clock,
1279 struct compat_sigevent __user *ev32, 1259 struct compat_sigevent __user *ev32,
1280 timer_t __user *timer_id) 1260 timer_t __user *timer_id)
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
index 2f704a2cafb1..02b8ac4e0168 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -112,7 +112,6 @@ void ppc64_enable_pmcs(void)
112 unsigned long hid0; 112 unsigned long hid0;
113#ifdef CONFIG_PPC_PSERIES 113#ifdef CONFIG_PPC_PSERIES
114 unsigned long set, reset; 114 unsigned long set, reset;
115 int ret;
116#endif /* CONFIG_PPC_PSERIES */ 115#endif /* CONFIG_PPC_PSERIES */
117 116
118 /* Only need to enable them once */ 117 /* Only need to enable them once */
@@ -145,11 +144,7 @@ void ppc64_enable_pmcs(void)
145 case PLATFORM_PSERIES_LPAR: 144 case PLATFORM_PSERIES_LPAR:
146 set = 1UL << 63; 145 set = 1UL << 63;
147 reset = 0; 146 reset = 0;
148 ret = plpar_hcall_norets(H_PERFMON, set, reset); 147 plpar_hcall_norets(H_PERFMON, set, reset);
149 if (ret)
150 printk(KERN_ERR "H_PERFMON call on cpu %u "
151 "returned %d\n",
152 smp_processor_id(), ret);
153 break; 148 break;
154#endif /* CONFIG_PPC_PSERIES */ 149#endif /* CONFIG_PPC_PSERIES */
155 150
@@ -161,13 +156,6 @@ void ppc64_enable_pmcs(void)
161 /* instruct hypervisor to maintain PMCs */ 156 /* instruct hypervisor to maintain PMCs */
162 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) 157 if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
163 get_paca()->lppaca.pmcregs_in_use = 1; 158 get_paca()->lppaca.pmcregs_in_use = 1;
164
165 /*
166 * On SMT machines we have to set the run latch in the ctrl register
167 * in order to make PMC6 spin.
168 */
169 if (cpu_has_feature(CPU_FTR_SMT))
170 ppc64_runlatch_on();
171#endif /* CONFIG_PPC_PSERIES */ 159#endif /* CONFIG_PPC_PSERIES */
172} 160}
173 161
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S
index 11290c902ba3..6f87a916a394 100644
--- a/arch/ppc64/kernel/vdso32/vdso32.lds.S
+++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S
@@ -40,9 +40,9 @@ SECTIONS
40 .gcc_except_table : { *(.gcc_except_table) } 40 .gcc_except_table : { *(.gcc_except_table) }
41 .fixup : { *(.fixup) } 41 .fixup : { *(.fixup) }
42 42
43 .got ALIGN(4) : { *(.got.plt) *(.got) }
44
45 .dynamic : { *(.dynamic) } :text :dynamic 43 .dynamic : { *(.dynamic) } :text :dynamic
44 .got : { *(.got) }
45 .plt : { *(.plt) }
46 46
47 _end = .; 47 _end = .;
48 __end = .; 48 __end = .;
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 9469e77303e6..6682c7883647 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -128,7 +128,6 @@ config HOSTFS
128 128
129config HPPFS 129config HPPFS
130 tristate "HoneyPot ProcFS (EXPERIMENTAL)" 130 tristate "HoneyPot ProcFS (EXPERIMENTAL)"
131 depends on BROKEN
132 help 131 help
133 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 132 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
134 entries to be overridden, removed, or fabricated from the host. 133 entries to be overridden, removed, or fabricated from the host.
@@ -141,8 +140,9 @@ config HPPFS
141 You only need this if you are setting up a UML honeypot. Otherwise, 140 You only need this if you are setting up a UML honeypot. Otherwise,
142 it is safe to say 'N' here. 141 it is safe to say 'N' here.
143 142
144 If you are actively using it, please ask for it to be fixed. In this 143 If you are actively using it, please report any problems, since it's
145 moment, it does not work on 2.6 (it works somehow on 2.4). 144 getting fixed. In this moment, it is experimental on 2.6 (it works on
145 2.4).
146 146
147config MCONSOLE 147config MCONSOLE
148 bool "Management console" 148 bool "Management console"
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
index e41f3748d30f..27c18a8d9d17 100644
--- a/arch/um/Kconfig_i386
+++ b/arch/um/Kconfig_i386
@@ -19,6 +19,18 @@ config 3_LEVEL_PGTABLES
19 memory. All the memory that can't be mapped directly will be treated 19 memory. All the memory that can't be mapped directly will be treated
20 as high memory. 20 as high memory.
21 21
22config STUB_CODE
23 hex
24 default 0xbfffe000
25
26config STUB_DATA
27 hex
28 default 0xbffff000
29
30config STUB_START
31 hex
32 default STUB_CODE
33
22config ARCH_HAS_SC_SIGNALS 34config ARCH_HAS_SC_SIGNALS
23 bool 35 bool
24 default y 36 default y
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
index f162f50f0b17..735a047c890c 100644
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -14,6 +14,18 @@ config 3_LEVEL_PGTABLES
14 bool 14 bool
15 default y 15 default y
16 16
17config STUB_CODE
18 hex
19 default 0x7fbfffe000
20
21config STUB_DATA
22 hex
23 default 0x7fbffff000
24
25config STUB_START
26 hex
27 default STUB_CODE
28
17config ARCH_HAS_SC_SIGNALS 29config ARCH_HAS_SC_SIGNALS
18 bool 30 bool
19 default n 31 default n
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 29e182d5a83a..301059062a3e 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -8,7 +8,7 @@ ifeq ($(CONFIG_MODE_SKAS),y)
8 endif 8 endif
9endif 9endif
10 10
11CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) 11CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS)
12ARCH_USER_CFLAGS := 12ARCH_USER_CFLAGS :=
13 13
14ifneq ($(CONFIG_GPROF),y) 14ifneq ($(CONFIG_GPROF),y)
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 32144562c279..d80bd0052e6b 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -4,7 +4,7 @@
4SUBARCH_LIBS := arch/um/sys-x86_64/ 4SUBARCH_LIBS := arch/um/sys-x86_64/
5START := 0x60000000 5START := 0x60000000
6 6
7CFLAGS += -U__$(SUBARCH)__ -fno-builtin 7CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS)
8ARCH_USER_CFLAGS := -D__x86_64__ 8ARCH_USER_CFLAGS := -D__x86_64__
9 9
10ELF_ARCH := i386:x86-64 10ELF_ARCH := i386:x86-64
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 4067c3aa5b60..80d30d19d750 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,7 +1,7 @@
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-rc3-skas3-v9-pre2 3# Linux kernel version: 2.6.12-rc6-mm1
4# Sun Apr 24 19:46:10 2005 4# Tue Jun 14 18:22:21 2005
5# 5#
6CONFIG_GENERIC_HARDIRQS=y 6CONFIG_GENERIC_HARDIRQS=y
7CONFIG_UML=y 7CONFIG_UML=y
@@ -13,23 +13,32 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
13# 13#
14# UML-specific options 14# UML-specific options
15# 15#
16CONFIG_MODE_TT=y 16# CONFIG_MODE_TT is not set
17# CONFIG_STATIC_LINK is not set
17CONFIG_MODE_SKAS=y 18CONFIG_MODE_SKAS=y
18CONFIG_UML_X86=y 19CONFIG_UML_X86=y
19# CONFIG_64BIT is not set 20# CONFIG_64BIT is not set
20CONFIG_TOP_ADDR=0xc0000000 21CONFIG_TOP_ADDR=0xc0000000
21# CONFIG_3_LEVEL_PGTABLES is not set 22# CONFIG_3_LEVEL_PGTABLES is not set
23CONFIG_STUB_CODE=0xbfffe000
24CONFIG_STUB_DATA=0xbffff000
25CONFIG_STUB_START=0xbfffe000
22CONFIG_ARCH_HAS_SC_SIGNALS=y 26CONFIG_ARCH_HAS_SC_SIGNALS=y
23CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y 27CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
24CONFIG_LD_SCRIPT_STATIC=y 28CONFIG_SELECT_MEMORY_MODEL=y
29CONFIG_FLATMEM_MANUAL=y
30# CONFIG_DISCONTIGMEM_MANUAL is not set
31# CONFIG_SPARSEMEM_MANUAL is not set
32CONFIG_FLATMEM=y
33CONFIG_FLAT_NODE_MEM_MAP=y
34CONFIG_LD_SCRIPT_DYN=y
25CONFIG_NET=y 35CONFIG_NET=y
26CONFIG_BINFMT_ELF=y 36CONFIG_BINFMT_ELF=y
27CONFIG_BINFMT_MISC=m 37CONFIG_BINFMT_MISC=m
28CONFIG_HOSTFS=y 38# CONFIG_HOSTFS is not set
29CONFIG_MCONSOLE=y 39CONFIG_MCONSOLE=y
30# CONFIG_MAGIC_SYSRQ is not set 40# CONFIG_MAGIC_SYSRQ is not set
31# CONFIG_HOST_2G_2G is not set 41# CONFIG_HOST_2G_2G is not set
32# CONFIG_SMP is not set
33CONFIG_NEST_LEVEL=0 42CONFIG_NEST_LEVEL=0
34CONFIG_KERNEL_HALF_GIGS=1 43CONFIG_KERNEL_HALF_GIGS=1
35# CONFIG_HIGHMEM is not set 44# CONFIG_HIGHMEM is not set
@@ -63,6 +72,8 @@ CONFIG_IKCONFIG_PROC=y
63CONFIG_KALLSYMS=y 72CONFIG_KALLSYMS=y
64# CONFIG_KALLSYMS_ALL is not set 73# CONFIG_KALLSYMS_ALL is not set
65CONFIG_KALLSYMS_EXTRA_PASS=y 74CONFIG_KALLSYMS_EXTRA_PASS=y
75CONFIG_PRINTK=y
76CONFIG_BUG=y
66CONFIG_BASE_FULL=y 77CONFIG_BASE_FULL=y
67CONFIG_FUTEX=y 78CONFIG_FUTEX=y
68CONFIG_EPOLL=y 79CONFIG_EPOLL=y
@@ -81,6 +92,7 @@ CONFIG_MODULES=y
81CONFIG_MODULE_UNLOAD=y 92CONFIG_MODULE_UNLOAD=y
82# CONFIG_MODULE_FORCE_UNLOAD is not set 93# CONFIG_MODULE_FORCE_UNLOAD is not set
83CONFIG_OBSOLETE_MODPARM=y 94CONFIG_OBSOLETE_MODPARM=y
95# CONFIG_MODVERSIONS is not set
84# CONFIG_MODULE_SRCVERSION_ALL is not set 96# CONFIG_MODULE_SRCVERSION_ALL is not set
85CONFIG_KMOD=y 97CONFIG_KMOD=y
86 98
@@ -115,6 +127,7 @@ CONFIG_UML_SOUND=m
115CONFIG_SOUND=m 127CONFIG_SOUND=m
116CONFIG_HOSTAUDIO=m 128CONFIG_HOSTAUDIO=m
117CONFIG_UML_RANDOM=y 129CONFIG_UML_RANDOM=y
130# CONFIG_MMAPPER is not set
118 131
119# 132#
120# Block devices 133# Block devices
@@ -176,6 +189,17 @@ CONFIG_INET=y
176# CONFIG_INET_TUNNEL is not set 189# CONFIG_INET_TUNNEL is not set
177CONFIG_IP_TCPDIAG=y 190CONFIG_IP_TCPDIAG=y
178# CONFIG_IP_TCPDIAG_IPV6 is not set 191# CONFIG_IP_TCPDIAG_IPV6 is not set
192
193#
194# TCP congestion control
195#
196CONFIG_TCP_CONG_BIC=y
197CONFIG_TCP_CONG_WESTWOOD=y
198CONFIG_TCP_CONG_HTCP=y
199# CONFIG_TCP_CONG_HSTCP is not set
200# CONFIG_TCP_CONG_HYBLA is not set
201# CONFIG_TCP_CONG_VEGAS is not set
202# CONFIG_TCP_CONG_SCALABLE is not set
179# CONFIG_IPV6 is not set 203# CONFIG_IPV6 is not set
180# CONFIG_NETFILTER is not set 204# CONFIG_NETFILTER is not set
181 205
@@ -206,11 +230,15 @@ CONFIG_IP_TCPDIAG=y
206# Network testing 230# Network testing
207# 231#
208# CONFIG_NET_PKTGEN is not set 232# CONFIG_NET_PKTGEN is not set
233# CONFIG_KGDBOE is not set
209# CONFIG_NETPOLL is not set 234# CONFIG_NETPOLL is not set
235# CONFIG_NETPOLL_RX is not set
236# CONFIG_NETPOLL_TRAP is not set
210# CONFIG_NET_POLL_CONTROLLER is not set 237# CONFIG_NET_POLL_CONTROLLER is not set
211# CONFIG_HAMRADIO is not set 238# CONFIG_HAMRADIO is not set
212# CONFIG_IRDA is not set 239# CONFIG_IRDA is not set
213# CONFIG_BT is not set 240# CONFIG_BT is not set
241# CONFIG_IEEE80211 is not set
214CONFIG_DUMMY=m 242CONFIG_DUMMY=m
215# CONFIG_BONDING is not set 243# CONFIG_BONDING is not set
216# CONFIG_EQUALIZER is not set 244# CONFIG_EQUALIZER is not set
@@ -227,6 +255,7 @@ CONFIG_PPP=m
227# CONFIG_PPP_SYNC_TTY is not set 255# CONFIG_PPP_SYNC_TTY is not set
228# CONFIG_PPP_DEFLATE is not set 256# CONFIG_PPP_DEFLATE is not set
229# CONFIG_PPP_BSDCOMP is not set 257# CONFIG_PPP_BSDCOMP is not set
258# CONFIG_PPP_MPPE is not set
230# CONFIG_PPPOE is not set 259# CONFIG_PPPOE is not set
231CONFIG_SLIP=m 260CONFIG_SLIP=m
232# CONFIG_SLIP_COMPRESSED is not set 261# CONFIG_SLIP_COMPRESSED is not set
@@ -240,10 +269,12 @@ CONFIG_SLIP=m
240# 269#
241CONFIG_EXT2_FS=y 270CONFIG_EXT2_FS=y
242# CONFIG_EXT2_FS_XATTR is not set 271# CONFIG_EXT2_FS_XATTR is not set
272# CONFIG_EXT2_FS_XIP is not set
243CONFIG_EXT3_FS=y 273CONFIG_EXT3_FS=y
244# CONFIG_EXT3_FS_XATTR is not set 274# CONFIG_EXT3_FS_XATTR is not set
245CONFIG_JBD=y 275CONFIG_JBD=y
246# CONFIG_JBD_DEBUG is not set 276# CONFIG_JBD_DEBUG is not set
277# CONFIG_REISER4_FS is not set
247CONFIG_REISERFS_FS=y 278CONFIG_REISERFS_FS=y
248# CONFIG_REISERFS_CHECK is not set 279# CONFIG_REISERFS_CHECK is not set
249# CONFIG_REISERFS_PROC_INFO is not set 280# CONFIG_REISERFS_PROC_INFO is not set
@@ -256,6 +287,7 @@ CONFIG_REISERFS_FS=y
256# CONFIG_XFS_FS is not set 287# CONFIG_XFS_FS is not set
257# CONFIG_MINIX_FS is not set 288# CONFIG_MINIX_FS is not set
258# CONFIG_ROMFS_FS is not set 289# CONFIG_ROMFS_FS is not set
290CONFIG_INOTIFY=y
259CONFIG_QUOTA=y 291CONFIG_QUOTA=y
260# CONFIG_QFMT_V1 is not set 292# CONFIG_QFMT_V1 is not set
261# CONFIG_QFMT_V2 is not set 293# CONFIG_QFMT_V2 is not set
@@ -265,6 +297,12 @@ CONFIG_AUTOFS_FS=m
265CONFIG_AUTOFS4_FS=m 297CONFIG_AUTOFS4_FS=m
266 298
267# 299#
300# Caches
301#
302# CONFIG_FSCACHE is not set
303# CONFIG_FUSE_FS is not set
304
305#
268# CD-ROM/DVD Filesystems 306# CD-ROM/DVD Filesystems
269# 307#
270CONFIG_ISO9660_FS=m 308CONFIG_ISO9660_FS=m
@@ -291,6 +329,8 @@ CONFIG_TMPFS=y
291# CONFIG_TMPFS_XATTR is not set 329# CONFIG_TMPFS_XATTR is not set
292# CONFIG_HUGETLB_PAGE is not set 330# CONFIG_HUGETLB_PAGE is not set
293CONFIG_RAMFS=y 331CONFIG_RAMFS=y
332# CONFIG_CONFIGFS_FS is not set
333# CONFIG_RELAYFS_FS is not set
294 334
295# 335#
296# Miscellaneous filesystems 336# Miscellaneous filesystems
@@ -319,6 +359,7 @@ CONFIG_RAMFS=y
319# CONFIG_NCP_FS is not set 359# CONFIG_NCP_FS is not set
320# CONFIG_CODA_FS is not set 360# CONFIG_CODA_FS is not set
321# CONFIG_AFS_FS is not set 361# CONFIG_AFS_FS is not set
362# CONFIG_9P_FS is not set
322 363
323# 364#
324# Partition Types 365# Partition Types
@@ -404,14 +445,15 @@ CONFIG_CRC32=m
404# CONFIG_PRINTK_TIME is not set 445# CONFIG_PRINTK_TIME is not set
405CONFIG_DEBUG_KERNEL=y 446CONFIG_DEBUG_KERNEL=y
406CONFIG_LOG_BUF_SHIFT=14 447CONFIG_LOG_BUF_SHIFT=14
448CONFIG_DETECT_SOFTLOCKUP=y
407# CONFIG_SCHEDSTATS is not set 449# CONFIG_SCHEDSTATS is not set
408# CONFIG_DEBUG_SLAB is not set 450CONFIG_DEBUG_SLAB=y
409# CONFIG_DEBUG_SPINLOCK is not set 451# CONFIG_DEBUG_SPINLOCK is not set
410# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 452# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
411# CONFIG_DEBUG_KOBJECT is not set 453# CONFIG_DEBUG_KOBJECT is not set
412CONFIG_DEBUG_INFO=y 454CONFIG_DEBUG_INFO=y
413# CONFIG_DEBUG_FS is not set 455# CONFIG_DEBUG_FS is not set
414CONFIG_FRAME_POINTER=y 456CONFIG_FRAME_POINTER=y
415CONFIG_PT_PROXY=y 457# CONFIG_GPROF is not set
416# CONFIG_GCOV is not set 458# CONFIG_GCOV is not set
417# CONFIG_SYSCALL_DEBUG is not set 459# CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 2bb4c4f5dec4..e0fdffa2d542 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -663,11 +663,15 @@ struct tty_driver *line_register_devfs(struct lines *set,
663 return driver; 663 return driver;
664} 664}
665 665
666static spinlock_t winch_handler_lock;
667LIST_HEAD(winch_handlers);
668
666void lines_init(struct line *lines, int nlines) 669void lines_init(struct line *lines, int nlines)
667{ 670{
668 struct line *line; 671 struct line *line;
669 int i; 672 int i;
670 673
674 spin_lock_init(&winch_handler_lock);
671 for(i = 0; i < nlines; i++){ 675 for(i = 0; i < nlines; i++){
672 line = &lines[i]; 676 line = &lines[i];
673 INIT_LIST_HEAD(&line->chan_list); 677 INIT_LIST_HEAD(&line->chan_list);
@@ -724,31 +728,30 @@ irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
724 return IRQ_HANDLED; 728 return IRQ_HANDLED;
725} 729}
726 730
727DECLARE_MUTEX(winch_handler_sem);
728LIST_HEAD(winch_handlers);
729
730void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) 731void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
731{ 732{
732 struct winch *winch; 733 struct winch *winch;
733 734
734 down(&winch_handler_sem);
735 winch = kmalloc(sizeof(*winch), GFP_KERNEL); 735 winch = kmalloc(sizeof(*winch), GFP_KERNEL);
736 if (winch == NULL) { 736 if (winch == NULL) {
737 printk("register_winch_irq - kmalloc failed\n"); 737 printk("register_winch_irq - kmalloc failed\n");
738 goto out; 738 return;
739 } 739 }
740
740 *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), 741 *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list),
741 .fd = fd, 742 .fd = fd,
742 .tty_fd = tty_fd, 743 .tty_fd = tty_fd,
743 .pid = pid, 744 .pid = pid,
744 .tty = tty }); 745 .tty = tty });
746
747 spin_lock(&winch_handler_lock);
745 list_add(&winch->list, &winch_handlers); 748 list_add(&winch->list, &winch_handlers);
749 spin_unlock(&winch_handler_lock);
750
746 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 751 if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
747 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 752 SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
748 "winch", winch) < 0) 753 "winch", winch) < 0)
749 printk("register_winch_irq - failed to register IRQ\n"); 754 printk("register_winch_irq - failed to register IRQ\n");
750 out:
751 up(&winch_handler_sem);
752} 755}
753 756
754static void unregister_winch(struct tty_struct *tty) 757static void unregister_winch(struct tty_struct *tty)
@@ -756,7 +759,7 @@ static void unregister_winch(struct tty_struct *tty)
756 struct list_head *ele; 759 struct list_head *ele;
757 struct winch *winch, *found = NULL; 760 struct winch *winch, *found = NULL;
758 761
759 down(&winch_handler_sem); 762 spin_lock(&winch_handler_lock);
760 list_for_each(ele, &winch_handlers){ 763 list_for_each(ele, &winch_handlers){
761 winch = list_entry(ele, struct winch, list); 764 winch = list_entry(ele, struct winch, list);
762 if(winch->tty == tty){ 765 if(winch->tty == tty){
@@ -764,20 +767,25 @@ static void unregister_winch(struct tty_struct *tty)
764 break; 767 break;
765 } 768 }
766 } 769 }
767
768 if(found == NULL) 770 if(found == NULL)
769 goto out; 771 goto err;
772
773 list_del(&winch->list);
774 spin_unlock(&winch_handler_lock);
770 775
771 if(winch->pid != -1) 776 if(winch->pid != -1)
772 os_kill_process(winch->pid, 1); 777 os_kill_process(winch->pid, 1);
773 778
774 free_irq(WINCH_IRQ, winch); 779 free_irq(WINCH_IRQ, winch);
775 list_del(&winch->list);
776 kfree(winch); 780 kfree(winch);
777 out: 781
778 up(&winch_handler_sem); 782 return;
783err:
784 spin_unlock(&winch_handler_lock);
779} 785}
780 786
787/* XXX: No lock as it's an exitcall... is this valid? Depending on cleanup
788 * order... are we sure that nothing else is done on the list? */
781static void winch_cleanup(void) 789static void winch_cleanup(void)
782{ 790{
783 struct list_head *ele; 791 struct list_head *ele;
@@ -786,6 +794,9 @@ static void winch_cleanup(void)
786 list_for_each(ele, &winch_handlers){ 794 list_for_each(ele, &winch_handlers){
787 winch = list_entry(ele, struct winch, list); 795 winch = list_entry(ele, struct winch, list);
788 if(winch->fd != -1){ 796 if(winch->fd != -1){
797 /* Why is this different from the above free_irq(),
798 * which deactivates SIGIO? This searches the FD
799 * somewhere else and removes it from the list... */
789 deactivate_fd(winch->fd, WINCH_IRQ); 800 deactivate_fd(winch->fd, WINCH_IRQ);
790 os_close_file(winch->fd); 801 os_close_file(winch->fd);
791 } 802 }
diff --git a/arch/um/include/mem.h b/arch/um/include/mem.h
index 10c46c38949a..99d3ad4a03e5 100644
--- a/arch/um/include/mem.h
+++ b/arch/um/include/mem.h
@@ -13,6 +13,7 @@ extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
13extern int is_remapped(void *virt); 13extern int is_remapped(void *virt);
14extern int physmem_remove_mapping(void *virt); 14extern int physmem_remove_mapping(void *virt);
15extern void physmem_forget_descriptor(int fd); 15extern void physmem_forget_descriptor(int fd);
16extern unsigned long to_phys(void *virt);
16 17
17#endif 18#endif
18 19
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 8744abb5224f..0a35e6d0baa0 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -14,6 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs);
14extern void save_registers(int pid, union uml_pt_regs *regs); 14extern void save_registers(int pid, union uml_pt_regs *regs);
15extern void restore_registers(int pid, union uml_pt_regs *regs); 15extern void restore_registers(int pid, union uml_pt_regs *regs);
16extern void init_registers(int pid); 16extern void init_registers(int pid);
17extern void get_safe_registers(unsigned long * regs);
17 18
18#endif 19#endif
19 20
diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h
index eca8066e7a43..899aa4b2a78d 100644
--- a/arch/um/include/sysdep-i386/ptrace_user.h
+++ b/arch/um/include/sysdep-i386/ptrace_user.h
@@ -20,11 +20,24 @@
20#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX) 20#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
21#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI) 21#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
22#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI) 22#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
23#define PT_SYSCALL_ARG6_OFFSET PT_OFFSET(EBP)
23 24
24#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) 25#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
25 26
27#define REGS_SYSCALL_NR EAX /* This is used before a system call */
28#define REGS_SYSCALL_ARG1 EBX
29#define REGS_SYSCALL_ARG2 ECX
30#define REGS_SYSCALL_ARG3 EDX
31#define REGS_SYSCALL_ARG4 ESI
32#define REGS_SYSCALL_ARG5 EDI
33#define REGS_SYSCALL_ARG6 EBP
34
35#define REGS_IP_INDEX EIP
36#define REGS_SP_INDEX UESP
37
26#define PT_IP_OFFSET PT_OFFSET(EIP) 38#define PT_IP_OFFSET PT_OFFSET(EIP)
27#define PT_IP(regs) ((regs)[EIP]) 39#define PT_IP(regs) ((regs)[EIP])
40#define PT_SP_OFFSET PT_OFFSET(UESP)
28#define PT_SP(regs) ((regs)[UESP]) 41#define PT_SP(regs) ((regs)[UESP])
29 42
30#ifndef FRAME_SIZE 43#ifndef FRAME_SIZE
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
new file mode 100644
index 000000000000..d3699fe1c613
--- /dev/null
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -0,0 +1,65 @@
1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_STUB_H
7#define __SYSDEP_STUB_H
8
9#include <asm/ptrace.h>
10#include <asm/unistd.h>
11
12extern void stub_segv_handler(int sig);
13extern void stub_clone_handler(void);
14
15#define STUB_SYSCALL_RET EAX
16#define STUB_MMAP_NR __NR_mmap2
17#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
18
19static inline long stub_syscall2(long syscall, long arg1, long arg2)
20{
21 long ret;
22
23 __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
24 __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
25 __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
26 __asm__("int $0x80;" : : : "%eax");
27 __asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :);
28 return(ret);
29}
30
31static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
32{
33 __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
34 return(stub_syscall2(syscall, arg1, arg2));
35}
36
37static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
38 long arg4)
39{
40 __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
41 return(stub_syscall3(syscall, arg1, arg2, arg3));
42}
43
44static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
45 long arg4, long arg5, long arg6)
46{
47 long ret;
48 __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
49 __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
50 __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
51 __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
52 __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
53 __asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi");
54 __asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; "
55 "int $0x80; popl %%ebp ; "
56 "movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax");
57 return(ret);
58}
59
60static inline void trap_myself(void)
61{
62 __asm("int3");
63}
64
65#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
index 31729973fb14..128faf027364 100644
--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -55,6 +55,20 @@
55#define PTRACE_OLDSETOPTIONS 21 55#define PTRACE_OLDSETOPTIONS 21
56#endif 56#endif
57 57
58/* These are before the system call, so the the system call number is RAX
59 * rather than ORIG_RAX, and arg4 is R10 rather than RCX
60 */
61#define REGS_SYSCALL_NR PT_INDEX(RAX)
62#define REGS_SYSCALL_ARG1 PT_INDEX(RDI)
63#define REGS_SYSCALL_ARG2 PT_INDEX(RSI)
64#define REGS_SYSCALL_ARG3 PT_INDEX(RDX)
65#define REGS_SYSCALL_ARG4 PT_INDEX(R10)
66#define REGS_SYSCALL_ARG5 PT_INDEX(R8)
67#define REGS_SYSCALL_ARG6 PT_INDEX(R9)
68
69#define REGS_IP_INDEX PT_INDEX(RIP)
70#define REGS_SP_INDEX PT_INDEX(RSP)
71
58#endif 72#endif
59 73
60/* 74/*
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
new file mode 100644
index 000000000000..f599058d8263
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SYSDEP_STUB_H
7#define __SYSDEP_STUB_H
8
9#include <asm/ptrace.h>
10#include <asm/unistd.h>
11#include <sysdep/ptrace_user.h>
12
13extern void stub_segv_handler(int sig);
14extern void stub_clone_handler(void);
15
16#define STUB_SYSCALL_RET PT_INDEX(RAX)
17#define STUB_MMAP_NR __NR_mmap
18#define MMAP_OFFSET(o) (o)
19
20static inline long stub_syscall2(long syscall, long arg1, long arg2)
21{
22 long ret;
23
24 __asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi");
25 __asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi");
26 __asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax");
27 __asm__("syscall;" : : : "%rax", "%r11", "%rcx");
28 __asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :);
29 return(ret);
30}
31
32static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
33{
34 __asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx");
35 return(stub_syscall2(syscall, arg1, arg2));
36}
37
38static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
39 long arg4)
40{
41 __asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10");
42 return(stub_syscall3(syscall, arg1, arg2, arg3));
43}
44
45static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
46 long arg4, long arg5, long arg6)
47{
48 __asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9");
49 __asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8");
50 return(stub_syscall4(syscall, arg1, arg2, arg3, arg4));
51}
52
53static inline void trap_myself(void)
54{
55 __asm("int3");
56}
57
58#endif
diff --git a/arch/um/include/time_user.h b/arch/um/include/time_user.h
index f64ef77019a3..17d7ef2141f4 100644
--- a/arch/um/include/time_user.h
+++ b/arch/um/include/time_user.h
@@ -10,6 +10,7 @@ extern void timer(void);
10extern void switch_timers(int to_real); 10extern void switch_timers(int to_real);
11extern void idle_sleep(int secs); 11extern void idle_sleep(int secs);
12extern void enable_timer(void); 12extern void enable_timer(void);
13extern void prepare_timer(void * ptr);
13extern void disable_timer(void); 14extern void disable_timer(void);
14extern unsigned long time_lock(void); 15extern unsigned long time_lock(void);
15extern void time_unlock(unsigned long); 16extern void time_unlock(unsigned long);
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
index da1097285b8c..c6f9628f39bf 100644
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -37,31 +37,25 @@ struct host_vm_op {
37extern void mprotect_kernel_vm(int w); 37extern void mprotect_kernel_vm(int w);
38extern void force_flush_all(void); 38extern void force_flush_all(void);
39extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr, 39extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
40 unsigned long end_addr, int force, int data, 40 unsigned long end_addr, int force,
41 void (*do_ops)(int, struct host_vm_op *, int)); 41 void (*do_ops)(union mm_context *,
42 struct host_vm_op *, int));
42extern int flush_tlb_kernel_range_common(unsigned long start, 43extern int flush_tlb_kernel_range_common(unsigned long start,
43 unsigned long end); 44 unsigned long end);
44 45
45extern int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, 46extern int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
46 int r, int w, int x, struct host_vm_op *ops, int index, 47 int r, int w, int x, struct host_vm_op *ops, int index,
47 int last_filled, int data, 48 int last_filled, union mm_context *mmu,
48 void (*do_ops)(int, struct host_vm_op *, int)); 49 void (*do_ops)(union mm_context *, struct host_vm_op *,
50 int));
49extern int add_munmap(unsigned long addr, unsigned long len, 51extern int add_munmap(unsigned long addr, unsigned long len,
50 struct host_vm_op *ops, int index, int last_filled, 52 struct host_vm_op *ops, int index, int last_filled,
51 int data, void (*do_ops)(int, struct host_vm_op *, int)); 53 union mm_context *mmu,
54 void (*do_ops)(union mm_context *, struct host_vm_op *,
55 int));
52extern int add_mprotect(unsigned long addr, unsigned long len, int r, int w, 56extern int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
53 int x, struct host_vm_op *ops, int index, 57 int x, struct host_vm_op *ops, int index,
54 int last_filled, int data, 58 int last_filled, union mm_context *mmu,
55 void (*do_ops)(int, struct host_vm_op *, int)); 59 void (*do_ops)(union mm_context *, struct host_vm_op *,
60 int));
56#endif 61#endif
57
58/*
59 * Overrides for Emacs so that we follow Linus's tabbing style.
60 * Emacs will notice this stuff at the end of the file and automatically
61 * adjust the settings for this buffer only. This must remain at the end
62 * of the file.
63 * ---------------------------------------------------------------------------
64 * Local variables:
65 * c-file-style: "linux"
66 * End:
67 */
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 715b0838a68c..3942a5f245de 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -67,6 +67,12 @@ SECTIONS
67 *(.stub .text.* .gnu.linkonce.t.*) 67 *(.stub .text.* .gnu.linkonce.t.*)
68 /* .gnu.warning sections are handled specially by elf32.em. */ 68 /* .gnu.warning sections are handled specially by elf32.em. */
69 *(.gnu.warning) 69 *(.gnu.warning)
70
71 . = ALIGN(4096);
72 __syscall_stub_start = .;
73 *(.__syscall_stub*)
74 __syscall_stub_end = .;
75 . = ALIGN(4096);
70 } =0x90909090 76 } =0x90909090
71 .fini : { 77 .fini : {
72 KEEP (*(.fini)) 78 KEEP (*(.fini))
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 420e6d51fa0f..a24e3b7f4bf0 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -353,6 +353,8 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
353 353
354#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) 354#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
355 355
356extern int __syscall_stub_start, __binary_start;
357
356void setup_physmem(unsigned long start, unsigned long reserve_end, 358void setup_physmem(unsigned long start, unsigned long reserve_end,
357 unsigned long len, unsigned long highmem) 359 unsigned long len, unsigned long highmem)
358{ 360{
@@ -371,6 +373,12 @@ void setup_physmem(unsigned long start, unsigned long reserve_end,
371 exit(1); 373 exit(1);
372 } 374 }
373 375
376 /* Special kludge - This page will be mapped in to userspace processes
377 * from physmem_fd, so it needs to be written out there.
378 */
379 os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
380 os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
381
374 bootmap_size = init_bootmem(pfn, pfn + delta); 382 bootmap_size = init_bootmem(pfn, pfn + delta);
375 free_bootmem(__pa(reserve_end) + bootmap_size, 383 free_bootmem(__pa(reserve_end) + bootmap_size,
376 len - bootmap_size - reserve); 384 len - bootmap_size - reserve);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 1b5ef3e96c71..c45a60e9c92d 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -32,6 +32,7 @@
32#include "uml-config.h" 32#include "uml-config.h"
33#include "choose-mode.h" 33#include "choose-mode.h"
34#include "mode.h" 34#include "mode.h"
35#include "tempfile.h"
35#ifdef UML_CONFIG_MODE_SKAS 36#ifdef UML_CONFIG_MODE_SKAS
36#include "skas.h" 37#include "skas.h"
37#include "skas_ptrace.h" 38#include "skas_ptrace.h"
@@ -358,11 +359,16 @@ void forward_pending_sigio(int target)
358 kill(target, SIGIO); 359 kill(target, SIGIO);
359} 360}
360 361
362int ptrace_faultinfo = 0;
363int proc_mm = 1;
364
365extern void *__syscall_stub_start, __syscall_stub_end;
366
361#ifdef UML_CONFIG_MODE_SKAS 367#ifdef UML_CONFIG_MODE_SKAS
362static inline int check_skas3_ptrace_support(void) 368static inline void check_skas3_ptrace_support(void)
363{ 369{
364 struct ptrace_faultinfo fi; 370 struct ptrace_faultinfo fi;
365 int pid, n, ret = 1; 371 int pid, n;
366 372
367 printf("Checking for the skas3 patch in the host..."); 373 printf("Checking for the skas3 patch in the host...");
368 pid = start_ptraced_child(); 374 pid = start_ptraced_child();
@@ -374,33 +380,31 @@ static inline int check_skas3_ptrace_support(void)
374 else { 380 else {
375 perror("not found"); 381 perror("not found");
376 } 382 }
377 ret = 0; 383 }
378 } else { 384 else {
385 ptrace_faultinfo = 1;
379 printf("found\n"); 386 printf("found\n");
380 } 387 }
381 388
382 init_registers(pid); 389 init_registers(pid);
383 stop_ptraced_child(pid, 1, 1); 390 stop_ptraced_child(pid, 1, 1);
384
385 return(ret);
386} 391}
387 392
388int can_do_skas(void) 393int can_do_skas(void)
389{ 394{
390 int ret = 1;
391
392 printf("Checking for /proc/mm..."); 395 printf("Checking for /proc/mm...");
393 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) { 396 if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
397 proc_mm = 0;
394 printf("not found\n"); 398 printf("not found\n");
395 ret = 0;
396 goto out; 399 goto out;
397 } else { 400 }
401 else {
398 printf("found\n"); 402 printf("found\n");
399 } 403 }
400 404
401 ret = check_skas3_ptrace_support();
402out: 405out:
403 return ret; 406 check_skas3_ptrace_support();
407 return 1;
404} 408}
405#else 409#else
406int can_do_skas(void) 410int can_do_skas(void)
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index ff69c4b312c0..d296d55ade4b 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -3,11 +3,14 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ 6obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
7 syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \ 7 syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \
8 8
9subdir- := util 9subdir- := util
10 10
11USER_OBJS := process.o 11USER_OBJS := process.o clone.o
12 12
13include arch/um/scripts/Makefile.rules 13include arch/um/scripts/Makefile.rules
14
15# clone.o is in the stub, so it can't be built with profiling
16$(obj)/clone.o : c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
new file mode 100644
index 000000000000..4dc55f10cd18
--- /dev/null
+++ b/arch/um/kernel/skas/clone.c
@@ -0,0 +1,44 @@
1#include <sched.h>
2#include <signal.h>
3#include <sys/mman.h>
4#include <sys/time.h>
5#include <asm/unistd.h>
6#include <asm/page.h>
7#include "ptrace_user.h"
8#include "skas.h"
9#include "stub-data.h"
10#include "uml-config.h"
11#include "sysdep/stub.h"
12
13/* This is in a separate file because it needs to be compiled with any
14 * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
15 */
16void __attribute__ ((__section__ (".__syscall_stub")))
17stub_clone_handler(void)
18{
19 long err;
20 struct stub_data *from = (struct stub_data *) UML_CONFIG_STUB_DATA;
21
22 err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
23 UML_CONFIG_STUB_DATA + PAGE_SIZE / 2 -
24 sizeof(void *));
25 if(err != 0)
26 goto out;
27
28 err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
29 if(err)
30 goto out;
31
32 err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
33 (long) &from->timer, 0);
34 if(err)
35 goto out;
36
37 err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, PAGE_SIZE,
38 PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED,
39 from->fd, from->offset);
40 out:
41 /* save current result. Parent: pid; child: retcode of mmap */
42 from->err = err;
43 trap_myself();
44}
diff --git a/arch/um/kernel/skas/exec_kern.c b/arch/um/kernel/skas/exec_kern.c
index c6b4d5dba789..77ed7bbab219 100644
--- a/arch/um/kernel/skas/exec_kern.c
+++ b/arch/um/kernel/skas/exec_kern.c
@@ -18,7 +18,7 @@
18void flush_thread_skas(void) 18void flush_thread_skas(void)
19{ 19{
20 force_flush_all(); 20 force_flush_all();
21 switch_mm_skas(current->mm->context.skas.mm_fd); 21 switch_mm_skas(&current->mm->context.skas.id);
22} 22}
23 23
24void start_thread_skas(struct pt_regs *regs, unsigned long eip, 24void start_thread_skas(struct pt_regs *regs, unsigned long eip,
diff --git a/arch/um/kernel/skas/include/mm_id.h b/arch/um/kernel/skas/include/mm_id.h
new file mode 100644
index 000000000000..48dd0989ddaa
--- /dev/null
+++ b/arch/um/kernel/skas/include/mm_id.h
@@ -0,0 +1,17 @@
1/*
2 * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MM_ID_H
7#define __MM_ID_H
8
9struct mm_id {
10 union {
11 int mm_fd;
12 int pid;
13 } u;
14 unsigned long stack;
15};
16
17#endif
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h
index 4cd60d7213f3..278b72f1d9ad 100644
--- a/arch/um/kernel/skas/include/mmu-skas.h
+++ b/arch/um/kernel/skas/include/mmu-skas.h
@@ -6,10 +6,15 @@
6#ifndef __SKAS_MMU_H 6#ifndef __SKAS_MMU_H
7#define __SKAS_MMU_H 7#define __SKAS_MMU_H
8 8
9#include "mm_id.h"
10
9struct mmu_context_skas { 11struct mmu_context_skas {
10 int mm_fd; 12 struct mm_id id;
13 unsigned long last_page_table;
11}; 14};
12 15
16extern void switch_mm_skas(struct mm_id * mm_idp);
17
13#endif 18#endif
14 19
15/* 20/*
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index 96b51dba3471..d983ea842547 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -6,9 +6,11 @@
6#ifndef __SKAS_H 6#ifndef __SKAS_H
7#define __SKAS_H 7#define __SKAS_H
8 8
9#include "mm_id.h"
9#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
10 11
11extern int userspace_pid[]; 12extern int userspace_pid[];
13extern int proc_mm, ptrace_faultinfo;
12 14
13extern void switch_threads(void *me, void *next); 15extern void switch_threads(void *me, void *next);
14extern void thread_wait(void *sw, void *fb); 16extern void thread_wait(void *sw, void *fb);
@@ -22,16 +24,18 @@ extern void new_thread_proc(void *stack, void (*handler)(int sig));
22extern void remove_sigstack(void); 24extern void remove_sigstack(void);
23extern void new_thread_handler(int sig); 25extern void new_thread_handler(int sig);
24extern void handle_syscall(union uml_pt_regs *regs); 26extern void handle_syscall(union uml_pt_regs *regs);
25extern void map(int fd, unsigned long virt, unsigned long len, int r, int w, 27extern int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
26 int x, int phys_fd, unsigned long long offset); 28 int r, int w, int x, int phys_fd, unsigned long long offset);
27extern int unmap(int fd, void *addr, unsigned long len); 29extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len);
28extern int protect(int fd, unsigned long addr, unsigned long len, 30extern int protect(struct mm_id * mm_idp, unsigned long addr,
29 int r, int w, int x); 31 unsigned long len, int r, int w, int x);
30extern void user_signal(int sig, union uml_pt_regs *regs, int pid); 32extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
31extern int new_mm(int from); 33extern int new_mm(int from);
32extern void start_userspace(int cpu); 34extern int start_userspace(unsigned long stub_stack);
35extern int copy_context_skas0(unsigned long stack, int pid);
33extern void get_skas_faultinfo(int pid, struct faultinfo * fi); 36extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
34extern long execute_syscall_skas(void *r); 37extern long execute_syscall_skas(void *r);
38extern unsigned long current_stub_stack(void);
35 39
36#endif 40#endif
37 41
diff --git a/arch/um/kernel/skas/include/stub-data.h b/arch/um/kernel/skas/include/stub-data.h
new file mode 100644
index 000000000000..f6ed92c3727d
--- /dev/null
+++ b/arch/um/kernel/skas/include/stub-data.h
@@ -0,0 +1,18 @@
1/*
2 * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __STUB_DATA_H
7#define __STUB_DATA_H
8
9#include <sys/time.h>
10
11struct stub_data {
12 long offset;
13 int fd;
14 struct itimerval timer;
15 long err;
16};
17
18#endif
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index 438db2f43456..147466d7ff4f 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -5,7 +5,9 @@
5 5
6#include "linux/config.h" 6#include "linux/config.h"
7#include "linux/mm.h" 7#include "linux/mm.h"
8#include "asm/pgtable.h"
8#include "mem_user.h" 9#include "mem_user.h"
10#include "skas.h"
9 11
10unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, 12unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
11 unsigned long *task_size_out) 13 unsigned long *task_size_out)
@@ -18,7 +20,9 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
18 *task_size_out = CONFIG_HOST_TASK_SIZE; 20 *task_size_out = CONFIG_HOST_TASK_SIZE;
19#else 21#else
20 *host_size_out = top; 22 *host_size_out = top;
21 *task_size_out = top; 23 if (proc_mm && ptrace_faultinfo)
24 *task_size_out = top;
25 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
22#endif 26#endif
23 return(((unsigned long) set_task_sizes_skas) & ~0xffffff); 27 return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
24} 28}
diff --git a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c
index 1310bf1e88d1..b0980ff3bd95 100644
--- a/arch/um/kernel/skas/mem_user.c
+++ b/arch/um/kernel/skas/mem_user.c
@@ -3,100 +3,171 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <signal.h>
6#include <errno.h> 7#include <errno.h>
7#include <sys/mman.h> 8#include <sys/mman.h>
9#include <sys/wait.h>
10#include <asm/page.h>
11#include <asm/unistd.h>
8#include "mem_user.h" 12#include "mem_user.h"
9#include "mem.h" 13#include "mem.h"
14#include "mm_id.h"
10#include "user.h" 15#include "user.h"
11#include "os.h" 16#include "os.h"
12#include "proc_mm.h" 17#include "proc_mm.h"
13 18#include "ptrace_user.h"
14void map(int fd, unsigned long virt, unsigned long len, int r, int w, 19#include "user_util.h"
15 int x, int phys_fd, unsigned long long offset) 20#include "kern_util.h"
21#include "task.h"
22#include "registers.h"
23#include "uml-config.h"
24#include "sysdep/ptrace.h"
25#include "sysdep/stub.h"
26#include "skas.h"
27
28extern unsigned long syscall_stub, __syscall_stub_start;
29
30extern void wait_stub_done(int pid, int sig, char * fname);
31
32static long run_syscall_stub(struct mm_id * mm_idp, int syscall,
33 unsigned long *args)
16{ 34{
17 struct proc_mm_op map; 35 int n, pid = mm_idp->u.pid;
18 int prot, n; 36 unsigned long regs[MAX_REG_NR];
19 37
20 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 38 get_safe_registers(regs);
21 (x ? PROT_EXEC : 0); 39 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
22 40 ((unsigned long) &syscall_stub -
23 map = ((struct proc_mm_op) { .op = MM_MMAP, 41 (unsigned long) &__syscall_stub_start);
24 .u = 42 /* XXX Don't have a define for starting a syscall */
25 { .mmap = 43 regs[REGS_SYSCALL_NR] = syscall;
26 { .addr = virt, 44 regs[REGS_SYSCALL_ARG1] = args[0];
27 .len = len, 45 regs[REGS_SYSCALL_ARG2] = args[1];
28 .prot = prot, 46 regs[REGS_SYSCALL_ARG3] = args[2];
29 .flags = MAP_SHARED | 47 regs[REGS_SYSCALL_ARG4] = args[3];
30 MAP_FIXED, 48 regs[REGS_SYSCALL_ARG5] = args[4];
31 .fd = phys_fd, 49 regs[REGS_SYSCALL_ARG6] = args[5];
32 .offset = offset 50 n = ptrace_setregs(pid, regs);
33 } } } ); 51 if(n < 0){
34 n = os_write_file(fd, &map, sizeof(map)); 52 printk("run_syscall_stub : PTRACE_SETREGS failed, "
35 if(n != sizeof(map)) 53 "errno = %d\n", n);
36 printk("map : /proc/mm map failed, err = %d\n", -n); 54 return(n);
55 }
56
57 wait_stub_done(pid, 0, "run_syscall_stub");
58
59 return(*((unsigned long *) mm_idp->stack));
37} 60}
38 61
39int unmap(int fd, void *addr, unsigned long len) 62int map(struct mm_id *mm_idp, unsigned long virt, unsigned long len,
63 int r, int w, int x, int phys_fd, unsigned long long offset)
40{ 64{
41 struct proc_mm_op unmap; 65 int prot, n;
42 int n; 66
43 67 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
44 unmap = ((struct proc_mm_op) { .op = MM_MUNMAP, 68 (x ? PROT_EXEC : 0);
45 .u = 69
46 { .munmap = 70 if(proc_mm){
47 { .addr = (unsigned long) addr, 71 struct proc_mm_op map;
48 .len = len } } } ); 72 int fd = mm_idp->u.mm_fd;
49 n = os_write_file(fd, &unmap, sizeof(unmap)); 73 map = ((struct proc_mm_op) { .op = MM_MMAP,
50 if(n != sizeof(unmap)) { 74 .u =
51 if(n < 0) 75 { .mmap =
52 return(n); 76 { .addr = virt,
53 else if(n > 0) 77 .len = len,
54 return(-EIO); 78 .prot = prot,
55 } 79 .flags = MAP_SHARED |
56 80 MAP_FIXED,
57 return(0); 81 .fd = phys_fd,
82 .offset= offset
83 } } } );
84 n = os_write_file(fd, &map, sizeof(map));
85 if(n != sizeof(map))
86 printk("map : /proc/mm map failed, err = %d\n", -n);
87 }
88 else {
89 long res;
90 unsigned long args[] = { virt, len, prot,
91 MAP_SHARED | MAP_FIXED, phys_fd,
92 MMAP_OFFSET(offset) };
93
94 res = run_syscall_stub(mm_idp, STUB_MMAP_NR, args);
95 if((void *) res == MAP_FAILED)
96 printk("mmap stub failed, errno = %d\n", res);
97 }
98
99 return 0;
58} 100}
59 101
60int protect(int fd, unsigned long addr, unsigned long len, int r, int w, 102int unmap(struct mm_id *mm_idp, void *addr, unsigned long len)
61 int x, int must_succeed)
62{ 103{
63 struct proc_mm_op protect; 104 int n;
64 int prot, n; 105
65 106 if(proc_mm){
66 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 107 struct proc_mm_op unmap;
67 (x ? PROT_EXEC : 0); 108 int fd = mm_idp->u.mm_fd;
68 109 unmap = ((struct proc_mm_op) { .op = MM_MUNMAP,
69 protect = ((struct proc_mm_op) { .op = MM_MPROTECT, 110 .u =
70 .u = 111 { .munmap =
71 { .mprotect = 112 { .addr =
72 { .addr = (unsigned long) addr, 113 (unsigned long) addr,
73 .len = len, 114 .len = len } } } );
74 .prot = prot } } } ); 115 n = os_write_file(fd, &unmap, sizeof(unmap));
75 116 if(n != sizeof(unmap)) {
76 n = os_write_file(fd, &protect, sizeof(protect)); 117 if(n < 0)
77 if(n != sizeof(protect)) { 118 return(n);
78 if(n == 0) return(0); 119 else if(n > 0)
79 120 return(-EIO);
80 if(must_succeed) 121 }
81 panic("protect failed, err = %d", -n); 122 }
82 123 else {
83 return(-EIO); 124 int res;
84 } 125 unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
126 0 };
127
128 res = run_syscall_stub(mm_idp, __NR_munmap, args);
129 if(res < 0)
130 printk("munmap stub failed, errno = %d\n", res);
131 }
132
133 return(0);
134}
85 135
86 return(0); 136int protect(struct mm_id *mm_idp, unsigned long addr, unsigned long len,
137 int r, int w, int x)
138{
139 struct proc_mm_op protect;
140 int prot, n;
141
142 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
143 (x ? PROT_EXEC : 0);
144
145 if(proc_mm){
146 int fd = mm_idp->u.mm_fd;
147 protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
148 .u =
149 { .mprotect =
150 { .addr =
151 (unsigned long) addr,
152 .len = len,
153 .prot = prot } } } );
154
155 n = os_write_file(fd, &protect, sizeof(protect));
156 if(n != sizeof(protect))
157 panic("protect failed, err = %d", -n);
158 }
159 else {
160 int res;
161 unsigned long args[] = { addr, len, prot, 0, 0, 0 };
162
163 res = run_syscall_stub(mm_idp, __NR_mprotect, args);
164 if(res < 0)
165 panic("mprotect stub failed, errno = %d\n", res);
166 }
167
168 return(0);
87} 169}
88 170
89void before_mem_skas(unsigned long unused) 171void before_mem_skas(unsigned long unused)
90{ 172{
91} 173}
92
93/*
94 * Overrides for Emacs so that we follow Linus's tabbing style.
95 * Emacs will notice this stuff at the end of the file and automatically
96 * adjust the settings for this buffer only. This must remain at the end
97 * of the file.
98 * ---------------------------------------------------------------------------
99 * Local variables:
100 * c-file-style: "linux"
101 * End:
102 */
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 6cb9a6d028a9..d232daa42c31 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -3,46 +3,143 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/config.h"
6#include "linux/sched.h" 7#include "linux/sched.h"
7#include "linux/list.h" 8#include "linux/list.h"
8#include "linux/spinlock.h" 9#include "linux/spinlock.h"
9#include "linux/slab.h" 10#include "linux/slab.h"
11#include "linux/errno.h"
12#include "linux/mm.h"
10#include "asm/current.h" 13#include "asm/current.h"
11#include "asm/segment.h" 14#include "asm/segment.h"
12#include "asm/mmu.h" 15#include "asm/mmu.h"
16#include "asm/pgalloc.h"
17#include "asm/pgtable.h"
13#include "os.h" 18#include "os.h"
14#include "skas.h" 19#include "skas.h"
15 20
21extern int __syscall_stub_start;
22
23static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
24 unsigned long kernel)
25{
26 pgd_t *pgd;
27 pud_t *pud;
28 pmd_t *pmd;
29 pte_t *pte;
30
31 spin_lock(&mm->page_table_lock);
32 pgd = pgd_offset(mm, proc);
33 pud = pud_alloc(mm, pgd, proc);
34 if (!pud)
35 goto out;
36
37 pmd = pmd_alloc(mm, pud, proc);
38 if (!pmd)
39 goto out_pmd;
40
41 pte = pte_alloc_map(mm, pmd, proc);
42 if (!pte)
43 goto out_pte;
44
45 /* There's an interaction between the skas0 stub pages, stack
46 * randomization, and the BUG at the end of exit_mmap. exit_mmap
47 * checks that the number of page tables freed is the same as had
48 * been allocated. If the stack is on the last page table page,
49 * then the stack pte page will be freed, and if not, it won't. To
50 * avoid having to know where the stack is, or if the process mapped
51 * something at the top of its address space for some other reason,
52 * we set TASK_SIZE to end at the start of the last page table.
53 * This keeps exit_mmap off the last page, but introduces a leak
54 * of that page. So, we hang onto it here and free it in
55 * destroy_context_skas.
56 */
57
58 mm->context.skas.last_page_table = pmd_page_kernel(*pmd);
59
60 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
61 *pte = pte_mkexec(*pte);
62 *pte = pte_wrprotect(*pte);
63 spin_unlock(&mm->page_table_lock);
64 return(0);
65
66 out_pmd:
67 pud_free(pud);
68 out_pte:
69 pmd_free(pmd);
70 out:
71 spin_unlock(&mm->page_table_lock);
72 return(-ENOMEM);
73}
74
16int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) 75int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
17{ 76{
18 int from; 77 struct mm_struct *cur_mm = current->mm;
78 struct mm_id *cur_mm_id = &cur_mm->context.skas.id;
79 struct mm_id *mm_id = &mm->context.skas.id;
80 unsigned long stack;
81 int from, ret;
19 82
20 if((current->mm != NULL) && (current->mm != &init_mm)) 83 if(proc_mm){
21 from = current->mm->context.skas.mm_fd; 84 if((cur_mm != NULL) && (cur_mm != &init_mm))
22 else from = -1; 85 from = cur_mm->context.skas.id.u.mm_fd;
86 else from = -1;
23 87
24 mm->context.skas.mm_fd = new_mm(from); 88 ret = new_mm(from);
25 if(mm->context.skas.mm_fd < 0){ 89 if(ret < 0){
26 printk("init_new_context_skas - new_mm failed, errno = %d\n", 90 printk("init_new_context_skas - new_mm failed, "
27 mm->context.skas.mm_fd); 91 "errno = %d\n", ret);
28 return(mm->context.skas.mm_fd); 92 return ret;
93 }
94 mm_id->u.mm_fd = ret;
29 } 95 }
96 else {
97 /* This zeros the entry that pgd_alloc didn't, needed since
98 * we are about to reinitialize it, and want mm.nr_ptes to
99 * be accurate.
100 */
101 mm->pgd[USER_PTRS_PER_PGD] = __pgd(0);
30 102
31 return(0); 103 ret = init_stub_pte(mm, CONFIG_STUB_CODE,
104 (unsigned long) &__syscall_stub_start);
105 if(ret)
106 goto out;
107
108 ret = -ENOMEM;
109 stack = get_zeroed_page(GFP_KERNEL);
110 if(stack == 0)
111 goto out;
112 mm_id->stack = stack;
113
114 ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack);
115 if(ret)
116 goto out_free;
117
118 mm->nr_ptes--;
119
120 if((cur_mm != NULL) && (cur_mm != &init_mm))
121 mm_id->u.pid = copy_context_skas0(stack,
122 cur_mm_id->u.pid);
123 else mm_id->u.pid = start_userspace(stack);
124 }
125
126 return 0;
127
128 out_free:
129 free_page(mm_id->stack);
130 out:
131 return ret;
32} 132}
33 133
34void destroy_context_skas(struct mm_struct *mm) 134void destroy_context_skas(struct mm_struct *mm)
35{ 135{
36 os_close_file(mm->context.skas.mm_fd); 136 struct mmu_context_skas *mmu = &mm->context.skas;
37}
38 137
39/* 138 if(proc_mm)
40 * Overrides for Emacs so that we follow Linus's tabbing style. 139 os_close_file(mmu->id.u.mm_fd);
41 * Emacs will notice this stuff at the end of the file and automatically 140 else {
42 * adjust the settings for this buffer only. This must remain at the end 141 os_kill_ptraced_process(mmu->id.u.pid, 1);
43 * of the file. 142 free_page(mmu->id.stack);
44 * --------------------------------------------------------------------------- 143 free_page(mmu->last_page_table);
45 * Local variables: 144 }
46 * c-file-style: "linux" 145}
47 * End:
48 */
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 773cd2b525fc..ba671dab8878 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -13,7 +13,9 @@
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include <sys/mman.h> 14#include <sys/mman.h>
15#include <sys/user.h> 15#include <sys/user.h>
16#include <sys/time.h>
16#include <asm/unistd.h> 17#include <asm/unistd.h>
18#include <asm/types.h>
17#include "user.h" 19#include "user.h"
18#include "ptrace_user.h" 20#include "ptrace_user.h"
19#include "time_user.h" 21#include "time_user.h"
@@ -21,13 +23,18 @@
21#include "user_util.h" 23#include "user_util.h"
22#include "kern_util.h" 24#include "kern_util.h"
23#include "skas.h" 25#include "skas.h"
26#include "stub-data.h"
27#include "mm_id.h"
24#include "sysdep/sigcontext.h" 28#include "sysdep/sigcontext.h"
29#include "sysdep/stub.h"
25#include "os.h" 30#include "os.h"
26#include "proc_mm.h" 31#include "proc_mm.h"
27#include "skas_ptrace.h" 32#include "skas_ptrace.h"
28#include "chan_user.h" 33#include "chan_user.h"
29#include "signal_user.h" 34#include "signal_user.h"
30#include "registers.h" 35#include "registers.h"
36#include "mem.h"
37#include "uml-config.h"
31#include "process.h" 38#include "process.h"
32 39
33int is_skas_winch(int pid, int fd, void *data) 40int is_skas_winch(int pid, int fd, void *data)
@@ -39,20 +46,55 @@ int is_skas_winch(int pid, int fd, void *data)
39 return(1); 46 return(1);
40} 47}
41 48
42void get_skas_faultinfo(int pid, struct faultinfo * fi) 49void wait_stub_done(int pid, int sig, char * fname)
43{ 50{
44 int err; 51 int n, status, err;
45 52
46 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); 53 do {
47 if(err) 54 if ( sig != -1 ) {
48 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " 55 err = ptrace(PTRACE_CONT, pid, 0, sig);
49 "errno = %d\n", errno); 56 if(err)
57 panic("%s : continue failed, errno = %d\n",
58 fname, errno);
59 }
60 sig = 0;
61
62 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
63 } while((n >= 0) && WIFSTOPPED(status) &&
64 (WSTOPSIG(status) == SIGVTALRM));
65
66 if((n < 0) || !WIFSTOPPED(status) ||
67 (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status != SIGTRAP))){
68 panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
69 "pid = %d, n = %d, errno = %d, status = 0x%x\n",
70 fname, pid, n, errno, status);
71 }
72}
50 73
51 /* Special handling for i386, which has different structs */ 74void get_skas_faultinfo(int pid, struct faultinfo * fi)
52 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) 75{
53 memset((char *)fi + sizeof(struct ptrace_faultinfo), 0, 76 int err;
54 sizeof(struct faultinfo) - 77
55 sizeof(struct ptrace_faultinfo)); 78 if(ptrace_faultinfo){
79 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
80 if(err)
81 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
82 "errno = %d\n", errno);
83
84 /* Special handling for i386, which has different structs */
85 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
86 memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
87 sizeof(struct faultinfo) -
88 sizeof(struct ptrace_faultinfo));
89 }
90 else {
91 wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
92
93 /* faultinfo is prepared by the stub-segv-handler at start of
94 * the stub stack page. We just have to copy it.
95 */
96 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
97 }
56} 98}
57 99
58static void handle_segv(int pid, union uml_pt_regs * regs) 100static void handle_segv(int pid, union uml_pt_regs * regs)
@@ -91,11 +133,56 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
91 handle_syscall(regs); 133 handle_syscall(regs);
92} 134}
93 135
94static int userspace_tramp(void *arg) 136extern int __syscall_stub_start;
137
138static int userspace_tramp(void *stack)
95{ 139{
96 init_new_thread_signals(0); 140 void *addr;
97 enable_timer(); 141
98 ptrace(PTRACE_TRACEME, 0, 0, 0); 142 ptrace(PTRACE_TRACEME, 0, 0, 0);
143
144 init_new_thread_signals(1);
145 enable_timer();
146
147 if(!proc_mm){
148 /* This has a pte, but it can't be mapped in with the usual
149 * tlb_flush mechanism because this is part of that mechanism
150 */
151 int fd;
152 __u64 offset;
153
154 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
155 addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
156 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
157 if(addr == MAP_FAILED){
158 printk("mapping mmap stub failed, errno = %d\n",
159 errno);
160 exit(1);
161 }
162
163 if(stack != NULL){
164 fd = phys_mapping(to_phys(stack), &offset);
165 addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
166 PROT_READ | PROT_WRITE,
167 MAP_FIXED | MAP_SHARED, fd, offset);
168 if(addr == MAP_FAILED){
169 printk("mapping segfault stack failed, "
170 "errno = %d\n", errno);
171 exit(1);
172 }
173 }
174 }
175 if(!ptrace_faultinfo && (stack != NULL)){
176 unsigned long v = UML_CONFIG_STUB_CODE +
177 (unsigned long) stub_segv_handler -
178 (unsigned long) &__syscall_stub_start;
179
180 set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
181 set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
182 SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
183 SIGUSR1, -1);
184 }
185
99 os_stop_process(os_getpid()); 186 os_stop_process(os_getpid());
100 return(0); 187 return(0);
101} 188}
@@ -105,11 +192,11 @@ static int userspace_tramp(void *arg)
105#define NR_CPUS 1 192#define NR_CPUS 1
106int userspace_pid[NR_CPUS]; 193int userspace_pid[NR_CPUS];
107 194
108void start_userspace(int cpu) 195int start_userspace(unsigned long stub_stack)
109{ 196{
110 void *stack; 197 void *stack;
111 unsigned long sp; 198 unsigned long sp;
112 int pid, status, n; 199 int pid, status, n, flags;
113 200
114 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, 201 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
115 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 202 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
@@ -117,8 +204,9 @@ void start_userspace(int cpu)
117 panic("start_userspace : mmap failed, errno = %d", errno); 204 panic("start_userspace : mmap failed, errno = %d", errno);
118 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); 205 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
119 206
120 pid = clone(userspace_tramp, (void *) sp, 207 flags = CLONE_FILES | SIGCHLD;
121 CLONE_FILES | CLONE_VM | SIGCHLD, NULL); 208 if(proc_mm) flags |= CLONE_VM;
209 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
122 if(pid < 0) 210 if(pid < 0)
123 panic("start_userspace : clone failed, errno = %d", errno); 211 panic("start_userspace : clone failed, errno = %d", errno);
124 212
@@ -140,7 +228,7 @@ void start_userspace(int cpu)
140 if(munmap(stack, PAGE_SIZE) < 0) 228 if(munmap(stack, PAGE_SIZE) < 0)
141 panic("start_userspace : munmap failed, errno = %d\n", errno); 229 panic("start_userspace : munmap failed, errno = %d\n", errno);
142 230
143 userspace_pid[cpu] = pid; 231 return(pid);
144} 232}
145 233
146void userspace(union uml_pt_regs *regs) 234void userspace(union uml_pt_regs *regs)
@@ -174,7 +262,9 @@ void userspace(union uml_pt_regs *regs)
174 if(WIFSTOPPED(status)){ 262 if(WIFSTOPPED(status)){
175 switch(WSTOPSIG(status)){ 263 switch(WSTOPSIG(status)){
176 case SIGSEGV: 264 case SIGSEGV:
177 handle_segv(pid, regs); 265 if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
266 user_signal(SIGSEGV, regs, pid);
267 else handle_segv(pid, regs);
178 break; 268 break;
179 case SIGTRAP + 0x80: 269 case SIGTRAP + 0x80:
180 handle_trap(pid, regs, local_using_sysemu); 270 handle_trap(pid, regs, local_using_sysemu);
@@ -194,6 +284,7 @@ void userspace(union uml_pt_regs *regs)
194 printk("userspace - child stopped with signal " 284 printk("userspace - child stopped with signal "
195 "%d\n", WSTOPSIG(status)); 285 "%d\n", WSTOPSIG(status));
196 } 286 }
287 pid = userspace_pid[0];
197 interrupt_end(); 288 interrupt_end();
198 289
199 /* Avoid -ERESTARTSYS handling in host */ 290 /* Avoid -ERESTARTSYS handling in host */
@@ -207,6 +298,67 @@ void userspace(union uml_pt_regs *regs)
207#define INIT_JMP_HALT 3 298#define INIT_JMP_HALT 3
208#define INIT_JMP_REBOOT 4 299#define INIT_JMP_REBOOT 4
209 300
301
302int copy_context_skas0(unsigned long new_stack, int pid)
303{
304 int err;
305 unsigned long regs[MAX_REG_NR];
306 unsigned long current_stack = current_stub_stack();
307 struct stub_data *data = (struct stub_data *) current_stack;
308 struct stub_data *child_data = (struct stub_data *) new_stack;
309 __u64 new_offset;
310 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
311
312 /* prepare offset and fd of child's stack as argument for parent's
313 * and child's mmap2 calls
314 */
315 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
316 .fd = new_fd,
317 .timer = ((struct itimerval)
318 { { 0, 1000000 / hz() },
319 { 0, 1000000 / hz() }})});
320 get_safe_registers(regs);
321
322 /* Set parent's instruction pointer to start of clone-stub */
323 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
324 (unsigned long) stub_clone_handler -
325 (unsigned long) &__syscall_stub_start;
326 regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
327 sizeof(void *);
328 err = ptrace_setregs(pid, regs);
329 if(err < 0)
330 panic("copy_context_skas0 : PTRACE_SETREGS failed, "
331 "pid = %d, errno = %d\n", pid, errno);
332
333 /* set a well known return code for detection of child write failure */
334 child_data->err = 12345678;
335
336 /* Wait, until parent has finished its work: read child's pid from
337 * parent's stack, and check, if bad result.
338 */
339 wait_stub_done(pid, 0, "copy_context_skas0");
340
341 pid = data->err;
342 if(pid < 0)
343 panic("copy_context_skas0 - stub-parent reports error %d\n",
344 pid);
345
346 /* Wait, until child has finished too: read child's result from
347 * child's stack and check it.
348 */
349 wait_stub_done(pid, -1, "copy_context_skas0");
350 if (child_data->err != UML_CONFIG_STUB_DATA)
351 panic("copy_context_skas0 - stub-child reports error %d\n",
352 child_data->err);
353
354 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
355 (void *)PTRACE_O_TRACESYSGOOD) < 0)
356 panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, "
357 "errno = %d\n", errno);
358
359 return pid;
360}
361
210void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, 362void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
211 void (*handler)(int)) 363 void (*handler)(int))
212{ 364{
@@ -334,21 +486,19 @@ void reboot_skas(void)
334 siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); 486 siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
335} 487}
336 488
337void switch_mm_skas(int mm_fd) 489void switch_mm_skas(struct mm_id *mm_idp)
338{ 490{
339 int err; 491 int err;
340 492
341#warning need cpu pid in switch_mm_skas 493#warning need cpu pid in switch_mm_skas
342 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd); 494 if(proc_mm){
343 if(err) 495 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
344 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n", 496 mm_idp->u.mm_fd);
345 errno); 497 if(err)
346} 498 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
347 499 "errno = %d\n", errno);
348void kill_off_processes_skas(void) 500 }
349{ 501 else userspace_pid[0] = mm_idp->u.pid;
350#warning need to loop over userspace_pids in kill_off_processes_skas
351 os_kill_ptraced_process(userspace_pid[0], 1);
352} 502}
353 503
354/* 504/*
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 0a7b8aa55db8..cbabab104ac3 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -175,9 +175,12 @@ static int start_kernel_proc(void *unused)
175 return(0); 175 return(0);
176} 176}
177 177
178extern int userspace_pid[];
179
178int start_uml_skas(void) 180int start_uml_skas(void)
179{ 181{
180 start_userspace(0); 182 if(proc_mm)
183 userspace_pid[0] = start_userspace(0);
181 184
182 init_new_thread_signals(1); 185 init_new_thread_signals(1);
183 186
@@ -199,3 +202,31 @@ int thread_pid_skas(struct task_struct *task)
199#warning Need to look up userspace_pid by cpu 202#warning Need to look up userspace_pid by cpu
200 return(userspace_pid[0]); 203 return(userspace_pid[0]);
201} 204}
205
206void kill_off_processes_skas(void)
207{
208 if(proc_mm)
209#warning need to loop over userspace_pids in kill_off_processes_skas
210 os_kill_ptraced_process(userspace_pid[0], 1);
211 else {
212 struct task_struct *p;
213 int pid, me;
214
215 me = os_getpid();
216 for_each_process(p){
217 if(p->mm == NULL)
218 continue;
219
220 pid = p->mm->context.skas.id.u.pid;
221 os_kill_ptraced_process(pid, 1);
222 }
223 }
224}
225
226unsigned long current_stub_stack(void)
227{
228 if(current->mm == NULL)
229 return(0);
230
231 return(current->mm->context.skas.id.stack);
232}
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
index b8c5e71763d1..6230999c672c 100644
--- a/arch/um/kernel/skas/tlb.c
+++ b/arch/um/kernel/skas/tlb.c
@@ -6,6 +6,7 @@
6 6
7#include "linux/stddef.h" 7#include "linux/stddef.h"
8#include "linux/sched.h" 8#include "linux/sched.h"
9#include "linux/config.h"
9#include "linux/mm.h" 10#include "linux/mm.h"
10#include "asm/page.h" 11#include "asm/page.h"
11#include "asm/pgtable.h" 12#include "asm/pgtable.h"
@@ -17,7 +18,7 @@
17#include "os.h" 18#include "os.h"
18#include "tlb.h" 19#include "tlb.h"
19 20
20static void do_ops(int fd, struct host_vm_op *ops, int last) 21static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last)
21{ 22{
22 struct host_vm_op *op; 23 struct host_vm_op *op;
23 int i; 24 int i;
@@ -26,18 +27,18 @@ static void do_ops(int fd, struct host_vm_op *ops, int last)
26 op = &ops[i]; 27 op = &ops[i];
27 switch(op->type){ 28 switch(op->type){
28 case MMAP: 29 case MMAP:
29 map(fd, op->u.mmap.addr, op->u.mmap.len, 30 map(&mmu->skas.id, op->u.mmap.addr, op->u.mmap.len,
30 op->u.mmap.r, op->u.mmap.w, op->u.mmap.x, 31 op->u.mmap.r, op->u.mmap.w, op->u.mmap.x,
31 op->u.mmap.fd, op->u.mmap.offset); 32 op->u.mmap.fd, op->u.mmap.offset);
32 break; 33 break;
33 case MUNMAP: 34 case MUNMAP:
34 unmap(fd, (void *) op->u.munmap.addr, 35 unmap(&mmu->skas.id, (void *) op->u.munmap.addr,
35 op->u.munmap.len); 36 op->u.munmap.len);
36 break; 37 break;
37 case MPROTECT: 38 case MPROTECT:
38 protect(fd, op->u.mprotect.addr, op->u.mprotect.len, 39 protect(&mmu->skas.id, op->u.mprotect.addr,
39 op->u.mprotect.r, op->u.mprotect.w, 40 op->u.mprotect.len, op->u.mprotect.r,
40 op->u.mprotect.x); 41 op->u.mprotect.w, op->u.mprotect.x);
41 break; 42 break;
42 default: 43 default:
43 printk("Unknown op type %d in do_ops\n", op->type); 44 printk("Unknown op type %d in do_ops\n", op->type);
@@ -46,12 +47,15 @@ static void do_ops(int fd, struct host_vm_op *ops, int last)
46 } 47 }
47} 48}
48 49
50extern int proc_mm;
51
49static void fix_range(struct mm_struct *mm, unsigned long start_addr, 52static void fix_range(struct mm_struct *mm, unsigned long start_addr,
50 unsigned long end_addr, int force) 53 unsigned long end_addr, int force)
51{ 54{
52 int fd = mm->context.skas.mm_fd; 55 if(!proc_mm && (end_addr > CONFIG_STUB_START))
56 end_addr = CONFIG_STUB_START;
53 57
54 fix_range_common(mm, start_addr, end_addr, force, fd, do_ops); 58 fix_range_common(mm, start_addr, end_addr, force, do_ops);
55} 59}
56 60
57void __flush_tlb_one_skas(unsigned long addr) 61void __flush_tlb_one_skas(unsigned long addr)
@@ -69,17 +73,20 @@ void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start,
69 73
70void flush_tlb_mm_skas(struct mm_struct *mm) 74void flush_tlb_mm_skas(struct mm_struct *mm)
71{ 75{
76 unsigned long end;
77
72 /* Don't bother flushing if this address space is about to be 78 /* Don't bother flushing if this address space is about to be
73 * destroyed. 79 * destroyed.
74 */ 80 */
75 if(atomic_read(&mm->mm_users) == 0) 81 if(atomic_read(&mm->mm_users) == 0)
76 return; 82 return;
77 83
78 fix_range(mm, 0, host_task_size, 0); 84 end = proc_mm ? task_size : CONFIG_STUB_START;
79 flush_tlb_kernel_range_common(start_vm, end_vm); 85 fix_range(mm, 0, end, 0);
80} 86}
81 87
82void force_flush_all_skas(void) 88void force_flush_all_skas(void)
83{ 89{
84 fix_range(current->mm, 0, host_task_size, 1); 90 unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
91 fix_range(current->mm, 0, end, 1);
85} 92}
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index f829b309b63c..c40b611e3d93 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -48,6 +48,13 @@ void enable_timer(void)
48 set_interval(ITIMER_VIRTUAL); 48 set_interval(ITIMER_VIRTUAL);
49} 49}
50 50
51void prepare_timer(void * ptr)
52{
53 int usec = 1000000/hz();
54 *(struct itimerval *)ptr = ((struct itimerval) { { 0, usec },
55 { 0, usec }});
56}
57
51void disable_timer(void) 58void disable_timer(void)
52{ 59{
53 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); 60 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index eda477edfdf5..83ec8d4747fd 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -18,13 +18,15 @@
18#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) 18#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
19 19
20void fix_range_common(struct mm_struct *mm, unsigned long start_addr, 20void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
21 unsigned long end_addr, int force, int data, 21 unsigned long end_addr, int force,
22 void (*do_ops)(int, struct host_vm_op *, int)) 22 void (*do_ops)(union mm_context *, struct host_vm_op *,
23 int))
23{ 24{
24 pgd_t *npgd; 25 pgd_t *npgd;
25 pud_t *npud; 26 pud_t *npud;
26 pmd_t *npmd; 27 pmd_t *npmd;
27 pte_t *npte; 28 pte_t *npte;
29 union mm_context *mmu = &mm->context;
28 unsigned long addr, end; 30 unsigned long addr, end;
29 int r, w, x; 31 int r, w, x;
30 struct host_vm_op ops[16]; 32 struct host_vm_op ops[16];
@@ -40,7 +42,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
40 end = end_addr; 42 end = end_addr;
41 if(force || pgd_newpage(*npgd)){ 43 if(force || pgd_newpage(*npgd)){
42 op_index = add_munmap(addr, end - addr, ops, 44 op_index = add_munmap(addr, end - addr, ops,
43 op_index, last_op, data, 45 op_index, last_op, mmu,
44 do_ops); 46 do_ops);
45 pgd_mkuptodate(*npgd); 47 pgd_mkuptodate(*npgd);
46 } 48 }
@@ -55,7 +57,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
55 end = end_addr; 57 end = end_addr;
56 if(force || pud_newpage(*npud)){ 58 if(force || pud_newpage(*npud)){
57 op_index = add_munmap(addr, end - addr, ops, 59 op_index = add_munmap(addr, end - addr, ops,
58 op_index, last_op, data, 60 op_index, last_op, mmu,
59 do_ops); 61 do_ops);
60 pud_mkuptodate(*npud); 62 pud_mkuptodate(*npud);
61 } 63 }
@@ -70,7 +72,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
70 end = end_addr; 72 end = end_addr;
71 if(force || pmd_newpage(*npmd)){ 73 if(force || pmd_newpage(*npmd)){
72 op_index = add_munmap(addr, end - addr, ops, 74 op_index = add_munmap(addr, end - addr, ops,
73 op_index, last_op, data, 75 op_index, last_op, mmu,
74 do_ops); 76 do_ops);
75 pmd_mkuptodate(*npmd); 77 pmd_mkuptodate(*npmd);
76 } 78 }
@@ -93,21 +95,21 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
93 op_index = add_mmap(addr, 95 op_index = add_mmap(addr,
94 pte_val(*npte) & PAGE_MASK, 96 pte_val(*npte) & PAGE_MASK,
95 PAGE_SIZE, r, w, x, ops, 97 PAGE_SIZE, r, w, x, ops,
96 op_index, last_op, data, 98 op_index, last_op, mmu,
97 do_ops); 99 do_ops);
98 else op_index = add_munmap(addr, PAGE_SIZE, ops, 100 else op_index = add_munmap(addr, PAGE_SIZE, ops,
99 op_index, last_op, data, 101 op_index, last_op, mmu,
100 do_ops); 102 do_ops);
101 } 103 }
102 else if(pte_newprot(*npte)) 104 else if(pte_newprot(*npte))
103 op_index = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, 105 op_index = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
104 op_index, last_op, data, 106 op_index, last_op, mmu,
105 do_ops); 107 do_ops);
106 108
107 *npte = pte_mkuptodate(*npte); 109 *npte = pte_mkuptodate(*npte);
108 addr += PAGE_SIZE; 110 addr += PAGE_SIZE;
109 } 111 }
110 (*do_ops)(data, ops, op_index); 112 (*do_ops)(mmu, ops, op_index);
111} 113}
112 114
113int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) 115int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
@@ -195,51 +197,6 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
195 return(updated); 197 return(updated);
196} 198}
197 199
198void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
199{
200 address &= PAGE_MASK;
201 flush_tlb_range(vma, address, address + PAGE_SIZE);
202}
203
204void flush_tlb_all(void)
205{
206 flush_tlb_mm(current->mm);
207}
208
209void flush_tlb_kernel_range(unsigned long start, unsigned long end)
210{
211 CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
212 flush_tlb_kernel_range_common, start, end);
213}
214
215void flush_tlb_kernel_vm(void)
216{
217 CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
218 flush_tlb_kernel_range_common(start_vm, end_vm));
219}
220
221void __flush_tlb_one(unsigned long addr)
222{
223 CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
224}
225
226void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
227 unsigned long end)
228{
229 CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
230 end);
231}
232
233void flush_tlb_mm(struct mm_struct *mm)
234{
235 CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
236}
237
238void force_flush_all(void)
239{
240 CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
241}
242
243pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) 200pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
244{ 201{
245 return(pgd_offset(mm, address)); 202 return(pgd_offset(mm, address));
@@ -270,9 +227,9 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr)
270} 227}
271 228
272int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, 229int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
273 int r, int w, int x, struct host_vm_op *ops, int index, 230 int r, int w, int x, struct host_vm_op *ops, int index,
274 int last_filled, int data, 231 int last_filled, union mm_context *mmu,
275 void (*do_ops)(int, struct host_vm_op *, int)) 232 void (*do_ops)(union mm_context *, struct host_vm_op *, int))
276{ 233{
277 __u64 offset; 234 __u64 offset;
278 struct host_vm_op *last; 235 struct host_vm_op *last;
@@ -292,7 +249,7 @@ int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
292 } 249 }
293 250
294 if(index == last_filled){ 251 if(index == last_filled){
295 (*do_ops)(data, ops, last_filled); 252 (*do_ops)(mmu, ops, last_filled);
296 index = -1; 253 index = -1;
297 } 254 }
298 255
@@ -310,8 +267,8 @@ int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
310} 267}
311 268
312int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops, 269int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
313 int index, int last_filled, int data, 270 int index, int last_filled, union mm_context *mmu,
314 void (*do_ops)(int, struct host_vm_op *, int)) 271 void (*do_ops)(union mm_context *, struct host_vm_op *, int))
315{ 272{
316 struct host_vm_op *last; 273 struct host_vm_op *last;
317 274
@@ -325,7 +282,7 @@ int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
325 } 282 }
326 283
327 if(index == last_filled){ 284 if(index == last_filled){
328 (*do_ops)(data, ops, last_filled); 285 (*do_ops)(mmu, ops, last_filled);
329 index = -1; 286 index = -1;
330 } 287 }
331 288
@@ -337,8 +294,9 @@ int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
337} 294}
338 295
339int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x, 296int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
340 struct host_vm_op *ops, int index, int last_filled, int data, 297 struct host_vm_op *ops, int index, int last_filled,
341 void (*do_ops)(int, struct host_vm_op *, int)) 298 union mm_context *mmu,
299 void (*do_ops)(union mm_context *, struct host_vm_op *, int))
342{ 300{
343 struct host_vm_op *last; 301 struct host_vm_op *last;
344 302
@@ -354,7 +312,7 @@ int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
354 } 312 }
355 313
356 if(index == last_filled){ 314 if(index == last_filled){
357 (*do_ops)(data, ops, last_filled); 315 (*do_ops)(mmu, ops, last_filled);
358 index = -1; 316 index = -1;
359 } 317 }
360 318
@@ -367,3 +325,49 @@ int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
367 .x = x } } }); 325 .x = x } } });
368 return(index); 326 return(index);
369} 327}
328
329void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
330{
331 address &= PAGE_MASK;
332 flush_tlb_range(vma, address, address + PAGE_SIZE);
333}
334
335void flush_tlb_all(void)
336{
337 flush_tlb_mm(current->mm);
338}
339
340void flush_tlb_kernel_range(unsigned long start, unsigned long end)
341{
342 CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
343 flush_tlb_kernel_range_common, start, end);
344}
345
346void flush_tlb_kernel_vm(void)
347{
348 CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
349 flush_tlb_kernel_range_common(start_vm, end_vm));
350}
351
352void __flush_tlb_one(unsigned long addr)
353{
354 CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
355}
356
357void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
358 unsigned long end)
359{
360 CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
361 end);
362}
363
364void flush_tlb_mm(struct mm_struct *mm)
365{
366 CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
367}
368
369void force_flush_all(void)
370{
371 CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
372}
373
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
index 203216ad86f1..2eefb43bc9c2 100644
--- a/arch/um/kernel/tt/tlb.c
+++ b/arch/um/kernel/tt/tlb.c
@@ -17,7 +17,7 @@
17#include "os.h" 17#include "os.h"
18#include "tlb.h" 18#include "tlb.h"
19 19
20static void do_ops(int unused, struct host_vm_op *ops, int last) 20static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last)
21{ 21{
22 struct host_vm_op *op; 22 struct host_vm_op *op;
23 int i; 23 int i;
@@ -55,7 +55,7 @@ static void fix_range(struct mm_struct *mm, unsigned long start_addr,
55 panic("fix_range fixing wrong address space, current = 0x%p", 55 panic("fix_range fixing wrong address space, current = 0x%p",
56 current); 56 current);
57 57
58 fix_range_common(mm, start_addr, end_addr, force, 0, do_ops); 58 fix_range_common(mm, start_addr, end_addr, force, do_ops);
59} 59}
60 60
61atomic_t vmchange_seq = ATOMIC_INIT(1); 61atomic_t vmchange_seq = ATOMIC_INIT(1);
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 61dfd4fef752..163476a8cb1b 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -30,6 +30,7 @@ SECTIONS
30 _einittext = .; 30 _einittext = .;
31 } 31 }
32 . = ALIGN(4096); 32 . = ALIGN(4096);
33
33 .text : 34 .text :
34 { 35 {
35 *(.text) 36 *(.text)
@@ -39,6 +40,12 @@ SECTIONS
39 /* .gnu.warning sections are handled specially by elf32.em. */ 40 /* .gnu.warning sections are handled specially by elf32.em. */
40 *(.gnu.warning) 41 *(.gnu.warning)
41 *(.gnu.linkonce.t*) 42 *(.gnu.linkonce.t*)
43
44 . = ALIGN(4096);
45 __syscall_stub_start = .;
46 *(.__syscall_stub*)
47 __syscall_stub_end = .;
48 . = ALIGN(4096);
42 } 49 }
43 50
44 #include "asm/common.lds.S" 51 #include "asm/common.lds.S"
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 9a0ad094d926..3125d320722c 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -121,6 +121,11 @@ void init_registers(int pid)
121 err); 121 err);
122} 122}
123 123
124void get_safe_registers(unsigned long *regs)
125{
126 memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
127}
128
124/* 129/*
125 * Overrides for Emacs so that we follow Linus's tabbing style. 130 * Overrides for Emacs so that we follow Linus's tabbing style.
126 * Emacs will notice this stuff at the end of the file and automatically 131 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 6286c974bbeb..44438d15c3d6 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -69,6 +69,11 @@ void init_registers(int pid)
69 err); 69 err);
70} 70}
71 71
72void get_safe_registers(unsigned long *regs)
73{
74 memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
75}
76
72/* 77/*
73 * Overrides for Emacs so that we follow Linus's tabbing style. 78 * Overrides for Emacs so that we follow Linus's tabbing style.
74 * Emacs will notice this stuff at the end of the file and automatically 79 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 7459d09c233e..17f305b6bade 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -16,6 +16,11 @@ define unprofile
16endef 16endef
17 17
18 18
19# The stubs and unmap.o can't try to call mcount or update basic block data
20define unprofile
21 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
22endef
23
19quiet_cmd_make_link = SYMLINK $@ 24quiet_cmd_make_link = SYMLINK $@
20cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ 25cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
21 26
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 095bcdb0b9cc..77c3c4d29f55 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,6 +1,6 @@
1obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 1obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ 2 ptrace_user.o semaphore.o signal.o sigcontext.o stub.o stub_segv.o \
3 sys_call_table.o 3 syscalls.o sysrq.o sys_call_table.o
4 4
5obj-$(CONFIG_HIGHMEM) += highmem.o 5obj-$(CONFIG_HIGHMEM) += highmem.o
6obj-$(CONFIG_MODULES) += module.o 6obj-$(CONFIG_MODULES) += module.o
@@ -16,6 +16,14 @@ semaphore.c-dir = kernel
16highmem.c-dir = mm 16highmem.c-dir = mm
17module.c-dir = kernel 17module.c-dir = kernel
18 18
19STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
20
21# _cflags works with kernel files, not with userspace ones, but c_flags does,
22# why ask why?
23$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS)
24
25$(obj)/stub.o : a_flags = $(STUB_CFLAGS)
26
19subdir- := util 27subdir- := util
20 28
21include arch/um/scripts/Makefile.unmap 29include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S
new file mode 100644
index 000000000000..2f2c70a8f043
--- /dev/null
+++ b/arch/um/sys-i386/stub.S
@@ -0,0 +1,8 @@
1#include "uml-config.h"
2
3 .globl syscall_stub
4.section .__syscall_stub, "x"
5syscall_stub:
6 int $0x80
7 mov %eax, UML_CONFIG_STUB_DATA
8 int3
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
new file mode 100644
index 000000000000..b251442ad0b1
--- /dev/null
+++ b/arch/um/sys-i386/stub_segv.c
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include <signal.h>
7#include <asm/sigcontext.h>
8#include <asm/unistd.h>
9#include "uml-config.h"
10#include "sysdep/sigcontext.h"
11#include "sysdep/faultinfo.h"
12
13void __attribute__ ((__section__ (".__syscall_stub")))
14stub_segv_handler(int sig)
15{
16 struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
17
18 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
19 sc);
20
21 __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid));
22 __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;"
23 "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1));
24 /* Pop the frame pointer and return address since we need to leave
25 * the stack in its original form when we do the sigreturn here, by
26 * hand.
27 */
28 __asm__("popl %%eax ; popl %%eax ; popl %%eax ; movl %0, %%eax ; "
29 "int $0x80" : : "g" (__NR_sigreturn));
30}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 2bc6f6849010..7488206ce6f4 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -6,8 +6,8 @@
6 6
7#XXX: why into lib-y? 7#XXX: why into lib-y?
8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ 8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
9 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ 9 ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o stub.o \
10 syscalls.o sysrq.o thunk.o syscall_table.o 10 stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
11 11
12obj-y := ksyms.o 12obj-y := ksyms.o
13obj-$(CONFIG_MODULES) += module.o um_module.o 13obj-$(CONFIG_MODULES) += module.o um_module.o
@@ -28,6 +28,14 @@ semaphore.c-dir = kernel
28thunk.S-dir = lib 28thunk.S-dir = lib
29module.c-dir = kernel 29module.c-dir = kernel
30 30
31STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
32
33# _cflags works with kernel files, not with userspace ones, but c_flags does,
34# why ask why?
35$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS)
36
37$(obj)/stub.o : a_flags = $(STUB_CFLAGS)
38
31subdir- := util 39subdir- := util
32 40
33include arch/um/scripts/Makefile.unmap 41include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S
new file mode 100644
index 000000000000..31c14925716b
--- /dev/null
+++ b/arch/um/sys-x86_64/stub.S
@@ -0,0 +1,15 @@
1#include "uml-config.h"
2
3 .globl syscall_stub
4.section .__syscall_stub, "x"
5syscall_stub:
6 syscall
7 /* We don't have 64-bit constants, so this constructs the address
8 * we need.
9 */
10 movq $(UML_CONFIG_STUB_DATA >> 32), %rbx
11 salq $32, %rbx
12 movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx
13 or %rcx, %rbx
14 movq %rax, (%rbx)
15 int3
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
new file mode 100644
index 000000000000..161d1fe9c034
--- /dev/null
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include <signal.h>
7#include <linux/compiler.h>
8#include <asm/unistd.h>
9#include "uml-config.h"
10#include "sysdep/sigcontext.h"
11#include "sysdep/faultinfo.h"
12
13void __attribute__ ((__section__ (".__syscall_stub")))
14stub_segv_handler(int sig)
15{
16 struct ucontext *uc;
17
18 __asm__("movq %%rdx, %0" : "=g" (uc) :);
19 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
20 &uc->uc_mcontext);
21
22 __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
23 __asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;"
24 "syscall": : "g" (__NR_kill), "g" (SIGUSR1));
25 /* Two popqs to restore the stack to the state just before entering
26 * the handler, one pops the return address, the other pops the frame
27 * pointer.
28 */
29 __asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g"
30 (__NR_rt_sigreturn));
31}
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index b02d921da4f7..5fd03225058a 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -1076,6 +1076,10 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
1076#ifdef CONFIG_X86_MCE 1076#ifdef CONFIG_X86_MCE
1077 mcheck_init(c); 1077 mcheck_init(c);
1078#endif 1078#endif
1079 if (c == &boot_cpu_data)
1080 mtrr_bp_init();
1081 else
1082 mtrr_ap_init();
1079#ifdef CONFIG_NUMA 1083#ifdef CONFIG_NUMA
1080 if (c != &boot_cpu_data) 1084 if (c != &boot_cpu_data)
1081 numa_add_cpu(c - cpu_data); 1085 numa_add_cpu(c - cpu_data);
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
index 6c0f402e3a88..0612640d91b1 100644
--- a/arch/x86_64/kernel/suspend.c
+++ b/arch/x86_64/kernel/suspend.c
@@ -119,6 +119,7 @@ void __restore_processor_state(struct saved_context *ctxt)
119 fix_processor_context(); 119 fix_processor_context();
120 120
121 do_fpu_end(); 121 do_fpu_end();
122 mtrr_ap_init();
122} 123}
123 124
124void restore_processor_state(void) 125void restore_processor_state(void)
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 73389f51c4e5..61c12758ca70 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -56,6 +56,10 @@ SECTIONS
56 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { 56 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
57 *(.data.cacheline_aligned) 57 *(.data.cacheline_aligned)
58 } 58 }
59 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
60 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
61 *(.data.read_mostly)
62 }
59 63
60#define VSYSCALL_ADDR (-10*1024*1024) 64#define VSYSCALL_ADDR (-10*1024*1024)
61#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) 65#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095))
diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c
index abc8ed6c7026..3540d8b119f3 100644
--- a/arch/xtensa/kernel/syscalls.c
+++ b/arch/xtensa/kernel/syscalls.c
@@ -46,8 +46,6 @@
46 46
47extern void do_syscall_trace(void); 47extern void do_syscall_trace(void);
48typedef int (*syscall_t)(void *a0,...); 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[]; 49extern syscall_t sys_call_table[];
52extern unsigned char sys_narg_table[]; 50extern unsigned char sys_narg_table[];
53 51
@@ -72,10 +70,8 @@ int sys_pipe(int __user *userfds)
72/* 70/*
73 * Common code for old and new mmaps. 71 * Common code for old and new mmaps.
74 */ 72 */
75 73long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
76static inline long do_mmap2(unsigned long addr, unsigned long len, 74 unsigned long flags, unsigned long fd, unsigned long pgoff)
77 unsigned long prot, unsigned long flags,
78 unsigned long fd, unsigned long pgoff)
79{ 75{
80 int error = -EBADF; 76 int error = -EBADF;
81 struct file * file = NULL; 77 struct file * file = NULL;
@@ -97,29 +93,6 @@ out:
97 return error; 93 return error;
98} 94}
99 95
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) 96int sys_clone(struct pt_regs *regs)
124{ 97{
125 unsigned long clone_flags; 98 unsigned long clone_flags;
@@ -162,30 +135,6 @@ int sys_uname(struct old_utsname * name)
162 return -EFAULT; 135 return -EFAULT;
163} 136}
164 137
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/* 138/*
190 * Build the string table for the builtin "poor man's strace". 139 * Build the string table for the builtin "poor man's strace".
191 */ 140 */
@@ -319,100 +268,3 @@ void system_call (struct pt_regs *regs)
319 regs->areg[2] = res; 268 regs->areg[2] = res;
320 do_syscall_trace(); 269 do_syscall_trace();
321} 270}
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
index 5b3f75f50feb..07580696b602 100644
--- a/arch/xtensa/kernel/syscalls.h
+++ b/arch/xtensa/kernel/syscalls.h
@@ -25,20 +25,19 @@
25 */ 25 */
26 26
27SYSCALL(0, 0) /* 00 */ 27SYSCALL(0, 0) /* 00 */
28
29SYSCALL(sys_exit, 1) 28SYSCALL(sys_exit, 1)
30SYSCALL(sys_fork, 0) 29SYSCALL(sys_ni_syscall, 0)
31SYSCALL(sys_read, 3) 30SYSCALL(sys_read, 3)
32SYSCALL(sys_write, 3) 31SYSCALL(sys_write, 3)
33SYSCALL(sys_open, 3) /* 05 */ 32SYSCALL(sys_open, 3) /* 05 */
34SYSCALL(sys_close, 1) 33SYSCALL(sys_close, 1)
35SYSCALL(sys_waitpid, 3) 34SYSCALL(sys_ni_syscall, 3)
36SYSCALL(sys_creat, 2) 35SYSCALL(sys_creat, 2)
37SYSCALL(sys_link, 2) 36SYSCALL(sys_link, 2)
38SYSCALL(sys_unlink, 1) /* 10 */ 37SYSCALL(sys_unlink, 1) /* 10 */
39SYSCALL(sys_execve, 0) 38SYSCALL(sys_execve, 0)
40SYSCALL(sys_chdir, 1) 39SYSCALL(sys_chdir, 1)
41SYSCALL(sys_time, 1) 40SYSCALL(sys_ni_syscall, 1)
42SYSCALL(sys_mknod, 3) 41SYSCALL(sys_mknod, 3)
43SYSCALL(sys_chmod, 2) /* 15 */ 42SYSCALL(sys_chmod, 2) /* 15 */
44SYSCALL(sys_lchown, 3) 43SYSCALL(sys_lchown, 3)
@@ -47,19 +46,19 @@ SYSCALL(sys_stat, 2)
47SYSCALL(sys_lseek, 3) 46SYSCALL(sys_lseek, 3)
48SYSCALL(sys_getpid, 0) /* 20 */ 47SYSCALL(sys_getpid, 0) /* 20 */
49SYSCALL(sys_mount, 5) 48SYSCALL(sys_mount, 5)
50SYSCALL(sys_oldumount, 1) 49SYSCALL(sys_ni_syscall, 1)
51SYSCALL(sys_setuid, 1) 50SYSCALL(sys_setuid, 1)
52SYSCALL(sys_getuid, 0) 51SYSCALL(sys_getuid, 0)
53SYSCALL(sys_stime, 1) /* 25 */ 52SYSCALL(sys_ni_syscall, 1) /* 25 */
54SYSCALL(sys_ptrace, 4) 53SYSCALL(sys_ptrace, 4)
55SYSCALL(sys_alarm, 1) 54SYSCALL(sys_ni_syscall, 1)
56SYSCALL(sys_fstat, 2) 55SYSCALL(sys_fstat, 2)
57SYSCALL(sys_pause, 0) 56SYSCALL(sys_ni_syscall, 0)
58SYSCALL(sys_utime, 2) /* 30 */ 57SYSCALL(sys_utime, 2) /* 30 */
59SYSCALL(sys_ni_syscall, 0) 58SYSCALL(sys_ni_syscall, 0)
60SYSCALL(sys_ni_syscall, 0) 59SYSCALL(sys_ni_syscall, 0)
61SYSCALL(sys_access, 2) 60SYSCALL(sys_access, 2)
62SYSCALL(sys_nice, 1) 61SYSCALL(sys_ni_syscall, 1)
63SYSCALL(sys_ni_syscall, 0) /* 35 */ 62SYSCALL(sys_ni_syscall, 0) /* 35 */
64SYSCALL(sys_sync, 0) 63SYSCALL(sys_sync, 0)
65SYSCALL(sys_kill, 2) 64SYSCALL(sys_kill, 2)
@@ -73,7 +72,7 @@ SYSCALL(sys_ni_syscall, 0)
73SYSCALL(sys_brk, 1) /* 45 */ 72SYSCALL(sys_brk, 1) /* 45 */
74SYSCALL(sys_setgid, 1) 73SYSCALL(sys_setgid, 1)
75SYSCALL(sys_getgid, 0) 74SYSCALL(sys_getgid, 0)
76SYSCALL(sys_ni_syscall, 0) /* was signal(2) */ 75SYSCALL(sys_ni_syscall, 0)
77SYSCALL(sys_geteuid, 0) 76SYSCALL(sys_geteuid, 0)
78SYSCALL(sys_getegid, 0) /* 50 */ 77SYSCALL(sys_getegid, 0) /* 50 */
79SYSCALL(sys_acct, 1) 78SYSCALL(sys_acct, 1)
@@ -84,21 +83,21 @@ SYSCALL(sys_fcntl, 3) /* 55 */
84SYSCALL(sys_ni_syscall, 2) 83SYSCALL(sys_ni_syscall, 2)
85SYSCALL(sys_setpgid, 2) 84SYSCALL(sys_setpgid, 2)
86SYSCALL(sys_ni_syscall, 0) 85SYSCALL(sys_ni_syscall, 0)
87SYSCALL(sys_olduname, 1) 86SYSCALL(sys_ni_syscall, 0)
88SYSCALL(sys_umask, 1) /* 60 */ 87SYSCALL(sys_umask, 1) /* 60 */
89SYSCALL(sys_chroot, 1) 88SYSCALL(sys_chroot, 1)
90SYSCALL(sys_ustat, 2) 89SYSCALL(sys_ustat, 2)
91SYSCALL(sys_dup2, 2) 90SYSCALL(sys_dup2, 2)
92SYSCALL(sys_getppid, 0) 91SYSCALL(sys_getppid, 0)
93SYSCALL(sys_getpgrp, 0) /* 65 */ 92SYSCALL(sys_ni_syscall, 0) /* 65 */
94SYSCALL(sys_setsid, 0) 93SYSCALL(sys_setsid, 0)
95SYSCALL(sys_sigaction, 3) 94SYSCALL(sys_sigaction, 3)
96SYSCALL(sys_sgetmask, 0) 95SYSCALL(sys_ni_syscall, 0)
97SYSCALL(sys_ssetmask, 1) 96SYSCALL(sys_ni_syscall, 1)
98SYSCALL(sys_setreuid, 2) /* 70 */ 97SYSCALL(sys_setreuid, 2) /* 70 */
99SYSCALL(sys_setregid, 2) 98SYSCALL(sys_setregid, 2)
100SYSCALL(sys_sigsuspend, 0) 99SYSCALL(sys_sigsuspend, 0)
101SYSCALL(sys_sigpending, 1) 100SYSCALL(sys_ni_syscall, 1)
102SYSCALL(sys_sethostname, 2) 101SYSCALL(sys_sethostname, 2)
103SYSCALL(sys_setrlimit, 2) /* 75 */ 102SYSCALL(sys_setrlimit, 2) /* 75 */
104SYSCALL(sys_getrlimit, 2) 103SYSCALL(sys_getrlimit, 2)
@@ -107,15 +106,15 @@ SYSCALL(sys_gettimeofday, 2)
107SYSCALL(sys_settimeofday, 2) 106SYSCALL(sys_settimeofday, 2)
108SYSCALL(sys_getgroups, 2) /* 80 */ 107SYSCALL(sys_getgroups, 2) /* 80 */
109SYSCALL(sys_setgroups, 2) 108SYSCALL(sys_setgroups, 2)
110SYSCALL(sys_ni_syscall, 0) /* old_select */ 109SYSCALL(sys_ni_syscall, 0)
111SYSCALL(sys_symlink, 2) 110SYSCALL(sys_symlink, 2)
112SYSCALL(sys_lstat, 2) 111SYSCALL(sys_lstat, 2)
113SYSCALL(sys_readlink, 3) /* 85 */ 112SYSCALL(sys_readlink, 3) /* 85 */
114SYSCALL(sys_uselib, 1) 113SYSCALL(sys_uselib, 1)
115SYSCALL(sys_swapon, 2) 114SYSCALL(sys_swapon, 2)
116SYSCALL(sys_reboot, 3) 115SYSCALL(sys_reboot, 3)
117SYSCALL(old_readdir, 3) 116SYSCALL(sys_ni_syscall, 3)
118SYSCALL(old_mmap, 6) /* 90 */ 117SYSCALL(sys_ni_syscall, 6) /* 90 */
119SYSCALL(sys_munmap, 2) 118SYSCALL(sys_munmap, 2)
120SYSCALL(sys_truncate, 2) 119SYSCALL(sys_truncate, 2)
121SYSCALL(sys_ftruncate, 2) 120SYSCALL(sys_ftruncate, 2)
@@ -127,7 +126,7 @@ SYSCALL(sys_ni_syscall, 0)
127SYSCALL(sys_statfs, 2) 126SYSCALL(sys_statfs, 2)
128SYSCALL(sys_fstatfs, 2) /* 100 */ 127SYSCALL(sys_fstatfs, 2) /* 100 */
129SYSCALL(sys_ni_syscall, 3) 128SYSCALL(sys_ni_syscall, 3)
130SYSCALL(sys_socketcall, 2) 129SYSCALL(sys_ni_syscall, 2)
131SYSCALL(sys_syslog, 3) 130SYSCALL(sys_syslog, 3)
132SYSCALL(sys_setitimer, 3) 131SYSCALL(sys_setitimer, 3)
133SYSCALL(sys_getitimer, 2) /* 105 */ 132SYSCALL(sys_getitimer, 2) /* 105 */
@@ -137,32 +136,32 @@ SYSCALL(sys_newfstat, 2)
137SYSCALL(sys_uname, 1) 136SYSCALL(sys_uname, 1)
138SYSCALL(sys_ni_syscall, 0) /* 110 */ 137SYSCALL(sys_ni_syscall, 0) /* 110 */
139SYSCALL(sys_vhangup, 0) 138SYSCALL(sys_vhangup, 0)
140SYSCALL(sys_ni_syscall, 0) /* was sys_idle() */ 139SYSCALL(sys_ni_syscall, 0)
141SYSCALL(sys_ni_syscall, 0) 140SYSCALL(sys_ni_syscall, 0)
142SYSCALL(sys_wait4, 4) 141SYSCALL(sys_wait4, 4)
143SYSCALL(sys_swapoff, 1) /* 115 */ 142SYSCALL(sys_swapoff, 1) /* 115 */
144SYSCALL(sys_sysinfo, 1) 143SYSCALL(sys_sysinfo, 1)
145SYSCALL(sys_ipc, 5) /* 6 really, but glibc uses only 5) */ 144SYSCALL(sys_ni_syscall, 0)
146SYSCALL(sys_fsync, 1) 145SYSCALL(sys_fsync, 1)
147SYSCALL(sys_sigreturn, 0) 146SYSCALL(sys_sigreturn, 0)
148SYSCALL(sys_clone, 0) /* 120 */ 147SYSCALL(sys_clone, 0) /* 120 */
149SYSCALL(sys_setdomainname, 2) 148SYSCALL(sys_setdomainname, 2)
150SYSCALL(sys_newuname, 1) 149SYSCALL(sys_newuname, 1)
151SYSCALL(sys_ni_syscall, 0) /* sys_modify_ldt */ 150SYSCALL(sys_ni_syscall, 0)
152SYSCALL(sys_adjtimex, 1) 151SYSCALL(sys_adjtimex, 1)
153SYSCALL(sys_mprotect, 3) /* 125 */ 152SYSCALL(sys_mprotect, 3) /* 125 */
154SYSCALL(sys_sigprocmask, 3) 153SYSCALL(sys_ni_syscall, 3)
155SYSCALL(sys_ni_syscall, 2) /* old sys_create_module */ 154SYSCALL(sys_ni_syscall, 2)
156SYSCALL(sys_init_module, 2) 155SYSCALL(sys_init_module, 2)
157SYSCALL(sys_delete_module, 1) 156SYSCALL(sys_delete_module, 1)
158SYSCALL(sys_ni_syscall, 1) /* old sys_get_kernel_sysm */ /* 130 */ 157SYSCALL(sys_ni_syscall, 1) /* 130 */
159SYSCALL(sys_quotactl, 0) 158SYSCALL(sys_quotactl, 0)
160SYSCALL(sys_getpgid, 1) 159SYSCALL(sys_getpgid, 1)
161SYSCALL(sys_fchdir, 1) 160SYSCALL(sys_fchdir, 1)
162SYSCALL(sys_bdflush, 2) 161SYSCALL(sys_bdflush, 2)
163SYSCALL(sys_sysfs, 3) /* 135 */ 162SYSCALL(sys_sysfs, 3) /* 135 */
164SYSCALL(sys_personality, 1) 163SYSCALL(sys_personality, 1)
165SYSCALL(sys_ni_syscall, 0) /* for afs_syscall */ 164SYSCALL(sys_ni_syscall, 0)
166SYSCALL(sys_setfsuid, 1) 165SYSCALL(sys_setfsuid, 1)
167SYSCALL(sys_setfsgid, 1) 166SYSCALL(sys_setfsgid, 1)
168SYSCALL(sys_llseek, 5) /* 140 */ 167SYSCALL(sys_llseek, 5) /* 140 */
@@ -212,7 +211,7 @@ SYSCALL(sys_socket, 3)
212SYSCALL(sys_socketpair, 4) 211SYSCALL(sys_socketpair, 4)
213SYSCALL(sys_setresuid, 3) /* 185 */ 212SYSCALL(sys_setresuid, 3) /* 185 */
214SYSCALL(sys_getresuid, 3) 213SYSCALL(sys_getresuid, 3)
215SYSCALL(sys_ni_syscall, 5) /* old sys_query_module */ 214SYSCALL(sys_ni_syscall, 5)
216SYSCALL(sys_poll, 3) 215SYSCALL(sys_poll, 3)
217SYSCALL(sys_nfsservctl, 3) 216SYSCALL(sys_nfsservctl, 3)
218SYSCALL(sys_setresgid, 3) /* 190 */ 217SYSCALL(sys_setresgid, 3) /* 190 */
@@ -235,7 +234,7 @@ SYSCALL(sys_sigaltstack, 0)
235SYSCALL(sys_sendfile, 4) 234SYSCALL(sys_sendfile, 4)
236SYSCALL(sys_ni_syscall, 0) 235SYSCALL(sys_ni_syscall, 0)
237SYSCALL(sys_ni_syscall, 0) 236SYSCALL(sys_ni_syscall, 0)
238SYSCALL(sys_mmap2, 6) /* 210 */ 237SYSCALL(sys_mmap, 6) /* 210 */
239SYSCALL(sys_truncate64, 2) 238SYSCALL(sys_truncate64, 2)
240SYSCALL(sys_ftruncate64, 2) 239SYSCALL(sys_ftruncate64, 2)
241SYSCALL(sys_stat64, 2) 240SYSCALL(sys_stat64, 2)
@@ -245,4 +244,4 @@ SYSCALL(sys_pivot_root, 2)
245SYSCALL(sys_mincore, 3) 244SYSCALL(sys_mincore, 3)
246SYSCALL(sys_madvise, 3) 245SYSCALL(sys_madvise, 3)
247SYSCALL(sys_getdents64, 3) 246SYSCALL(sys_getdents64, 3)
248SYSCALL(sys_vfork, 0) /* 220 */ 247SYSCALL(sys_ni_syscall, 0) /* 220 */
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 5ef9adb9fe73..bd2ec7e284cc 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -40,7 +40,6 @@
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <asm/io.h> 41#include <asm/io.h>
42 42
43#include <pcmcia/version.h>
44#include <pcmcia/cs_types.h> 43#include <pcmcia/cs_types.h>
45#include <pcmcia/cs.h> 44#include <pcmcia/cs.h>
46#include <pcmcia/cistpl.h> 45#include <pcmcia/cistpl.h>
@@ -895,11 +894,6 @@ static dev_link_t *bluecard_attach(void)
895 link->next = dev_list; 894 link->next = dev_list;
896 dev_list = link; 895 dev_list = link;
897 client_reg.dev_info = &dev_info; 896 client_reg.dev_info = &dev_info;
898 client_reg.EventMask =
899 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
900 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
901 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
902 client_reg.event_handler = &bluecard_event;
903 client_reg.Version = 0x0210; 897 client_reg.Version = 0x0210;
904 client_reg.event_callback_args.client_data = link; 898 client_reg.event_callback_args.client_data = link;
905 899
@@ -1103,6 +1097,7 @@ static struct pcmcia_driver bluecard_driver = {
1103 .name = "bluecard_cs", 1097 .name = "bluecard_cs",
1104 }, 1098 },
1105 .attach = bluecard_attach, 1099 .attach = bluecard_attach,
1100 .event = bluecard_event,
1106 .detach = bluecard_detach, 1101 .detach = bluecard_detach,
1107 .id_table = bluecard_ids, 1102 .id_table = bluecard_ids,
1108}; 1103};
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 9013cd759afb..adf1750ea58d 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -47,7 +47,6 @@
47#include <linux/device.h> 47#include <linux/device.h>
48#include <linux/firmware.h> 48#include <linux/firmware.h>
49 49
50#include <pcmcia/version.h>
51#include <pcmcia/cs_types.h> 50#include <pcmcia/cs_types.h>
52#include <pcmcia/cs.h> 51#include <pcmcia/cs.h>
53#include <pcmcia/cistpl.h> 52#include <pcmcia/cistpl.h>
@@ -696,11 +695,6 @@ static dev_link_t *bt3c_attach(void)
696 link->next = dev_list; 695 link->next = dev_list;
697 dev_list = link; 696 dev_list = link;
698 client_reg.dev_info = &dev_info; 697 client_reg.dev_info = &dev_info;
699 client_reg.EventMask =
700 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
701 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
702 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
703 client_reg.event_handler = &bt3c_event;
704 client_reg.Version = 0x0210; 698 client_reg.Version = 0x0210;
705 client_reg.event_callback_args.client_data = link; 699 client_reg.event_callback_args.client_data = link;
706 700
@@ -947,6 +941,7 @@ static struct pcmcia_driver bt3c_driver = {
947 .name = "bt3c_cs", 941 .name = "bt3c_cs",
948 }, 942 },
949 .attach = bt3c_attach, 943 .attach = bt3c_attach,
944 .event = bt3c_event,
950 .detach = bt3c_detach, 945 .detach = bt3c_detach,
951 .id_table = bt3c_ids, 946 .id_table = bt3c_ids,
952}; 947};
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index c479484a1f7f..e4c59fdc0e12 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -43,7 +43,6 @@
43#include <asm/system.h> 43#include <asm/system.h>
44#include <asm/io.h> 44#include <asm/io.h>
45 45
46#include <pcmcia/version.h>
47#include <pcmcia/cs_types.h> 46#include <pcmcia/cs_types.h>
48#include <pcmcia/cs.h> 47#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h> 48#include <pcmcia/cistpl.h>
@@ -615,11 +614,6 @@ static dev_link_t *btuart_attach(void)
615 link->next = dev_list; 614 link->next = dev_list;
616 dev_list = link; 615 dev_list = link;
617 client_reg.dev_info = &dev_info; 616 client_reg.dev_info = &dev_info;
618 client_reg.EventMask =
619 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
620 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
621 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
622 client_reg.event_handler = &btuart_event;
623 client_reg.Version = 0x0210; 617 client_reg.Version = 0x0210;
624 client_reg.event_callback_args.client_data = link; 618 client_reg.event_callback_args.client_data = link;
625 619
@@ -867,6 +861,7 @@ static struct pcmcia_driver btuart_driver = {
867 .name = "btuart_cs", 861 .name = "btuart_cs",
868 }, 862 },
869 .attach = btuart_attach, 863 .attach = btuart_attach,
864 .event = btuart_event,
870 .detach = btuart_detach, 865 .detach = btuart_detach,
871 .id_table = btuart_ids, 866 .id_table = btuart_ids,
872}; 867};
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index bb12f7daeb91..e39868c3da48 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -43,7 +43,6 @@
43#include <asm/system.h> 43#include <asm/system.h>
44#include <asm/io.h> 44#include <asm/io.h>
45 45
46#include <pcmcia/version.h>
47#include <pcmcia/cs_types.h> 46#include <pcmcia/cs_types.h>
48#include <pcmcia/cs.h> 47#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h> 48#include <pcmcia/cistpl.h>
@@ -594,11 +593,6 @@ static dev_link_t *dtl1_attach(void)
594 link->next = dev_list; 593 link->next = dev_list;
595 dev_list = link; 594 dev_list = link;
596 client_reg.dev_info = &dev_info; 595 client_reg.dev_info = &dev_info;
597 client_reg.EventMask =
598 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
599 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
600 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
601 client_reg.event_handler = &dtl1_event;
602 client_reg.Version = 0x0210; 596 client_reg.Version = 0x0210;
603 client_reg.event_callback_args.client_data = link; 597 client_reg.event_callback_args.client_data = link;
604 598
@@ -820,6 +814,7 @@ static struct pcmcia_driver dtl1_driver = {
820 .name = "dtl1_cs", 814 .name = "dtl1_cs",
821 }, 815 },
822 .attach = dtl1_attach, 816 .attach = dtl1_attach,
817 .event = dtl1_event,
823 .detach = dtl1_detach, 818 .detach = dtl1_detach,
824 .id_table = dtl1_ids, 819 .id_table = dtl1_ids,
825}; 820};
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 1aff819f3832..08f69287ea36 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o
40obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o 40obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
41obj-$(CONFIG_SX) += sx.o generic_serial.o 41obj-$(CONFIG_SX) += sx.o generic_serial.o
42obj-$(CONFIG_RIO) += rio/ generic_serial.o 42obj-$(CONFIG_RIO) += rio/ generic_serial.o
43obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvsi.o 43obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o
44obj-$(CONFIG_RAW_DRIVER) += raw.o 44obj-$(CONFIG_RAW_DRIVER) += raw.o
45obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o 45obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
46obj-$(CONFIG_MMTIMER) += mmtimer.o 46obj-$(CONFIG_MMTIMER) += mmtimer.o
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 88cd858f74d0..cddb789902db 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -22,6 +22,7 @@
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */ 23 */
24 24
25#include <linux/config.h>
25#include <linux/console.h> 26#include <linux/console.h>
26#include <linux/cpumask.h> 27#include <linux/cpumask.h>
27#include <linux/init.h> 28#include <linux/init.h>
@@ -40,7 +41,6 @@
40#include <linux/delay.h> 41#include <linux/delay.h>
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/hvconsole.h> 43#include <asm/hvconsole.h>
43#include <asm/vio.h>
44 44
45#define HVC_MAJOR 229 45#define HVC_MAJOR 229
46#define HVC_MINOR 0 46#define HVC_MINOR 0
@@ -61,16 +61,21 @@
61 */ 61 */
62#define HVC_ALLOC_TTY_ADAPTERS 8 62#define HVC_ALLOC_TTY_ADAPTERS 8
63 63
64static struct tty_driver *hvc_driver;
65#ifdef CONFIG_MAGIC_SYSRQ
66static int sysrq_pressed;
67#endif
68
69#define N_OUTBUF 16 64#define N_OUTBUF 16
70#define N_INBUF 16 65#define N_INBUF 16
71 66
72#define __ALIGNED__ __attribute__((__aligned__(8))) 67#define __ALIGNED__ __attribute__((__aligned__(8)))
73 68
69static struct tty_driver *hvc_driver;
70static struct task_struct *hvc_task;
71
72/* Picks up late kicks after list walk but before schedule() */
73static int hvc_kicked;
74
75#ifdef CONFIG_MAGIC_SYSRQ
76static int sysrq_pressed;
77#endif
78
74struct hvc_struct { 79struct hvc_struct {
75 spinlock_t lock; 80 spinlock_t lock;
76 int index; 81 int index;
@@ -80,11 +85,11 @@ struct hvc_struct {
80 char outbuf[N_OUTBUF] __ALIGNED__; 85 char outbuf[N_OUTBUF] __ALIGNED__;
81 int n_outbuf; 86 int n_outbuf;
82 uint32_t vtermno; 87 uint32_t vtermno;
88 struct hv_ops *ops;
83 int irq_requested; 89 int irq_requested;
84 int irq; 90 int irq;
85 struct list_head next; 91 struct list_head next;
86 struct kobject kobj; /* ref count & hvc_struct lifetime */ 92 struct kobject kobj; /* ref count & hvc_struct lifetime */
87 struct vio_dev *vdev;
88}; 93};
89 94
90/* dynamic list of hvc_struct instances */ 95/* dynamic list of hvc_struct instances */
@@ -97,26 +102,185 @@ static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs);
97static DEFINE_SPINLOCK(hvc_structs_lock); 102static DEFINE_SPINLOCK(hvc_structs_lock);
98 103
99/* 104/*
105 * This value is used to assign a tty->index value to a hvc_struct based
106 * upon order of exposure via hvc_probe(), when we can not match it to
107 * a console canidate registered with hvc_instantiate().
108 */
109static int last_hvc = -1;
110
111/*
112 * Do not call this function with either the hvc_strucst_lock or the hvc_struct
113 * lock held. If successful, this function increments the kobject reference
114 * count against the target hvc_struct so it should be released when finished.
115 */
116struct hvc_struct *hvc_get_by_index(int index)
117{
118 struct hvc_struct *hp;
119 unsigned long flags;
120
121 spin_lock(&hvc_structs_lock);
122
123 list_for_each_entry(hp, &hvc_structs, next) {
124 spin_lock_irqsave(&hp->lock, flags);
125 if (hp->index == index) {
126 kobject_get(&hp->kobj);
127 spin_unlock_irqrestore(&hp->lock, flags);
128 spin_unlock(&hvc_structs_lock);
129 return hp;
130 }
131 spin_unlock_irqrestore(&hp->lock, flags);
132 }
133 hp = NULL;
134
135 spin_unlock(&hvc_structs_lock);
136 return hp;
137}
138
139
140/*
100 * Initial console vtermnos for console API usage prior to full console 141 * Initial console vtermnos for console API usage prior to full console
101 * initialization. Any vty adapter outside this range will not have usable 142 * initialization. Any vty adapter outside this range will not have usable
102 * console interfaces but can still be used as a tty device. This has to be 143 * console interfaces but can still be used as a tty device. This has to be
103 * static because kmalloc will not work during early console init. 144 * static because kmalloc will not work during early console init.
104 */ 145 */
105static uint32_t vtermnos[MAX_NR_HVC_CONSOLES]; 146static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
147static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
148 {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
106 149
107/* Used for accounting purposes */ 150/*
108static int num_vterms = 0; 151 * Console APIs, NOT TTY. These APIs are available immediately when
152 * hvc_console_setup() finds adapters.
153 */
109 154
110static struct task_struct *hvc_task; 155void hvc_console_print(struct console *co, const char *b, unsigned count)
156{
157 char c[16] __ALIGNED__;
158 unsigned i = 0, n = 0;
159 int r, donecr = 0, index = co->index;
160
161 /* Console access attempt outside of acceptable console range. */
162 if (index >= MAX_NR_HVC_CONSOLES)
163 return;
164
165 /* This console adapter was removed so it is not useable. */
166 if (vtermnos[index] < 0)
167 return;
168
169 while (count > 0 || i > 0) {
170 if (count > 0 && i < sizeof(c)) {
171 if (b[n] == '\n' && !donecr) {
172 c[i++] = '\r';
173 donecr = 1;
174 } else {
175 c[i++] = b[n++];
176 donecr = 0;
177 --count;
178 }
179 } else {
180 r = cons_ops[index]->put_chars(vtermnos[index], c, i);
181 if (r < 0) {
182 /* throw away chars on error */
183 i = 0;
184 } else if (r > 0) {
185 i -= r;
186 if (i > 0)
187 memmove(c, c+r, i);
188 }
189 }
190 }
191}
192
193static struct tty_driver *hvc_console_device(struct console *c, int *index)
194{
195 if (vtermnos[c->index] == -1)
196 return NULL;
197
198 *index = c->index;
199 return hvc_driver;
200}
201
202static int __init hvc_console_setup(struct console *co, char *options)
203{
204 if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
205 return -ENODEV;
206
207 if (vtermnos[co->index] == -1)
208 return -ENODEV;
209
210 return 0;
211}
212
213struct console hvc_con_driver = {
214 .name = "hvc",
215 .write = hvc_console_print,
216 .device = hvc_console_device,
217 .setup = hvc_console_setup,
218 .flags = CON_PRINTBUFFER,
219 .index = -1,
220};
111 221
112/* 222/*
113 * This value is used to associate a tty->index value to a hvc_struct based 223 * Early console initialization. Preceeds driver initialization.
114 * upon order of exposure via hvc_probe(). 224 *
225 * (1) we are first, and the user specified another driver
226 * -- index will remain -1
227 * (2) we are first and the user specified no driver
228 * -- index will be set to 0, then we will fail setup.
229 * (3) we are first and the user specified our driver
230 * -- index will be set to user specified driver, and we will fail
231 * (4) we are after driver, and this initcall will register us
232 * -- if the user didn't specify a driver then the console will match
233 *
234 * Note that for cases 2 and 3, we will match later when the io driver
235 * calls hvc_instantiate() and call register again.
115 */ 236 */
116static int hvc_count = -1; 237static int __init hvc_console_init(void)
238{
239 register_console(&hvc_con_driver);
240 return 0;
241}
242console_initcall(hvc_console_init);
117 243
118/* Picks up late kicks after list walk but before schedule() */ 244/*
119static int hvc_kicked; 245 * hvc_instantiate() is an early console discovery method which locates
246 * consoles * prior to the vio subsystem discovering them. Hotplugged
247 * vty adapters do NOT get an hvc_instantiate() callback since they
248 * appear after early console init.
249 */
250int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
251{
252 struct hvc_struct *hp;
253
254 if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
255 return -1;
256
257 if (vtermnos[index] != -1)
258 return -1;
259
260 /* make sure no no tty has been registerd in this index */
261 hp = hvc_get_by_index(index);
262 if (hp) {
263 kobject_put(&hp->kobj);
264 return -1;
265 }
266
267 vtermnos[index] = vtermno;
268 cons_ops[index] = ops;
269
270 /* reserve all indices upto and including this index */
271 if (last_hvc < index)
272 last_hvc = index;
273
274 /* if this index is what the user requested, then register
275 * now (setup won't fail at this point). It's ok to just
276 * call register again if previously .setup failed.
277 */
278 if (index == hvc_con_driver.index)
279 register_console(&hvc_con_driver);
280
281 return 0;
282}
283EXPORT_SYMBOL(hvc_instantiate);
120 284
121/* Wake the sleeping khvcd */ 285/* Wake the sleeping khvcd */
122static void hvc_kick(void) 286static void hvc_kick(void)
@@ -125,13 +289,17 @@ static void hvc_kick(void)
125 wake_up_process(hvc_task); 289 wake_up_process(hvc_task);
126} 290}
127 291
292static int hvc_poll(struct hvc_struct *hp);
293
128/* 294/*
129 * NOTE: This API isn't used if the console adapter doesn't support interrupts. 295 * NOTE: This API isn't used if the console adapter doesn't support interrupts.
130 * In this case the console is poll driven. 296 * In this case the console is poll driven.
131 */ 297 */
132static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs) 298static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
133{ 299{
134 hvc_kick(); 300 /* if hvc_poll request a repoll, then kick the hvcd thread */
301 if (hvc_poll(dev_instance))
302 hvc_kick();
135 return IRQ_HANDLED; 303 return IRQ_HANDLED;
136} 304}
137 305
@@ -141,34 +309,6 @@ static void hvc_unthrottle(struct tty_struct *tty)
141} 309}
142 310
143/* 311/*
144 * Do not call this function with either the hvc_strucst_lock or the hvc_struct
145 * lock held. If successful, this function increments the kobject reference
146 * count against the target hvc_struct so it should be released when finished.
147 */
148struct hvc_struct *hvc_get_by_index(int index)
149{
150 struct hvc_struct *hp;
151 unsigned long flags;
152
153 spin_lock(&hvc_structs_lock);
154
155 list_for_each_entry(hp, &hvc_structs, next) {
156 spin_lock_irqsave(&hp->lock, flags);
157 if (hp->index == index) {
158 kobject_get(&hp->kobj);
159 spin_unlock_irqrestore(&hp->lock, flags);
160 spin_unlock(&hvc_structs_lock);
161 return hp;
162 }
163 spin_unlock_irqrestore(&hp->lock, flags);
164 }
165 hp = NULL;
166
167 spin_unlock(&hvc_structs_lock);
168 return hp;
169}
170
171/*
172 * The TTY interface won't be used until after the vio layer has exposed the vty 312 * The TTY interface won't be used until after the vio layer has exposed the vty
173 * adapter to the kernel. 313 * adapter to the kernel.
174 */ 314 */
@@ -329,7 +469,7 @@ static void hvc_push(struct hvc_struct *hp)
329{ 469{
330 int n; 470 int n;
331 471
332 n = hvc_put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); 472 n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
333 if (n <= 0) { 473 if (n <= 0) {
334 if (n == 0) 474 if (n == 0)
335 return; 475 return;
@@ -467,7 +607,7 @@ static int hvc_poll(struct hvc_struct *hp)
467 break; 607 break;
468 } 608 }
469 609
470 n = hvc_get_chars(hp->vtermno, buf, count); 610 n = hp->ops->get_chars(hp->vtermno, buf, count);
471 if (n <= 0) { 611 if (n <= 0) {
472 /* Hangup the tty when disconnected from host */ 612 /* Hangup the tty when disconnected from host */
473 if (n == -EPIPE) { 613 if (n == -EPIPE) {
@@ -479,14 +619,17 @@ static int hvc_poll(struct hvc_struct *hp)
479 } 619 }
480 for (i = 0; i < n; ++i) { 620 for (i = 0; i < n; ++i) {
481#ifdef CONFIG_MAGIC_SYSRQ 621#ifdef CONFIG_MAGIC_SYSRQ
482 /* Handle the SysRq Hack */ 622 if (hp->index == hvc_con_driver.index) {
483 if (buf[i] == '\x0f') { /* ^O -- should support a sequence */ 623 /* Handle the SysRq Hack */
484 sysrq_pressed = 1; 624 /* XXX should support a sequence */
485 continue; 625 if (buf[i] == '\x0f') { /* ^O */
486 } else if (sysrq_pressed) { 626 sysrq_pressed = 1;
487 handle_sysrq(buf[i], NULL, tty); 627 continue;
488 sysrq_pressed = 0; 628 } else if (sysrq_pressed) {
489 continue; 629 handle_sysrq(buf[i], NULL, tty);
630 sysrq_pressed = 0;
631 continue;
632 }
490 } 633 }
491#endif /* CONFIG_MAGIC_SYSRQ */ 634#endif /* CONFIG_MAGIC_SYSRQ */
492 tty_insert_flip_char(tty, buf[i], 0); 635 tty_insert_flip_char(tty, buf[i], 0);
@@ -497,8 +640,8 @@ static int hvc_poll(struct hvc_struct *hp)
497 640
498 /* 641 /*
499 * Account for the total amount read in one loop, and if above 642 * Account for the total amount read in one loop, and if above
500 * 64 bytes, we do a quick schedule loop to let the tty grok the 643 * 64 bytes, we do a quick schedule loop to let the tty grok
501 * data and eventually throttle us. 644 * the data and eventually throttle us.
502 */ 645 */
503 read_total += n; 646 read_total += n;
504 if (read_total >= 64) { 647 if (read_total >= 64) {
@@ -542,7 +685,6 @@ int khvcd(void *unused)
542 if (cpus_empty(cpus_in_xmon)) { 685 if (cpus_empty(cpus_in_xmon)) {
543 spin_lock(&hvc_structs_lock); 686 spin_lock(&hvc_structs_lock);
544 list_for_each_entry(hp, &hvc_structs, next) { 687 list_for_each_entry(hp, &hvc_structs, next) {
545 /*hp = list_entry(node, struct hvc_struct, * next); */
546 poll_mask |= hvc_poll(hp); 688 poll_mask |= hvc_poll(hp);
547 } 689 }
548 spin_unlock(&hvc_structs_lock); 690 spin_unlock(&hvc_structs_lock);
@@ -577,14 +719,6 @@ static struct tty_operations hvc_ops = {
577 .chars_in_buffer = hvc_chars_in_buffer, 719 .chars_in_buffer = hvc_chars_in_buffer,
578}; 720};
579 721
580char hvc_driver_name[] = "hvc_console";
581
582static struct vio_device_id hvc_driver_table[] __devinitdata= {
583 {"serial", "hvterm1"},
584 { NULL, }
585};
586MODULE_DEVICE_TABLE(vio, hvc_driver_table);
587
588/* callback when the kboject ref count reaches zero. */ 722/* callback when the kboject ref count reaches zero. */
589static void destroy_hvc_struct(struct kobject *kobj) 723static void destroy_hvc_struct(struct kobject *kobj)
590{ 724{
@@ -606,41 +740,51 @@ static struct kobj_type hvc_kobj_type = {
606 .release = destroy_hvc_struct, 740 .release = destroy_hvc_struct,
607}; 741};
608 742
609static int __devinit hvc_probe( 743struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
610 struct vio_dev *dev, 744 struct hv_ops *ops)
611 const struct vio_device_id *id)
612{ 745{
613 struct hvc_struct *hp; 746 struct hvc_struct *hp;
614 747 int i;
615 /* probed with invalid parameters. */
616 if (!dev || !id)
617 return -EPERM;
618 748
619 hp = kmalloc(sizeof(*hp), GFP_KERNEL); 749 hp = kmalloc(sizeof(*hp), GFP_KERNEL);
620 if (!hp) 750 if (!hp)
621 return -ENOMEM; 751 return ERR_PTR(-ENOMEM);
622 752
623 memset(hp, 0x00, sizeof(*hp)); 753 memset(hp, 0x00, sizeof(*hp));
624 hp->vtermno = dev->unit_address; 754
625 hp->vdev = dev; 755 hp->vtermno = vtermno;
626 hp->vdev->dev.driver_data = hp; 756 hp->irq = irq;
627 hp->irq = dev->irq; 757 hp->ops = ops;
628 758
629 kobject_init(&hp->kobj); 759 kobject_init(&hp->kobj);
630 hp->kobj.ktype = &hvc_kobj_type; 760 hp->kobj.ktype = &hvc_kobj_type;
631 761
632 spin_lock_init(&hp->lock); 762 spin_lock_init(&hp->lock);
633 spin_lock(&hvc_structs_lock); 763 spin_lock(&hvc_structs_lock);
634 hp->index = ++hvc_count; 764
765 /*
766 * find index to use:
767 * see if this vterm id matches one registered for console.
768 */
769 for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
770 if (vtermnos[i] == hp->vtermno)
771 break;
772
773 /* no matching slot, just use a counter */
774 if (i >= MAX_NR_HVC_CONSOLES)
775 i = ++last_hvc;
776
777 hp->index = i;
778
635 list_add_tail(&(hp->next), &hvc_structs); 779 list_add_tail(&(hp->next), &hvc_structs);
636 spin_unlock(&hvc_structs_lock); 780 spin_unlock(&hvc_structs_lock);
637 781
638 return 0; 782 return hp;
639} 783}
784EXPORT_SYMBOL(hvc_alloc);
640 785
641static int __devexit hvc_remove(struct vio_dev *dev) 786int __devexit hvc_remove(struct hvc_struct *hp)
642{ 787{
643 struct hvc_struct *hp = dev->dev.driver_data;
644 unsigned long flags; 788 unsigned long flags;
645 struct kobject *kobjp; 789 struct kobject *kobjp;
646 struct tty_struct *tty; 790 struct tty_struct *tty;
@@ -673,23 +817,14 @@ static int __devexit hvc_remove(struct vio_dev *dev)
673 tty_hangup(tty); 817 tty_hangup(tty);
674 return 0; 818 return 0;
675} 819}
676 820EXPORT_SYMBOL(hvc_remove);
677static struct vio_driver hvc_vio_driver = {
678 .name = hvc_driver_name,
679 .id_table = hvc_driver_table,
680 .probe = hvc_probe,
681 .remove = hvc_remove,
682};
683 821
684/* Driver initialization. Follow console initialization. This is where the TTY 822/* Driver initialization. Follow console initialization. This is where the TTY
685 * interfaces start to become available. */ 823 * interfaces start to become available. */
686int __init hvc_init(void) 824int __init hvc_init(void)
687{ 825{
688 int rc; 826 /* We need more than hvc_count adapters due to hotplug additions. */
689
690 /* We need more than num_vterms adapters due to hotplug additions. */
691 hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); 827 hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
692 /* hvc_driver = alloc_tty_driver(num_vterms); */
693 if (!hvc_driver) 828 if (!hvc_driver)
694 return -ENOMEM; 829 return -ENOMEM;
695 830
@@ -716,116 +851,20 @@ int __init hvc_init(void)
716 return -EIO; 851 return -EIO;
717 } 852 }
718 853
719 /* Register as a vio device to receive callbacks */ 854 return 0;
720 rc = vio_register_driver(&hvc_vio_driver);
721
722 return rc;
723} 855}
856module_init(hvc_init);
724 857
725/* This isn't particularily necessary due to this being a console driver but it 858/* This isn't particularily necessary due to this being a console driver
726 * is nice to be thorough */ 859 * but it is nice to be thorough.
860 */
727static void __exit hvc_exit(void) 861static void __exit hvc_exit(void)
728{ 862{
729 kthread_stop(hvc_task); 863 kthread_stop(hvc_task);
730 864
731 vio_unregister_driver(&hvc_vio_driver);
732 tty_unregister_driver(hvc_driver); 865 tty_unregister_driver(hvc_driver);
733 /* return tty_struct instances allocated in hvc_init(). */ 866 /* return tty_struct instances allocated in hvc_init(). */
734 put_tty_driver(hvc_driver); 867 put_tty_driver(hvc_driver);
868 unregister_console(&hvc_con_driver);
735} 869}
736
737/*
738 * Console APIs, NOT TTY. These APIs are available immediately when
739 * hvc_console_setup() finds adapters.
740 */
741
742/*
743 * hvc_instantiate() is an early console discovery method which locates consoles
744 * prior to the vio subsystem discovering them. Hotplugged vty adapters do NOT
745 * get an hvc_instantiate() callback since the appear after early console init.
746 */
747int hvc_instantiate(uint32_t vtermno, int index)
748{
749 if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
750 return -1;
751
752 if (vtermnos[index] != -1)
753 return -1;
754
755 vtermnos[index] = vtermno;
756 return 0;
757}
758
759void hvc_console_print(struct console *co, const char *b, unsigned count)
760{
761 char c[16] __ALIGNED__;
762 unsigned i = 0, n = 0;
763 int r, donecr = 0;
764
765 /* Console access attempt outside of acceptable console range. */
766 if (co->index >= MAX_NR_HVC_CONSOLES)
767 return;
768
769 /* This console adapter was removed so it is not useable. */
770 if (vtermnos[co->index] < 0)
771 return;
772
773 while (count > 0 || i > 0) {
774 if (count > 0 && i < sizeof(c)) {
775 if (b[n] == '\n' && !donecr) {
776 c[i++] = '\r';
777 donecr = 1;
778 } else {
779 c[i++] = b[n++];
780 donecr = 0;
781 --count;
782 }
783 } else {
784 r = hvc_put_chars(vtermnos[co->index], c, i);
785 if (r < 0) {
786 /* throw away chars on error */
787 i = 0;
788 } else if (r > 0) {
789 i -= r;
790 if (i > 0)
791 memmove(c, c+r, i);
792 }
793 }
794 }
795}
796
797static struct tty_driver *hvc_console_device(struct console *c, int *index)
798{
799 *index = c->index;
800 return hvc_driver;
801}
802
803static int __init hvc_console_setup(struct console *co, char *options)
804{
805 return 0;
806}
807
808struct console hvc_con_driver = {
809 .name = "hvc",
810 .write = hvc_console_print,
811 .device = hvc_console_device,
812 .setup = hvc_console_setup,
813 .flags = CON_PRINTBUFFER,
814 .index = -1,
815};
816
817/* Early console initialization. Preceeds driver initialization. */
818static int __init hvc_console_init(void)
819{
820 int i;
821
822 for (i=0; i<MAX_NR_HVC_CONSOLES; i++)
823 vtermnos[i] = -1;
824 num_vterms = hvc_find_vtys();
825 register_console(&hvc_con_driver);
826 return 0;
827}
828console_initcall(hvc_console_init);
829
830module_init(hvc_init);
831module_exit(hvc_exit); 870module_exit(hvc_exit);
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
new file mode 100644
index 000000000000..60bb9152b832
--- /dev/null
+++ b/drivers/char/hvc_vio.c
@@ -0,0 +1,152 @@
1/*
2 * vio driver interface to hvc_console.c
3 *
4 * This code was moved here to allow the remaing code to be reused as a
5 * generic polling mode with semi-reliable transport driver core to the
6 * console and tty subsystems.
7 *
8 *
9 * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
10 * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
11 * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
12 * Copyright (C) 2004 IBM Corporation
13 *
14 * Additional Author(s):
15 * Ryan S. Arnold <rsa@us.ibm.com>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32#include <linux/types.h>
33#include <linux/init.h>
34#include <asm/hvconsole.h>
35#include <asm/vio.h>
36#include <asm/prom.h>
37
38char hvc_driver_name[] = "hvc_console";
39
40static struct vio_device_id hvc_driver_table[] __devinitdata = {
41 {"serial", "hvterm1"},
42 { NULL, }
43};
44MODULE_DEVICE_TABLE(vio, hvc_driver_table);
45
46static int filtered_get_chars(uint32_t vtermno, char *buf, int count)
47{
48 unsigned long got;
49 int i;
50
51 got = hvc_get_chars(vtermno, buf, count);
52
53 /*
54 * Work around a HV bug where it gives us a null
55 * after every \r. -- paulus
56 */
57 for (i = 1; i < got; ++i) {
58 if (buf[i] == 0 && buf[i-1] == '\r') {
59 --got;
60 if (i < got)
61 memmove(&buf[i], &buf[i+1],
62 got - i);
63 }
64 }
65 return got;
66}
67
68static struct hv_ops hvc_get_put_ops = {
69 .get_chars = filtered_get_chars,
70 .put_chars = hvc_put_chars,
71};
72
73static int __devinit hvc_vio_probe(struct vio_dev *vdev,
74 const struct vio_device_id *id)
75{
76 struct hvc_struct *hp;
77
78 /* probed with invalid parameters. */
79 if (!vdev || !id)
80 return -EPERM;
81
82 hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops);
83 if (IS_ERR(hp))
84 return PTR_ERR(hp);
85 dev_set_drvdata(&vdev->dev, hp);
86
87 return 0;
88}
89
90static int __devexit hvc_vio_remove(struct vio_dev *vdev)
91{
92 struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
93
94 return hvc_remove(hp);
95}
96
97static struct vio_driver hvc_vio_driver = {
98 .name = hvc_driver_name,
99 .id_table = hvc_driver_table,
100 .probe = hvc_vio_probe,
101 .remove = hvc_vio_remove,
102 .driver = {
103 .owner = THIS_MODULE,
104 }
105};
106
107static int hvc_vio_init(void)
108{
109 int rc;
110
111 /* Register as a vio device to receive callbacks */
112 rc = vio_register_driver(&hvc_vio_driver);
113
114 return rc;
115}
116module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
117
118static void hvc_vio_exit(void)
119{
120 vio_unregister_driver(&hvc_vio_driver);
121}
122module_exit(hvc_vio_exit);
123
124/* the device tree order defines our numbering */
125static int hvc_find_vtys(void)
126{
127 struct device_node *vty;
128 int num_found = 0;
129
130 for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
131 vty = of_find_node_by_name(vty, "vty")) {
132 uint32_t *vtermno;
133
134 /* We have statically defined space for only a certain number
135 * of console adapters.
136 */
137 if (num_found >= MAX_NR_HVC_CONSOLES)
138 break;
139
140 vtermno = (uint32_t *)get_property(vty, "reg", NULL);
141 if (!vtermno)
142 continue;
143
144 if (device_is_compatible(vty, "hvterm1")) {
145 hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
146 ++num_found;
147 }
148 }
149
150 return num_found;
151}
152console_initcall(hvc_find_vtys);
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index f1f1192ba2b5..a22aa940e01e 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -291,15 +291,13 @@ static void dump_packet(uint8_t *packet)
291 dump_hex(packet, header->len); 291 dump_hex(packet, header->len);
292} 292}
293 293
294/* can't use hvc_get_chars because that strips CRs */
295static int hvsi_read(struct hvsi_struct *hp, char *buf, int count) 294static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
296{ 295{
297 unsigned long got; 296 unsigned long got;
298 297
299 if (plpar_hcall(H_GET_TERM_CHAR, hp->vtermno, 0, 0, 0, &got, 298 got = hvc_get_chars(hp->vtermno, buf, count);
300 (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) 299
301 return got; 300 return got;
302 return 0;
303} 301}
304 302
305static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, 303static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index edba5a35bf21..09103b3d8f05 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -770,10 +770,8 @@ send_signal:
770 } 770 }
771 if (c == '\n') { 771 if (c == '\n') {
772 if (L_ECHO(tty) || L_ECHONL(tty)) { 772 if (L_ECHO(tty) || L_ECHONL(tty)) {
773 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { 773 if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
774 put_char('\a', tty); 774 put_char('\a', tty);
775 return;
776 }
777 opost('\n', tty); 775 opost('\n', tty);
778 } 776 }
779 goto handle_newline; 777 goto handle_newline;
@@ -790,10 +788,8 @@ send_signal:
790 * XXX are EOL_CHAR and EOL2_CHAR echoed?!? 788 * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
791 */ 789 */
792 if (L_ECHO(tty)) { 790 if (L_ECHO(tty)) {
793 if (tty->read_cnt >= N_TTY_BUF_SIZE-1) { 791 if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
794 put_char('\a', tty); 792 put_char('\a', tty);
795 return;
796 }
797 /* Record the column of first canon char. */ 793 /* Record the column of first canon char. */
798 if (tty->canon_head == tty->read_head) 794 if (tty->canon_head == tty->read_head)
799 tty->canon_column = tty->column; 795 tty->canon_column = tty->column;
@@ -862,12 +858,9 @@ static int n_tty_receive_room(struct tty_struct *tty)
862 * that erase characters will be handled. Other excess 858 * that erase characters will be handled. Other excess
863 * characters will be beeped. 859 * characters will be beeped.
864 */ 860 */
865 if (tty->icanon && !tty->canon_data) 861 if (left <= 0)
866 return N_TTY_BUF_SIZE; 862 left = tty->icanon && !tty->canon_data;
867 863 return left;
868 if (left > 0)
869 return left;
870 return 0;
871} 864}
872 865
873/** 866/**
@@ -1473,13 +1466,17 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file,
1473 if (tty->driver->flush_chars) 1466 if (tty->driver->flush_chars)
1474 tty->driver->flush_chars(tty); 1467 tty->driver->flush_chars(tty);
1475 } else { 1468 } else {
1476 c = tty->driver->write(tty, b, nr); 1469 while (nr > 0) {
1477 if (c < 0) { 1470 c = tty->driver->write(tty, b, nr);
1478 retval = c; 1471 if (c < 0) {
1479 goto break_out; 1472 retval = c;
1473 goto break_out;
1474 }
1475 if (!c)
1476 break;
1477 b += c;
1478 nr -= c;
1480 } 1479 }
1481 b += c;
1482 nr -= c;
1483 } 1480 }
1484 if (!nr) 1481 if (!nr)
1485 break; 1482 break;
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 8f36b1758eb6..7a0c74648124 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -71,7 +71,6 @@
71#include <linux/workqueue.h> 71#include <linux/workqueue.h>
72#include <linux/hdlc.h> 72#include <linux/hdlc.h>
73 73
74#include <pcmcia/version.h>
75#include <pcmcia/cs_types.h> 74#include <pcmcia/cs_types.h>
76#include <pcmcia/cs.h> 75#include <pcmcia/cs.h>
77#include <pcmcia/cistpl.h> 76#include <pcmcia/cistpl.h>
@@ -593,11 +592,6 @@ static dev_link_t *mgslpc_attach(void)
593 dev_list = link; 592 dev_list = link;
594 593
595 client_reg.dev_info = &dev_info; 594 client_reg.dev_info = &dev_info;
596 client_reg.EventMask =
597 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
598 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
599 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
600 client_reg.event_handler = &mgslpc_event;
601 client_reg.Version = 0x0210; 595 client_reg.Version = 0x0210;
602 client_reg.event_callback_args.client_data = link; 596 client_reg.event_callback_args.client_data = link;
603 597
@@ -3093,6 +3087,7 @@ static struct pcmcia_driver mgslpc_driver = {
3093 .name = "synclink_cs", 3087 .name = "synclink_cs",
3094 }, 3088 },
3095 .attach = mgslpc_attach, 3089 .attach = mgslpc_attach,
3090 .event = mgslpc_event,
3096 .detach = mgslpc_detach, 3091 .detach = mgslpc_detach,
3097 .id_table = mgslpc_ids, 3092 .id_table = mgslpc_ids,
3098}; 3093};
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 460b5d475edd..6b11d6b2129f 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -271,7 +271,7 @@ static int random_write_wakeup_thresh = 128;
271 * samples to avoid wasting CPU time and reduce lock contention. 271 * samples to avoid wasting CPU time and reduce lock contention.
272 */ 272 */
273 273
274static int trickle_thresh = INPUT_POOL_WORDS * 28; 274static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
275 275
276static DEFINE_PER_CPU(int, trickle_count) = 0; 276static DEFINE_PER_CPU(int, trickle_count) = 0;
277 277
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index af79805b5576..12d563c648f7 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -228,7 +228,7 @@ static struct sysrq_key_op sysrq_term_op = {
228 228
229static void moom_callback(void *ignored) 229static void moom_callback(void *ignored)
230{ 230{
231 out_of_memory(GFP_KERNEL); 231 out_of_memory(GFP_KERNEL, 0);
232} 232}
233 233
234static DECLARE_WORK(moom_work, moom_callback, NULL); 234static DECLARE_WORK(moom_work, moom_callback, NULL);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index bf62dfe4976a..7a7859dd0d98 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -869,7 +869,7 @@ EXPORT_SYMBOL(cpufreq_get);
869 * cpufreq_suspend - let the low level driver prepare for suspend 869 * cpufreq_suspend - let the low level driver prepare for suspend
870 */ 870 */
871 871
872static int cpufreq_suspend(struct sys_device * sysdev, u32 state) 872static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
873{ 873{
874 int cpu = sysdev->id; 874 int cpu = sysdev->id;
875 unsigned int ret = 0; 875 unsigned int ret = 0;
@@ -897,7 +897,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, u32 state)
897 } 897 }
898 898
899 if (cpufreq_driver->suspend) { 899 if (cpufreq_driver->suspend) {
900 ret = cpufreq_driver->suspend(cpu_policy, state); 900 ret = cpufreq_driver->suspend(cpu_policy, pmsg);
901 if (ret) { 901 if (ret) {
902 printk(KERN_ERR "cpufreq: suspend failed in ->suspend " 902 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
903 "step on CPU %u\n", cpu_policy->cpu); 903 "step on CPU %u\n", cpu_policy->cpu);
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index 978d27d6452d..aac59751e1b4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -46,7 +46,6 @@
46#include <asm/io.h> 46#include <asm/io.h>
47#include <asm/system.h> 47#include <asm/system.h>
48 48
49#include <pcmcia/version.h>
50#include <pcmcia/cs_types.h> 49#include <pcmcia/cs_types.h>
51#include <pcmcia/cs.h> 50#include <pcmcia/cs.h>
52#include <pcmcia/cistpl.h> 51#include <pcmcia/cistpl.h>
@@ -134,11 +133,6 @@ static dev_link_t *ide_attach(void)
134 link->next = dev_list; 133 link->next = dev_list;
135 dev_list = link; 134 dev_list = link;
136 client_reg.dev_info = &dev_info; 135 client_reg.dev_info = &dev_info;
137 client_reg.EventMask =
138 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
139 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
140 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
141 client_reg.event_handler = &ide_event;
142 client_reg.Version = 0x0210; 136 client_reg.Version = 0x0210;
143 client_reg.event_callback_args.client_data = link; 137 client_reg.event_callback_args.client_data = link;
144 ret = pcmcia_register_client(&link->handle, &client_reg); 138 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -497,6 +491,7 @@ static struct pcmcia_driver ide_cs_driver = {
497 .name = "ide-cs", 491 .name = "ide-cs",
498 }, 492 },
499 .attach = ide_attach, 493 .attach = ide_attach,
494 .event = ide_event,
500 .detach = ide_detach, 495 .detach = ide_detach,
501 .id_table = ide_ids, 496 .id_table = ide_ids,
502}; 497};
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 3cc3ff0cccb1..79c8e2dd9c33 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -7,6 +7,16 @@ config INFINIBAND
7 any protocols you wish to use as well as drivers for your 7 any protocols you wish to use as well as drivers for your
8 InfiniBand hardware. 8 InfiniBand hardware.
9 9
10config INFINIBAND_USER_VERBS
11 tristate "InfiniBand userspace verbs support"
12 depends on INFINIBAND
13 ---help---
14 Userspace InfiniBand verbs support. This is the kernel side
15 of userspace verbs, which allows userspace processes to
16 directly access InfiniBand hardware for fast-path
17 operations. You will also need libibverbs and a hardware
18 driver library from <http://www.openib.org>.
19
10source "drivers/infiniband/hw/mthca/Kconfig" 20source "drivers/infiniband/hw/mthca/Kconfig"
11 21
12source "drivers/infiniband/ulp/ipoib/Kconfig" 22source "drivers/infiniband/ulp/ipoib/Kconfig"
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index d2dbfb52c0a3..e1a7cf3e8636 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -1,6 +1,7 @@
1EXTRA_CFLAGS += -Idrivers/infiniband/include 1EXTRA_CFLAGS += -Idrivers/infiniband/include
2 2
3obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o ib_umad.o 3obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o ib_umad.o
4obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o
4 5
5ib_core-y := packer.o ud_header.o verbs.o sysfs.o \ 6ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
6 device.o fmr_pool.o cache.o 7 device.o fmr_pool.o cache.o
@@ -10,3 +11,5 @@ ib_mad-y := mad.o smi.o agent.o
10ib_sa-y := sa_query.o 11ib_sa-y := sa_query.o
11 12
12ib_umad-y := user_mad.o 13ib_umad-y := user_mad.o
14
15ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_mem.o
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
new file mode 100644
index 000000000000..57347f1e82c1
--- /dev/null
+++ b/drivers/infiniband/core/uverbs.h
@@ -0,0 +1,132 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 * $Id: uverbs.h 2559 2005-06-06 19:43:16Z roland $
34 */
35
36#ifndef UVERBS_H
37#define UVERBS_H
38
39/* Include device.h and fs.h until cdev.h is self-sufficient */
40#include <linux/fs.h>
41#include <linux/device.h>
42#include <linux/cdev.h>
43#include <linux/kref.h>
44#include <linux/idr.h>
45
46#include <ib_verbs.h>
47#include <ib_user_verbs.h>
48
49struct ib_uverbs_device {
50 int devnum;
51 struct cdev dev;
52 struct class_device class_dev;
53 struct ib_device *ib_dev;
54 int num_comp;
55};
56
57struct ib_uverbs_event_file {
58 struct kref ref;
59 struct ib_uverbs_file *uverbs_file;
60 spinlock_t lock;
61 int fd;
62 int is_async;
63 wait_queue_head_t poll_wait;
64 struct list_head event_list;
65};
66
67struct ib_uverbs_file {
68 struct kref ref;
69 struct ib_uverbs_device *device;
70 struct ib_ucontext *ucontext;
71 struct ib_event_handler event_handler;
72 struct ib_uverbs_event_file async_file;
73 struct ib_uverbs_event_file comp_file[1];
74};
75
76struct ib_uverbs_async_event {
77 struct ib_uverbs_async_event_desc desc;
78 struct list_head list;
79};
80
81struct ib_uverbs_comp_event {
82 struct ib_uverbs_comp_event_desc desc;
83 struct list_head list;
84};
85
86struct ib_uobject_mr {
87 struct ib_uobject uobj;
88 struct page *page_list;
89 struct scatterlist *sg_list;
90};
91
92extern struct semaphore ib_uverbs_idr_mutex;
93extern struct idr ib_uverbs_pd_idr;
94extern struct idr ib_uverbs_mr_idr;
95extern struct idr ib_uverbs_mw_idr;
96extern struct idr ib_uverbs_ah_idr;
97extern struct idr ib_uverbs_cq_idr;
98extern struct idr ib_uverbs_qp_idr;
99
100void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
101void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
102void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
103
104int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
105 void *addr, size_t size, int write);
106void ib_umem_release(struct ib_device *dev, struct ib_umem *umem);
107void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem);
108
109#define IB_UVERBS_DECLARE_CMD(name) \
110 ssize_t ib_uverbs_##name(struct ib_uverbs_file *file, \
111 const char __user *buf, int in_len, \
112 int out_len)
113
114IB_UVERBS_DECLARE_CMD(query_params);
115IB_UVERBS_DECLARE_CMD(get_context);
116IB_UVERBS_DECLARE_CMD(query_device);
117IB_UVERBS_DECLARE_CMD(query_port);
118IB_UVERBS_DECLARE_CMD(query_gid);
119IB_UVERBS_DECLARE_CMD(query_pkey);
120IB_UVERBS_DECLARE_CMD(alloc_pd);
121IB_UVERBS_DECLARE_CMD(dealloc_pd);
122IB_UVERBS_DECLARE_CMD(reg_mr);
123IB_UVERBS_DECLARE_CMD(dereg_mr);
124IB_UVERBS_DECLARE_CMD(create_cq);
125IB_UVERBS_DECLARE_CMD(destroy_cq);
126IB_UVERBS_DECLARE_CMD(create_qp);
127IB_UVERBS_DECLARE_CMD(modify_qp);
128IB_UVERBS_DECLARE_CMD(destroy_qp);
129IB_UVERBS_DECLARE_CMD(attach_mcast);
130IB_UVERBS_DECLARE_CMD(detach_mcast);
131
132#endif /* UVERBS_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
new file mode 100644
index 000000000000..5f2bbcda4c73
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -0,0 +1,1006 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
34 */
35
36#include <asm/uaccess.h>
37
38#include "uverbs.h"
39
40#define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \
41 do { \
42 (udata)->inbuf = (void __user *) (ibuf); \
43 (udata)->outbuf = (void __user *) (obuf); \
44 (udata)->inlen = (ilen); \
45 (udata)->outlen = (olen); \
46 } while (0)
47
48ssize_t ib_uverbs_query_params(struct ib_uverbs_file *file,
49 const char __user *buf,
50 int in_len, int out_len)
51{
52 struct ib_uverbs_query_params cmd;
53 struct ib_uverbs_query_params_resp resp;
54
55 if (out_len < sizeof resp)
56 return -ENOSPC;
57
58 if (copy_from_user(&cmd, buf, sizeof cmd))
59 return -EFAULT;
60
61 memset(&resp, 0, sizeof resp);
62
63 resp.num_cq_events = file->device->num_comp;
64
65 if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp))
66 return -EFAULT;
67
68 return in_len;
69}
70
71ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
72 const char __user *buf,
73 int in_len, int out_len)
74{
75 struct ib_uverbs_get_context cmd;
76 struct ib_uverbs_get_context_resp resp;
77 struct ib_udata udata;
78 struct ib_device *ibdev = file->device->ib_dev;
79 int i;
80 int ret = in_len;
81
82 if (out_len < sizeof resp)
83 return -ENOSPC;
84
85 if (copy_from_user(&cmd, buf, sizeof cmd))
86 return -EFAULT;
87
88 INIT_UDATA(&udata, buf + sizeof cmd,
89 (unsigned long) cmd.response + sizeof resp,
90 in_len - sizeof cmd, out_len - sizeof resp);
91
92 file->ucontext = ibdev->alloc_ucontext(ibdev, &udata);
93 if (IS_ERR(file->ucontext)) {
94 ret = PTR_ERR(file->ucontext);
95 file->ucontext = NULL;
96 return ret;
97 }
98
99 file->ucontext->device = ibdev;
100 INIT_LIST_HEAD(&file->ucontext->pd_list);
101 INIT_LIST_HEAD(&file->ucontext->mr_list);
102 INIT_LIST_HEAD(&file->ucontext->mw_list);
103 INIT_LIST_HEAD(&file->ucontext->cq_list);
104 INIT_LIST_HEAD(&file->ucontext->qp_list);
105 INIT_LIST_HEAD(&file->ucontext->srq_list);
106 INIT_LIST_HEAD(&file->ucontext->ah_list);
107 spin_lock_init(&file->ucontext->lock);
108
109 resp.async_fd = file->async_file.fd;
110 for (i = 0; i < file->device->num_comp; ++i)
111 if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
112 i * sizeof (__u32),
113 &file->comp_file[i].fd, sizeof (__u32)))
114 goto err;
115
116 if (copy_to_user((void __user *) (unsigned long) cmd.response,
117 &resp, sizeof resp))
118 goto err;
119
120 return in_len;
121
122err:
123 ibdev->dealloc_ucontext(file->ucontext);
124 file->ucontext = NULL;
125
126 return -EFAULT;
127}
128
129ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
130 const char __user *buf,
131 int in_len, int out_len)
132{
133 struct ib_uverbs_query_device cmd;
134 struct ib_uverbs_query_device_resp resp;
135 struct ib_device_attr attr;
136 int ret;
137
138 if (out_len < sizeof resp)
139 return -ENOSPC;
140
141 if (copy_from_user(&cmd, buf, sizeof cmd))
142 return -EFAULT;
143
144 ret = ib_query_device(file->device->ib_dev, &attr);
145 if (ret)
146 return ret;
147
148 memset(&resp, 0, sizeof resp);
149
150 resp.fw_ver = attr.fw_ver;
151 resp.node_guid = attr.node_guid;
152 resp.sys_image_guid = attr.sys_image_guid;
153 resp.max_mr_size = attr.max_mr_size;
154 resp.page_size_cap = attr.page_size_cap;
155 resp.vendor_id = attr.vendor_id;
156 resp.vendor_part_id = attr.vendor_part_id;
157 resp.hw_ver = attr.hw_ver;
158 resp.max_qp = attr.max_qp;
159 resp.max_qp_wr = attr.max_qp_wr;
160 resp.device_cap_flags = attr.device_cap_flags;
161 resp.max_sge = attr.max_sge;
162 resp.max_sge_rd = attr.max_sge_rd;
163 resp.max_cq = attr.max_cq;
164 resp.max_cqe = attr.max_cqe;
165 resp.max_mr = attr.max_mr;
166 resp.max_pd = attr.max_pd;
167 resp.max_qp_rd_atom = attr.max_qp_rd_atom;
168 resp.max_ee_rd_atom = attr.max_ee_rd_atom;
169 resp.max_res_rd_atom = attr.max_res_rd_atom;
170 resp.max_qp_init_rd_atom = attr.max_qp_init_rd_atom;
171 resp.max_ee_init_rd_atom = attr.max_ee_init_rd_atom;
172 resp.atomic_cap = attr.atomic_cap;
173 resp.max_ee = attr.max_ee;
174 resp.max_rdd = attr.max_rdd;
175 resp.max_mw = attr.max_mw;
176 resp.max_raw_ipv6_qp = attr.max_raw_ipv6_qp;
177 resp.max_raw_ethy_qp = attr.max_raw_ethy_qp;
178 resp.max_mcast_grp = attr.max_mcast_grp;
179 resp.max_mcast_qp_attach = attr.max_mcast_qp_attach;
180 resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach;
181 resp.max_ah = attr.max_ah;
182 resp.max_fmr = attr.max_fmr;
183 resp.max_map_per_fmr = attr.max_map_per_fmr;
184 resp.max_srq = attr.max_srq;
185 resp.max_srq_wr = attr.max_srq_wr;
186 resp.max_srq_sge = attr.max_srq_sge;
187 resp.max_pkeys = attr.max_pkeys;
188 resp.local_ca_ack_delay = attr.local_ca_ack_delay;
189 resp.phys_port_cnt = file->device->ib_dev->phys_port_cnt;
190
191 if (copy_to_user((void __user *) (unsigned long) cmd.response,
192 &resp, sizeof resp))
193 return -EFAULT;
194
195 return in_len;
196}
197
198ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
199 const char __user *buf,
200 int in_len, int out_len)
201{
202 struct ib_uverbs_query_port cmd;
203 struct ib_uverbs_query_port_resp resp;
204 struct ib_port_attr attr;
205 int ret;
206
207 if (out_len < sizeof resp)
208 return -ENOSPC;
209
210 if (copy_from_user(&cmd, buf, sizeof cmd))
211 return -EFAULT;
212
213 ret = ib_query_port(file->device->ib_dev, cmd.port_num, &attr);
214 if (ret)
215 return ret;
216
217 memset(&resp, 0, sizeof resp);
218
219 resp.state = attr.state;
220 resp.max_mtu = attr.max_mtu;
221 resp.active_mtu = attr.active_mtu;
222 resp.gid_tbl_len = attr.gid_tbl_len;
223 resp.port_cap_flags = attr.port_cap_flags;
224 resp.max_msg_sz = attr.max_msg_sz;
225 resp.bad_pkey_cntr = attr.bad_pkey_cntr;
226 resp.qkey_viol_cntr = attr.qkey_viol_cntr;
227 resp.pkey_tbl_len = attr.pkey_tbl_len;
228 resp.lid = attr.lid;
229 resp.sm_lid = attr.sm_lid;
230 resp.lmc = attr.lmc;
231 resp.max_vl_num = attr.max_vl_num;
232 resp.sm_sl = attr.sm_sl;
233 resp.subnet_timeout = attr.subnet_timeout;
234 resp.init_type_reply = attr.init_type_reply;
235 resp.active_width = attr.active_width;
236 resp.active_speed = attr.active_speed;
237 resp.phys_state = attr.phys_state;
238
239 if (copy_to_user((void __user *) (unsigned long) cmd.response,
240 &resp, sizeof resp))
241 return -EFAULT;
242
243 return in_len;
244}
245
246ssize_t ib_uverbs_query_gid(struct ib_uverbs_file *file,
247 const char __user *buf,
248 int in_len, int out_len)
249{
250 struct ib_uverbs_query_gid cmd;
251 struct ib_uverbs_query_gid_resp resp;
252 int ret;
253
254 if (out_len < sizeof resp)
255 return -ENOSPC;
256
257 if (copy_from_user(&cmd, buf, sizeof cmd))
258 return -EFAULT;
259
260 memset(&resp, 0, sizeof resp);
261
262 ret = ib_query_gid(file->device->ib_dev, cmd.port_num, cmd.index,
263 (union ib_gid *) resp.gid);
264 if (ret)
265 return ret;
266
267 if (copy_to_user((void __user *) (unsigned long) cmd.response,
268 &resp, sizeof resp))
269 return -EFAULT;
270
271 return in_len;
272}
273
274ssize_t ib_uverbs_query_pkey(struct ib_uverbs_file *file,
275 const char __user *buf,
276 int in_len, int out_len)
277{
278 struct ib_uverbs_query_pkey cmd;
279 struct ib_uverbs_query_pkey_resp resp;
280 int ret;
281
282 if (out_len < sizeof resp)
283 return -ENOSPC;
284
285 if (copy_from_user(&cmd, buf, sizeof cmd))
286 return -EFAULT;
287
288 memset(&resp, 0, sizeof resp);
289
290 ret = ib_query_pkey(file->device->ib_dev, cmd.port_num, cmd.index,
291 &resp.pkey);
292 if (ret)
293 return ret;
294
295 if (copy_to_user((void __user *) (unsigned long) cmd.response,
296 &resp, sizeof resp))
297 return -EFAULT;
298
299 return in_len;
300}
301
302ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
303 const char __user *buf,
304 int in_len, int out_len)
305{
306 struct ib_uverbs_alloc_pd cmd;
307 struct ib_uverbs_alloc_pd_resp resp;
308 struct ib_udata udata;
309 struct ib_uobject *uobj;
310 struct ib_pd *pd;
311 int ret;
312
313 if (out_len < sizeof resp)
314 return -ENOSPC;
315
316 if (copy_from_user(&cmd, buf, sizeof cmd))
317 return -EFAULT;
318
319 INIT_UDATA(&udata, buf + sizeof cmd,
320 (unsigned long) cmd.response + sizeof resp,
321 in_len - sizeof cmd, out_len - sizeof resp);
322
323 uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
324 if (!uobj)
325 return -ENOMEM;
326
327 uobj->context = file->ucontext;
328
329 pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
330 file->ucontext, &udata);
331 if (IS_ERR(pd)) {
332 ret = PTR_ERR(pd);
333 goto err;
334 }
335
336 pd->device = file->device->ib_dev;
337 pd->uobject = uobj;
338 atomic_set(&pd->usecnt, 0);
339
340retry:
341 if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
342 ret = -ENOMEM;
343 goto err_pd;
344 }
345
346 down(&ib_uverbs_idr_mutex);
347 ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id);
348 up(&ib_uverbs_idr_mutex);
349
350 if (ret == -EAGAIN)
351 goto retry;
352 if (ret)
353 goto err_pd;
354
355 spin_lock_irq(&file->ucontext->lock);
356 list_add_tail(&uobj->list, &file->ucontext->pd_list);
357 spin_unlock_irq(&file->ucontext->lock);
358
359 memset(&resp, 0, sizeof resp);
360 resp.pd_handle = uobj->id;
361
362 if (copy_to_user((void __user *) (unsigned long) cmd.response,
363 &resp, sizeof resp)) {
364 ret = -EFAULT;
365 goto err_list;
366 }
367
368 return in_len;
369
370err_list:
371 spin_lock_irq(&file->ucontext->lock);
372 list_del(&uobj->list);
373 spin_unlock_irq(&file->ucontext->lock);
374
375 down(&ib_uverbs_idr_mutex);
376 idr_remove(&ib_uverbs_pd_idr, uobj->id);
377 up(&ib_uverbs_idr_mutex);
378
379err_pd:
380 ib_dealloc_pd(pd);
381
382err:
383 kfree(uobj);
384 return ret;
385}
386
387ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
388 const char __user *buf,
389 int in_len, int out_len)
390{
391 struct ib_uverbs_dealloc_pd cmd;
392 struct ib_pd *pd;
393 struct ib_uobject *uobj;
394 int ret = -EINVAL;
395
396 if (copy_from_user(&cmd, buf, sizeof cmd))
397 return -EFAULT;
398
399 down(&ib_uverbs_idr_mutex);
400
401 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
402 if (!pd || pd->uobject->context != file->ucontext)
403 goto out;
404
405 uobj = pd->uobject;
406
407 ret = ib_dealloc_pd(pd);
408 if (ret)
409 goto out;
410
411 idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
412
413 spin_lock_irq(&file->ucontext->lock);
414 list_del(&uobj->list);
415 spin_unlock_irq(&file->ucontext->lock);
416
417 kfree(uobj);
418
419out:
420 up(&ib_uverbs_idr_mutex);
421
422 return ret ? ret : in_len;
423}
424
425ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
426 const char __user *buf, int in_len,
427 int out_len)
428{
429 struct ib_uverbs_reg_mr cmd;
430 struct ib_uverbs_reg_mr_resp resp;
431 struct ib_udata udata;
432 struct ib_umem_object *obj;
433 struct ib_pd *pd;
434 struct ib_mr *mr;
435 int ret;
436
437 if (out_len < sizeof resp)
438 return -ENOSPC;
439
440 if (copy_from_user(&cmd, buf, sizeof cmd))
441 return -EFAULT;
442
443 INIT_UDATA(&udata, buf + sizeof cmd,
444 (unsigned long) cmd.response + sizeof resp,
445 in_len - sizeof cmd, out_len - sizeof resp);
446
447 if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
448 return -EINVAL;
449
450 obj = kmalloc(sizeof *obj, GFP_KERNEL);
451 if (!obj)
452 return -ENOMEM;
453
454 obj->uobject.context = file->ucontext;
455
456 /*
457 * We ask for writable memory if any access flags other than
458 * "remote read" are set. "Local write" and "remote write"
459 * obviously require write access. "Remote atomic" can do
460 * things like fetch and add, which will modify memory, and
461 * "MW bind" can change permissions by binding a window.
462 */
463 ret = ib_umem_get(file->device->ib_dev, &obj->umem,
464 (void *) (unsigned long) cmd.start, cmd.length,
465 !!(cmd.access_flags & ~IB_ACCESS_REMOTE_READ));
466 if (ret)
467 goto err_free;
468
469 obj->umem.virt_base = cmd.hca_va;
470
471 down(&ib_uverbs_idr_mutex);
472
473 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
474 if (!pd || pd->uobject->context != file->ucontext) {
475 ret = -EINVAL;
476 goto err_up;
477 }
478
479 if (!pd->device->reg_user_mr) {
480 ret = -ENOSYS;
481 goto err_up;
482 }
483
484 mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata);
485 if (IS_ERR(mr)) {
486 ret = PTR_ERR(mr);
487 goto err_up;
488 }
489
490 mr->device = pd->device;
491 mr->pd = pd;
492 mr->uobject = &obj->uobject;
493 atomic_inc(&pd->usecnt);
494 atomic_set(&mr->usecnt, 0);
495
496 memset(&resp, 0, sizeof resp);
497 resp.lkey = mr->lkey;
498 resp.rkey = mr->rkey;
499
500retry:
501 if (!idr_pre_get(&ib_uverbs_mr_idr, GFP_KERNEL)) {
502 ret = -ENOMEM;
503 goto err_unreg;
504 }
505
506 ret = idr_get_new(&ib_uverbs_mr_idr, mr, &obj->uobject.id);
507
508 if (ret == -EAGAIN)
509 goto retry;
510 if (ret)
511 goto err_unreg;
512
513 resp.mr_handle = obj->uobject.id;
514
515 spin_lock_irq(&file->ucontext->lock);
516 list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
517 spin_unlock_irq(&file->ucontext->lock);
518
519 if (copy_to_user((void __user *) (unsigned long) cmd.response,
520 &resp, sizeof resp)) {
521 ret = -EFAULT;
522 goto err_list;
523 }
524
525 up(&ib_uverbs_idr_mutex);
526
527 return in_len;
528
529err_list:
530 spin_lock_irq(&file->ucontext->lock);
531 list_del(&obj->uobject.list);
532 spin_unlock_irq(&file->ucontext->lock);
533
534err_unreg:
535 ib_dereg_mr(mr);
536
537err_up:
538 up(&ib_uverbs_idr_mutex);
539
540 ib_umem_release(file->device->ib_dev, &obj->umem);
541
542err_free:
543 kfree(obj);
544 return ret;
545}
546
547ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
548 const char __user *buf, int in_len,
549 int out_len)
550{
551 struct ib_uverbs_dereg_mr cmd;
552 struct ib_mr *mr;
553 struct ib_umem_object *memobj;
554 int ret = -EINVAL;
555
556 if (copy_from_user(&cmd, buf, sizeof cmd))
557 return -EFAULT;
558
559 down(&ib_uverbs_idr_mutex);
560
561 mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle);
562 if (!mr || mr->uobject->context != file->ucontext)
563 goto out;
564
565 memobj = container_of(mr->uobject, struct ib_umem_object, uobject);
566
567 ret = ib_dereg_mr(mr);
568 if (ret)
569 goto out;
570
571 idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
572
573 spin_lock_irq(&file->ucontext->lock);
574 list_del(&memobj->uobject.list);
575 spin_unlock_irq(&file->ucontext->lock);
576
577 ib_umem_release(file->device->ib_dev, &memobj->umem);
578 kfree(memobj);
579
580out:
581 up(&ib_uverbs_idr_mutex);
582
583 return ret ? ret : in_len;
584}
585
586ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
587 const char __user *buf, int in_len,
588 int out_len)
589{
590 struct ib_uverbs_create_cq cmd;
591 struct ib_uverbs_create_cq_resp resp;
592 struct ib_udata udata;
593 struct ib_uobject *uobj;
594 struct ib_cq *cq;
595 int ret;
596
597 if (out_len < sizeof resp)
598 return -ENOSPC;
599
600 if (copy_from_user(&cmd, buf, sizeof cmd))
601 return -EFAULT;
602
603 INIT_UDATA(&udata, buf + sizeof cmd,
604 (unsigned long) cmd.response + sizeof resp,
605 in_len - sizeof cmd, out_len - sizeof resp);
606
607 if (cmd.event_handler >= file->device->num_comp)
608 return -EINVAL;
609
610 uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
611 if (!uobj)
612 return -ENOMEM;
613
614 uobj->user_handle = cmd.user_handle;
615 uobj->context = file->ucontext;
616
617 cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
618 file->ucontext, &udata);
619 if (IS_ERR(cq)) {
620 ret = PTR_ERR(cq);
621 goto err;
622 }
623
624 cq->device = file->device->ib_dev;
625 cq->uobject = uobj;
626 cq->comp_handler = ib_uverbs_comp_handler;
627 cq->event_handler = ib_uverbs_cq_event_handler;
628 cq->cq_context = file;
629 atomic_set(&cq->usecnt, 0);
630
631retry:
632 if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
633 ret = -ENOMEM;
634 goto err_cq;
635 }
636
637 down(&ib_uverbs_idr_mutex);
638 ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->id);
639 up(&ib_uverbs_idr_mutex);
640
641 if (ret == -EAGAIN)
642 goto retry;
643 if (ret)
644 goto err_cq;
645
646 spin_lock_irq(&file->ucontext->lock);
647 list_add_tail(&uobj->list, &file->ucontext->cq_list);
648 spin_unlock_irq(&file->ucontext->lock);
649
650 memset(&resp, 0, sizeof resp);
651 resp.cq_handle = uobj->id;
652 resp.cqe = cq->cqe;
653
654 if (copy_to_user((void __user *) (unsigned long) cmd.response,
655 &resp, sizeof resp)) {
656 ret = -EFAULT;
657 goto err_list;
658 }
659
660 return in_len;
661
662err_list:
663 spin_lock_irq(&file->ucontext->lock);
664 list_del(&uobj->list);
665 spin_unlock_irq(&file->ucontext->lock);
666
667 down(&ib_uverbs_idr_mutex);
668 idr_remove(&ib_uverbs_cq_idr, uobj->id);
669 up(&ib_uverbs_idr_mutex);
670
671err_cq:
672 ib_destroy_cq(cq);
673
674err:
675 kfree(uobj);
676 return ret;
677}
678
679ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
680 const char __user *buf, int in_len,
681 int out_len)
682{
683 struct ib_uverbs_destroy_cq cmd;
684 struct ib_cq *cq;
685 struct ib_uobject *uobj;
686 int ret = -EINVAL;
687
688 if (copy_from_user(&cmd, buf, sizeof cmd))
689 return -EFAULT;
690
691 down(&ib_uverbs_idr_mutex);
692
693 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
694 if (!cq || cq->uobject->context != file->ucontext)
695 goto out;
696
697 uobj = cq->uobject;
698
699 ret = ib_destroy_cq(cq);
700 if (ret)
701 goto out;
702
703 idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
704
705 spin_lock_irq(&file->ucontext->lock);
706 list_del(&uobj->list);
707 spin_unlock_irq(&file->ucontext->lock);
708
709 kfree(uobj);
710
711out:
712 up(&ib_uverbs_idr_mutex);
713
714 return ret ? ret : in_len;
715}
716
717ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
718 const char __user *buf, int in_len,
719 int out_len)
720{
721 struct ib_uverbs_create_qp cmd;
722 struct ib_uverbs_create_qp_resp resp;
723 struct ib_udata udata;
724 struct ib_uobject *uobj;
725 struct ib_pd *pd;
726 struct ib_cq *scq, *rcq;
727 struct ib_qp *qp;
728 struct ib_qp_init_attr attr;
729 int ret;
730
731 if (out_len < sizeof resp)
732 return -ENOSPC;
733
734 if (copy_from_user(&cmd, buf, sizeof cmd))
735 return -EFAULT;
736
737 INIT_UDATA(&udata, buf + sizeof cmd,
738 (unsigned long) cmd.response + sizeof resp,
739 in_len - sizeof cmd, out_len - sizeof resp);
740
741 uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
742 if (!uobj)
743 return -ENOMEM;
744
745 down(&ib_uverbs_idr_mutex);
746
747 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
748 scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
749 rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
750
751 if (!pd || pd->uobject->context != file->ucontext ||
752 !scq || scq->uobject->context != file->ucontext ||
753 !rcq || rcq->uobject->context != file->ucontext) {
754 ret = -EINVAL;
755 goto err_up;
756 }
757
758 attr.event_handler = ib_uverbs_qp_event_handler;
759 attr.qp_context = file;
760 attr.send_cq = scq;
761 attr.recv_cq = rcq;
762 attr.srq = NULL;
763 attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
764 attr.qp_type = cmd.qp_type;
765
766 attr.cap.max_send_wr = cmd.max_send_wr;
767 attr.cap.max_recv_wr = cmd.max_recv_wr;
768 attr.cap.max_send_sge = cmd.max_send_sge;
769 attr.cap.max_recv_sge = cmd.max_recv_sge;
770 attr.cap.max_inline_data = cmd.max_inline_data;
771
772 uobj->user_handle = cmd.user_handle;
773 uobj->context = file->ucontext;
774
775 qp = pd->device->create_qp(pd, &attr, &udata);
776 if (IS_ERR(qp)) {
777 ret = PTR_ERR(qp);
778 goto err_up;
779 }
780
781 qp->device = pd->device;
782 qp->pd = pd;
783 qp->send_cq = attr.send_cq;
784 qp->recv_cq = attr.recv_cq;
785 qp->srq = attr.srq;
786 qp->uobject = uobj;
787 qp->event_handler = attr.event_handler;
788 qp->qp_context = attr.qp_context;
789 qp->qp_type = attr.qp_type;
790 atomic_inc(&pd->usecnt);
791 atomic_inc(&attr.send_cq->usecnt);
792 atomic_inc(&attr.recv_cq->usecnt);
793 if (attr.srq)
794 atomic_inc(&attr.srq->usecnt);
795
796 memset(&resp, 0, sizeof resp);
797 resp.qpn = qp->qp_num;
798
799retry:
800 if (!idr_pre_get(&ib_uverbs_qp_idr, GFP_KERNEL)) {
801 ret = -ENOMEM;
802 goto err_destroy;
803 }
804
805 ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->id);
806
807 if (ret == -EAGAIN)
808 goto retry;
809 if (ret)
810 goto err_destroy;
811
812 resp.qp_handle = uobj->id;
813
814 spin_lock_irq(&file->ucontext->lock);
815 list_add_tail(&uobj->list, &file->ucontext->qp_list);
816 spin_unlock_irq(&file->ucontext->lock);
817
818 if (copy_to_user((void __user *) (unsigned long) cmd.response,
819 &resp, sizeof resp)) {
820 ret = -EFAULT;
821 goto err_list;
822 }
823
824 up(&ib_uverbs_idr_mutex);
825
826 return in_len;
827
828err_list:
829 spin_lock_irq(&file->ucontext->lock);
830 list_del(&uobj->list);
831 spin_unlock_irq(&file->ucontext->lock);
832
833err_destroy:
834 ib_destroy_qp(qp);
835
836err_up:
837 up(&ib_uverbs_idr_mutex);
838
839 kfree(uobj);
840 return ret;
841}
842
843ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
844 const char __user *buf, int in_len,
845 int out_len)
846{
847 struct ib_uverbs_modify_qp cmd;
848 struct ib_qp *qp;
849 struct ib_qp_attr *attr;
850 int ret;
851
852 if (copy_from_user(&cmd, buf, sizeof cmd))
853 return -EFAULT;
854
855 attr = kmalloc(sizeof *attr, GFP_KERNEL);
856 if (!attr)
857 return -ENOMEM;
858
859 down(&ib_uverbs_idr_mutex);
860
861 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
862 if (!qp || qp->uobject->context != file->ucontext) {
863 ret = -EINVAL;
864 goto out;
865 }
866
867 attr->qp_state = cmd.qp_state;
868 attr->cur_qp_state = cmd.cur_qp_state;
869 attr->path_mtu = cmd.path_mtu;
870 attr->path_mig_state = cmd.path_mig_state;
871 attr->qkey = cmd.qkey;
872 attr->rq_psn = cmd.rq_psn;
873 attr->sq_psn = cmd.sq_psn;
874 attr->dest_qp_num = cmd.dest_qp_num;
875 attr->qp_access_flags = cmd.qp_access_flags;
876 attr->pkey_index = cmd.pkey_index;
877 attr->alt_pkey_index = cmd.pkey_index;
878 attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
879 attr->max_rd_atomic = cmd.max_rd_atomic;
880 attr->max_dest_rd_atomic = cmd.max_dest_rd_atomic;
881 attr->min_rnr_timer = cmd.min_rnr_timer;
882 attr->port_num = cmd.port_num;
883 attr->timeout = cmd.timeout;
884 attr->retry_cnt = cmd.retry_cnt;
885 attr->rnr_retry = cmd.rnr_retry;
886 attr->alt_port_num = cmd.alt_port_num;
887 attr->alt_timeout = cmd.alt_timeout;
888
889 memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
890 attr->ah_attr.grh.flow_label = cmd.dest.flow_label;
891 attr->ah_attr.grh.sgid_index = cmd.dest.sgid_index;
892 attr->ah_attr.grh.hop_limit = cmd.dest.hop_limit;
893 attr->ah_attr.grh.traffic_class = cmd.dest.traffic_class;
894 attr->ah_attr.dlid = cmd.dest.dlid;
895 attr->ah_attr.sl = cmd.dest.sl;
896 attr->ah_attr.src_path_bits = cmd.dest.src_path_bits;
897 attr->ah_attr.static_rate = cmd.dest.static_rate;
898 attr->ah_attr.ah_flags = cmd.dest.is_global ? IB_AH_GRH : 0;
899 attr->ah_attr.port_num = cmd.dest.port_num;
900
901 memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
902 attr->alt_ah_attr.grh.flow_label = cmd.alt_dest.flow_label;
903 attr->alt_ah_attr.grh.sgid_index = cmd.alt_dest.sgid_index;
904 attr->alt_ah_attr.grh.hop_limit = cmd.alt_dest.hop_limit;
905 attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
906 attr->alt_ah_attr.dlid = cmd.alt_dest.dlid;
907 attr->alt_ah_attr.sl = cmd.alt_dest.sl;
908 attr->alt_ah_attr.src_path_bits = cmd.alt_dest.src_path_bits;
909 attr->alt_ah_attr.static_rate = cmd.alt_dest.static_rate;
910 attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
911 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
912
913 ret = ib_modify_qp(qp, attr, cmd.attr_mask);
914 if (ret)
915 goto out;
916
917 ret = in_len;
918
919out:
920 up(&ib_uverbs_idr_mutex);
921 kfree(attr);
922
923 return ret;
924}
925
926ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
927 const char __user *buf, int in_len,
928 int out_len)
929{
930 struct ib_uverbs_destroy_qp cmd;
931 struct ib_qp *qp;
932 struct ib_uobject *uobj;
933 int ret = -EINVAL;
934
935 if (copy_from_user(&cmd, buf, sizeof cmd))
936 return -EFAULT;
937
938 down(&ib_uverbs_idr_mutex);
939
940 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
941 if (!qp || qp->uobject->context != file->ucontext)
942 goto out;
943
944 uobj = qp->uobject;
945
946 ret = ib_destroy_qp(qp);
947 if (ret)
948 goto out;
949
950 idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
951
952 spin_lock_irq(&file->ucontext->lock);
953 list_del(&uobj->list);
954 spin_unlock_irq(&file->ucontext->lock);
955
956 kfree(uobj);
957
958out:
959 up(&ib_uverbs_idr_mutex);
960
961 return ret ? ret : in_len;
962}
963
964ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
965 const char __user *buf, int in_len,
966 int out_len)
967{
968 struct ib_uverbs_attach_mcast cmd;
969 struct ib_qp *qp;
970 int ret = -EINVAL;
971
972 if (copy_from_user(&cmd, buf, sizeof cmd))
973 return -EFAULT;
974
975 down(&ib_uverbs_idr_mutex);
976
977 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
978 if (qp && qp->uobject->context == file->ucontext)
979 ret = ib_attach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
980
981 up(&ib_uverbs_idr_mutex);
982
983 return ret ? ret : in_len;
984}
985
986ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
987 const char __user *buf, int in_len,
988 int out_len)
989{
990 struct ib_uverbs_detach_mcast cmd;
991 struct ib_qp *qp;
992 int ret = -EINVAL;
993
994 if (copy_from_user(&cmd, buf, sizeof cmd))
995 return -EFAULT;
996
997 down(&ib_uverbs_idr_mutex);
998
999 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1000 if (qp && qp->uobject->context == file->ucontext)
1001 ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
1002
1003 up(&ib_uverbs_idr_mutex);
1004
1005 return ret ? ret : in_len;
1006}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
new file mode 100644
index 000000000000..fbbe03d8c901
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -0,0 +1,698 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 * $Id: uverbs_main.c 2733 2005-06-28 19:14:34Z roland $
34 */
35
36#include <linux/module.h>
37#include <linux/init.h>
38#include <linux/device.h>
39#include <linux/err.h>
40#include <linux/fs.h>
41#include <linux/poll.h>
42#include <linux/file.h>
43#include <linux/mount.h>
44
45#include <asm/uaccess.h>
46
47#include "uverbs.h"
48
49MODULE_AUTHOR("Roland Dreier");
50MODULE_DESCRIPTION("InfiniBand userspace verbs access");
51MODULE_LICENSE("Dual BSD/GPL");
52
53#define INFINIBANDEVENTFS_MAGIC 0x49426576 /* "IBev" */
54
55enum {
56 IB_UVERBS_MAJOR = 231,
57 IB_UVERBS_BASE_MINOR = 192,
58 IB_UVERBS_MAX_DEVICES = 32
59};
60
61#define IB_UVERBS_BASE_DEV MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR)
62
63DECLARE_MUTEX(ib_uverbs_idr_mutex);
64DEFINE_IDR(ib_uverbs_pd_idr);
65DEFINE_IDR(ib_uverbs_mr_idr);
66DEFINE_IDR(ib_uverbs_mw_idr);
67DEFINE_IDR(ib_uverbs_ah_idr);
68DEFINE_IDR(ib_uverbs_cq_idr);
69DEFINE_IDR(ib_uverbs_qp_idr);
70
71static spinlock_t map_lock;
72static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
73
74static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
75 const char __user *buf, int in_len,
76 int out_len) = {
77 [IB_USER_VERBS_CMD_QUERY_PARAMS] = ib_uverbs_query_params,
78 [IB_USER_VERBS_CMD_GET_CONTEXT] = ib_uverbs_get_context,
79 [IB_USER_VERBS_CMD_QUERY_DEVICE] = ib_uverbs_query_device,
80 [IB_USER_VERBS_CMD_QUERY_PORT] = ib_uverbs_query_port,
81 [IB_USER_VERBS_CMD_QUERY_GID] = ib_uverbs_query_gid,
82 [IB_USER_VERBS_CMD_QUERY_PKEY] = ib_uverbs_query_pkey,
83 [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd,
84 [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd,
85 [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr,
86 [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr,
87 [IB_USER_VERBS_CMD_CREATE_CQ] = ib_uverbs_create_cq,
88 [IB_USER_VERBS_CMD_DESTROY_CQ] = ib_uverbs_destroy_cq,
89 [IB_USER_VERBS_CMD_CREATE_QP] = ib_uverbs_create_qp,
90 [IB_USER_VERBS_CMD_MODIFY_QP] = ib_uverbs_modify_qp,
91 [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp,
92 [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast,
93 [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast,
94};
95
96static struct vfsmount *uverbs_event_mnt;
97
98static void ib_uverbs_add_one(struct ib_device *device);
99static void ib_uverbs_remove_one(struct ib_device *device);
100
101static int ib_dealloc_ucontext(struct ib_ucontext *context)
102{
103 struct ib_uobject *uobj, *tmp;
104
105 if (!context)
106 return 0;
107
108 down(&ib_uverbs_idr_mutex);
109
110 /* XXX Free AHs */
111
112 list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) {
113 struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id);
114 idr_remove(&ib_uverbs_qp_idr, uobj->id);
115 ib_destroy_qp(qp);
116 list_del(&uobj->list);
117 kfree(uobj);
118 }
119
120 list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
121 struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id);
122 idr_remove(&ib_uverbs_cq_idr, uobj->id);
123 ib_destroy_cq(cq);
124 list_del(&uobj->list);
125 kfree(uobj);
126 }
127
128 /* XXX Free SRQs */
129 /* XXX Free MWs */
130
131 list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
132 struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id);
133 struct ib_umem_object *memobj;
134
135 idr_remove(&ib_uverbs_mr_idr, uobj->id);
136 ib_dereg_mr(mr);
137
138 memobj = container_of(uobj, struct ib_umem_object, uobject);
139 ib_umem_release_on_close(mr->device, &memobj->umem);
140
141 list_del(&uobj->list);
142 kfree(memobj);
143 }
144
145 list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) {
146 struct ib_pd *pd = idr_find(&ib_uverbs_pd_idr, uobj->id);
147 idr_remove(&ib_uverbs_pd_idr, uobj->id);
148 ib_dealloc_pd(pd);
149 list_del(&uobj->list);
150 kfree(uobj);
151 }
152
153 up(&ib_uverbs_idr_mutex);
154
155 return context->device->dealloc_ucontext(context);
156}
157
158static void ib_uverbs_release_file(struct kref *ref)
159{
160 struct ib_uverbs_file *file =
161 container_of(ref, struct ib_uverbs_file, ref);
162
163 module_put(file->device->ib_dev->owner);
164 kfree(file);
165}
166
167static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
168 size_t count, loff_t *pos)
169{
170 struct ib_uverbs_event_file *file = filp->private_data;
171 void *event;
172 int eventsz;
173 int ret = 0;
174
175 spin_lock_irq(&file->lock);
176
177 while (list_empty(&file->event_list) && file->fd >= 0) {
178 spin_unlock_irq(&file->lock);
179
180 if (filp->f_flags & O_NONBLOCK)
181 return -EAGAIN;
182
183 if (wait_event_interruptible(file->poll_wait,
184 !list_empty(&file->event_list) ||
185 file->fd < 0))
186 return -ERESTARTSYS;
187
188 spin_lock_irq(&file->lock);
189 }
190
191 if (file->fd < 0) {
192 spin_unlock_irq(&file->lock);
193 return -ENODEV;
194 }
195
196 if (file->is_async) {
197 event = list_entry(file->event_list.next,
198 struct ib_uverbs_async_event, list);
199 eventsz = sizeof (struct ib_uverbs_async_event_desc);
200 } else {
201 event = list_entry(file->event_list.next,
202 struct ib_uverbs_comp_event, list);
203 eventsz = sizeof (struct ib_uverbs_comp_event_desc);
204 }
205
206 if (eventsz > count) {
207 ret = -EINVAL;
208 event = NULL;
209 } else
210 list_del(file->event_list.next);
211
212 spin_unlock_irq(&file->lock);
213
214 if (event) {
215 if (copy_to_user(buf, event, eventsz))
216 ret = -EFAULT;
217 else
218 ret = eventsz;
219 }
220
221 kfree(event);
222
223 return ret;
224}
225
226static unsigned int ib_uverbs_event_poll(struct file *filp,
227 struct poll_table_struct *wait)
228{
229 unsigned int pollflags = 0;
230 struct ib_uverbs_event_file *file = filp->private_data;
231
232 poll_wait(filp, &file->poll_wait, wait);
233
234 spin_lock_irq(&file->lock);
235 if (file->fd < 0)
236 pollflags = POLLERR;
237 else if (!list_empty(&file->event_list))
238 pollflags = POLLIN | POLLRDNORM;
239 spin_unlock_irq(&file->lock);
240
241 return pollflags;
242}
243
244static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
245{
246 struct list_head *entry, *tmp;
247
248 spin_lock_irq(&file->lock);
249 if (file->fd != -1) {
250 file->fd = -1;
251 list_for_each_safe(entry, tmp, &file->event_list)
252 if (file->is_async)
253 kfree(list_entry(entry, struct ib_uverbs_async_event, list));
254 else
255 kfree(list_entry(entry, struct ib_uverbs_comp_event, list));
256 }
257 spin_unlock_irq(&file->lock);
258}
259
260static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
261{
262 struct ib_uverbs_event_file *file = filp->private_data;
263
264 ib_uverbs_event_release(file);
265 kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
266
267 return 0;
268}
269
270static struct file_operations uverbs_event_fops = {
271 /*
272 * No .owner field since we artificially create event files,
273 * so there is no increment to the module reference count in
274 * the open path. All event files come from a uverbs command
275 * file, which already takes a module reference, so this is OK.
276 */
277 .read = ib_uverbs_event_read,
278 .poll = ib_uverbs_event_poll,
279 .release = ib_uverbs_event_close
280};
281
282void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
283{
284 struct ib_uverbs_file *file = cq_context;
285 struct ib_uverbs_comp_event *entry;
286 unsigned long flags;
287
288 entry = kmalloc(sizeof *entry, GFP_ATOMIC);
289 if (!entry)
290 return;
291
292 entry->desc.cq_handle = cq->uobject->user_handle;
293
294 spin_lock_irqsave(&file->comp_file[0].lock, flags);
295 list_add_tail(&entry->list, &file->comp_file[0].event_list);
296 spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
297
298 wake_up_interruptible(&file->comp_file[0].poll_wait);
299}
300
301static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
302 __u64 element, __u64 event)
303{
304 struct ib_uverbs_async_event *entry;
305 unsigned long flags;
306
307 entry = kmalloc(sizeof *entry, GFP_ATOMIC);
308 if (!entry)
309 return;
310
311 entry->desc.element = element;
312 entry->desc.event_type = event;
313
314 spin_lock_irqsave(&file->async_file.lock, flags);
315 list_add_tail(&entry->list, &file->async_file.event_list);
316 spin_unlock_irqrestore(&file->async_file.lock, flags);
317
318 wake_up_interruptible(&file->async_file.poll_wait);
319}
320
321void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
322{
323 ib_uverbs_async_handler(context_ptr,
324 event->element.cq->uobject->user_handle,
325 event->event);
326}
327
328void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
329{
330 ib_uverbs_async_handler(context_ptr,
331 event->element.qp->uobject->user_handle,
332 event->event);
333}
334
335static void ib_uverbs_event_handler(struct ib_event_handler *handler,
336 struct ib_event *event)
337{
338 struct ib_uverbs_file *file =
339 container_of(handler, struct ib_uverbs_file, event_handler);
340
341 ib_uverbs_async_handler(file, event->element.port_num, event->event);
342}
343
344static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
345 struct ib_uverbs_file *uverbs_file)
346{
347 struct file *filp;
348
349 spin_lock_init(&file->lock);
350 INIT_LIST_HEAD(&file->event_list);
351 init_waitqueue_head(&file->poll_wait);
352 file->uverbs_file = uverbs_file;
353
354 file->fd = get_unused_fd();
355 if (file->fd < 0)
356 return file->fd;
357
358 filp = get_empty_filp();
359 if (!filp) {
360 put_unused_fd(file->fd);
361 return -ENFILE;
362 }
363
364 filp->f_op = &uverbs_event_fops;
365 filp->f_vfsmnt = mntget(uverbs_event_mnt);
366 filp->f_dentry = dget(uverbs_event_mnt->mnt_root);
367 filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
368 filp->f_flags = O_RDONLY;
369 filp->f_mode = FMODE_READ;
370 filp->private_data = file;
371
372 fd_install(file->fd, filp);
373
374 return 0;
375}
376
377static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
378 size_t count, loff_t *pos)
379{
380 struct ib_uverbs_file *file = filp->private_data;
381 struct ib_uverbs_cmd_hdr hdr;
382
383 if (count < sizeof hdr)
384 return -EINVAL;
385
386 if (copy_from_user(&hdr, buf, sizeof hdr))
387 return -EFAULT;
388
389 if (hdr.in_words * 4 != count)
390 return -EINVAL;
391
392 if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table))
393 return -EINVAL;
394
395 if (!file->ucontext &&
396 hdr.command != IB_USER_VERBS_CMD_QUERY_PARAMS &&
397 hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT)
398 return -EINVAL;
399
400 return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr,
401 hdr.in_words * 4, hdr.out_words * 4);
402}
403
404static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma)
405{
406 struct ib_uverbs_file *file = filp->private_data;
407
408 if (!file->ucontext)
409 return -ENODEV;
410 else
411 return file->device->ib_dev->mmap(file->ucontext, vma);
412}
413
414static int ib_uverbs_open(struct inode *inode, struct file *filp)
415{
416 struct ib_uverbs_device *dev =
417 container_of(inode->i_cdev, struct ib_uverbs_device, dev);
418 struct ib_uverbs_file *file;
419 int i = 0;
420 int ret;
421
422 if (!try_module_get(dev->ib_dev->owner))
423 return -ENODEV;
424
425 file = kmalloc(sizeof *file +
426 (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
427 GFP_KERNEL);
428 if (!file)
429 return -ENOMEM;
430
431 file->device = dev;
432 kref_init(&file->ref);
433
434 file->ucontext = NULL;
435
436 ret = ib_uverbs_event_init(&file->async_file, file);
437 if (ret)
438 goto err;
439
440 file->async_file.is_async = 1;
441
442 kref_get(&file->ref);
443
444 for (i = 0; i < dev->num_comp; ++i) {
445 ret = ib_uverbs_event_init(&file->comp_file[i], file);
446 if (ret)
447 goto err_async;
448 kref_get(&file->ref);
449 file->comp_file[i].is_async = 0;
450 }
451
452
453 filp->private_data = file;
454
455 INIT_IB_EVENT_HANDLER(&file->event_handler, dev->ib_dev,
456 ib_uverbs_event_handler);
457 if (ib_register_event_handler(&file->event_handler))
458 goto err_async;
459
460 return 0;
461
462err_async:
463 while (i--)
464 ib_uverbs_event_release(&file->comp_file[i]);
465
466 ib_uverbs_event_release(&file->async_file);
467
468err:
469 kref_put(&file->ref, ib_uverbs_release_file);
470
471 return ret;
472}
473
474static int ib_uverbs_close(struct inode *inode, struct file *filp)
475{
476 struct ib_uverbs_file *file = filp->private_data;
477 int i;
478
479 ib_unregister_event_handler(&file->event_handler);
480 ib_uverbs_event_release(&file->async_file);
481 ib_dealloc_ucontext(file->ucontext);
482
483 for (i = 0; i < file->device->num_comp; ++i)
484 ib_uverbs_event_release(&file->comp_file[i]);
485
486 kref_put(&file->ref, ib_uverbs_release_file);
487
488 return 0;
489}
490
491static struct file_operations uverbs_fops = {
492 .owner = THIS_MODULE,
493 .write = ib_uverbs_write,
494 .open = ib_uverbs_open,
495 .release = ib_uverbs_close
496};
497
498static struct file_operations uverbs_mmap_fops = {
499 .owner = THIS_MODULE,
500 .write = ib_uverbs_write,
501 .mmap = ib_uverbs_mmap,
502 .open = ib_uverbs_open,
503 .release = ib_uverbs_close
504};
505
506static struct ib_client uverbs_client = {
507 .name = "uverbs",
508 .add = ib_uverbs_add_one,
509 .remove = ib_uverbs_remove_one
510};
511
512static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
513{
514 struct ib_uverbs_device *dev =
515 container_of(class_dev, struct ib_uverbs_device, class_dev);
516
517 return sprintf(buf, "%s\n", dev->ib_dev->name);
518}
519static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
520
521static void ib_uverbs_release_class_dev(struct class_device *class_dev)
522{
523 struct ib_uverbs_device *dev =
524 container_of(class_dev, struct ib_uverbs_device, class_dev);
525
526 cdev_del(&dev->dev);
527 clear_bit(dev->devnum, dev_map);
528 kfree(dev);
529}
530
531static struct class uverbs_class = {
532 .name = "infiniband_verbs",
533 .release = ib_uverbs_release_class_dev
534};
535
536static ssize_t show_abi_version(struct class *class, char *buf)
537{
538 return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION);
539}
540static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
541
542static void ib_uverbs_add_one(struct ib_device *device)
543{
544 struct ib_uverbs_device *uverbs_dev;
545
546 if (!device->alloc_ucontext)
547 return;
548
549 uverbs_dev = kmalloc(sizeof *uverbs_dev, GFP_KERNEL);
550 if (!uverbs_dev)
551 return;
552
553 memset(uverbs_dev, 0, sizeof *uverbs_dev);
554
555 spin_lock(&map_lock);
556 uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
557 if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) {
558 spin_unlock(&map_lock);
559 goto err;
560 }
561 set_bit(uverbs_dev->devnum, dev_map);
562 spin_unlock(&map_lock);
563
564 uverbs_dev->ib_dev = device;
565 uverbs_dev->num_comp = 1;
566
567 if (device->mmap)
568 cdev_init(&uverbs_dev->dev, &uverbs_mmap_fops);
569 else
570 cdev_init(&uverbs_dev->dev, &uverbs_fops);
571 uverbs_dev->dev.owner = THIS_MODULE;
572 kobject_set_name(&uverbs_dev->dev.kobj, "uverbs%d", uverbs_dev->devnum);
573 if (cdev_add(&uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
574 goto err;
575
576 uverbs_dev->class_dev.class = &uverbs_class;
577 uverbs_dev->class_dev.dev = device->dma_device;
578 uverbs_dev->class_dev.devt = uverbs_dev->dev.dev;
579 snprintf(uverbs_dev->class_dev.class_id, BUS_ID_SIZE, "uverbs%d", uverbs_dev->devnum);
580 if (class_device_register(&uverbs_dev->class_dev))
581 goto err_cdev;
582
583 if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_ibdev))
584 goto err_class;
585
586 ib_set_client_data(device, &uverbs_client, uverbs_dev);
587
588 return;
589
590err_class:
591 class_device_unregister(&uverbs_dev->class_dev);
592
593err_cdev:
594 cdev_del(&uverbs_dev->dev);
595 clear_bit(uverbs_dev->devnum, dev_map);
596
597err:
598 kfree(uverbs_dev);
599 return;
600}
601
602static void ib_uverbs_remove_one(struct ib_device *device)
603{
604 struct ib_uverbs_device *uverbs_dev = ib_get_client_data(device, &uverbs_client);
605
606 if (!uverbs_dev)
607 return;
608
609 class_device_unregister(&uverbs_dev->class_dev);
610}
611
612static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
613 const char *dev_name, void *data)
614{
615 return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
616 INFINIBANDEVENTFS_MAGIC);
617}
618
619static struct file_system_type uverbs_event_fs = {
620 /* No owner field so module can be unloaded */
621 .name = "infinibandeventfs",
622 .get_sb = uverbs_event_get_sb,
623 .kill_sb = kill_litter_super
624};
625
626static int __init ib_uverbs_init(void)
627{
628 int ret;
629
630 spin_lock_init(&map_lock);
631
632 ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES,
633 "infiniband_verbs");
634 if (ret) {
635 printk(KERN_ERR "user_verbs: couldn't register device number\n");
636 goto out;
637 }
638
639 ret = class_register(&uverbs_class);
640 if (ret) {
641 printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n");
642 goto out_chrdev;
643 }
644
645 ret = class_create_file(&uverbs_class, &class_attr_abi_version);
646 if (ret) {
647 printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
648 goto out_class;
649 }
650
651 ret = register_filesystem(&uverbs_event_fs);
652 if (ret) {
653 printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n");
654 goto out_class;
655 }
656
657 uverbs_event_mnt = kern_mount(&uverbs_event_fs);
658 if (IS_ERR(uverbs_event_mnt)) {
659 ret = PTR_ERR(uverbs_event_mnt);
660 printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n");
661 goto out_fs;
662 }
663
664 ret = ib_register_client(&uverbs_client);
665 if (ret) {
666 printk(KERN_ERR "user_verbs: couldn't register client\n");
667 goto out_mnt;
668 }
669
670 return 0;
671
672out_mnt:
673 mntput(uverbs_event_mnt);
674
675out_fs:
676 unregister_filesystem(&uverbs_event_fs);
677
678out_class:
679 class_unregister(&uverbs_class);
680
681out_chrdev:
682 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
683
684out:
685 return ret;
686}
687
688static void __exit ib_uverbs_cleanup(void)
689{
690 ib_unregister_client(&uverbs_client);
691 mntput(uverbs_event_mnt);
692 unregister_filesystem(&uverbs_event_fs);
693 class_unregister(&uverbs_class);
694 unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
695}
696
697module_init(ib_uverbs_init);
698module_exit(ib_uverbs_cleanup);
diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c
new file mode 100644
index 000000000000..ed550f6595bd
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_mem.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 * $Id: uverbs_mem.c 2743 2005-06-28 22:27:59Z roland $
34 */
35
36#include <linux/mm.h>
37#include <linux/dma-mapping.h>
38
39#include "uverbs.h"
40
41struct ib_umem_account_work {
42 struct work_struct work;
43 struct mm_struct *mm;
44 unsigned long diff;
45};
46
47
48static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty)
49{
50 struct ib_umem_chunk *chunk, *tmp;
51 int i;
52
53 list_for_each_entry_safe(chunk, tmp, &umem->chunk_list, list) {
54 dma_unmap_sg(dev->dma_device, chunk->page_list,
55 chunk->nents, DMA_BIDIRECTIONAL);
56 for (i = 0; i < chunk->nents; ++i) {
57 if (umem->writable && dirty)
58 set_page_dirty_lock(chunk->page_list[i].page);
59 put_page(chunk->page_list[i].page);
60 }
61
62 kfree(chunk);
63 }
64}
65
66int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
67 void *addr, size_t size, int write)
68{
69 struct page **page_list;
70 struct ib_umem_chunk *chunk;
71 unsigned long locked;
72 unsigned long lock_limit;
73 unsigned long cur_base;
74 unsigned long npages;
75 int ret = 0;
76 int off;
77 int i;
78
79 if (!can_do_mlock())
80 return -EPERM;
81
82 page_list = (struct page **) __get_free_page(GFP_KERNEL);
83 if (!page_list)
84 return -ENOMEM;
85
86 mem->user_base = (unsigned long) addr;
87 mem->length = size;
88 mem->offset = (unsigned long) addr & ~PAGE_MASK;
89 mem->page_size = PAGE_SIZE;
90 mem->writable = write;
91
92 INIT_LIST_HEAD(&mem->chunk_list);
93
94 npages = PAGE_ALIGN(size + mem->offset) >> PAGE_SHIFT;
95
96 down_write(&current->mm->mmap_sem);
97
98 locked = npages + current->mm->locked_vm;
99 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
100
101 if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
102 ret = -ENOMEM;
103 goto out;
104 }
105
106 cur_base = (unsigned long) addr & PAGE_MASK;
107
108 while (npages) {
109 ret = get_user_pages(current, current->mm, cur_base,
110 min_t(int, npages,
111 PAGE_SIZE / sizeof (struct page *)),
112 1, !write, page_list, NULL);
113
114 if (ret < 0)
115 goto out;
116
117 cur_base += ret * PAGE_SIZE;
118 npages -= ret;
119
120 off = 0;
121
122 while (ret) {
123 chunk = kmalloc(sizeof *chunk + sizeof (struct scatterlist) *
124 min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK),
125 GFP_KERNEL);
126 if (!chunk) {
127 ret = -ENOMEM;
128 goto out;
129 }
130
131 chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
132 for (i = 0; i < chunk->nents; ++i) {
133 chunk->page_list[i].page = page_list[i + off];
134 chunk->page_list[i].offset = 0;
135 chunk->page_list[i].length = PAGE_SIZE;
136 }
137
138 chunk->nmap = dma_map_sg(dev->dma_device,
139 &chunk->page_list[0],
140 chunk->nents,
141 DMA_BIDIRECTIONAL);
142 if (chunk->nmap <= 0) {
143 for (i = 0; i < chunk->nents; ++i)
144 put_page(chunk->page_list[i].page);
145 kfree(chunk);
146
147 ret = -ENOMEM;
148 goto out;
149 }
150
151 ret -= chunk->nents;
152 off += chunk->nents;
153 list_add_tail(&chunk->list, &mem->chunk_list);
154 }
155
156 ret = 0;
157 }
158
159out:
160 if (ret < 0)
161 __ib_umem_release(dev, mem, 0);
162 else
163 current->mm->locked_vm = locked;
164
165 up_write(&current->mm->mmap_sem);
166 free_page((unsigned long) page_list);
167
168 return ret;
169}
170
171void ib_umem_release(struct ib_device *dev, struct ib_umem *umem)
172{
173 __ib_umem_release(dev, umem, 1);
174
175 down_write(&current->mm->mmap_sem);
176 current->mm->locked_vm -=
177 PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
178 up_write(&current->mm->mmap_sem);
179}
180
181static void ib_umem_account(void *work_ptr)
182{
183 struct ib_umem_account_work *work = work_ptr;
184
185 down_write(&work->mm->mmap_sem);
186 work->mm->locked_vm -= work->diff;
187 up_write(&work->mm->mmap_sem);
188 mmput(work->mm);
189 kfree(work);
190}
191
192void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem)
193{
194 struct ib_umem_account_work *work;
195 struct mm_struct *mm;
196
197 __ib_umem_release(dev, umem, 1);
198
199 mm = get_task_mm(current);
200 if (!mm)
201 return;
202
203 /*
204 * We may be called with the mm's mmap_sem already held. This
205 * can happen when a userspace munmap() is the call that drops
206 * the last reference to our file and calls our release
207 * method. If there are memory regions to destroy, we'll end
208 * up here and not be able to take the mmap_sem. Therefore we
209 * defer the vm_locked accounting to the system workqueue.
210 */
211
212 work = kmalloc(sizeof *work, GFP_KERNEL);
213 if (!work)
214 return;
215
216 INIT_WORK(&work->work, ib_umem_account, work);
217 work->mm = mm;
218 work->diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
219
220 schedule_work(&work->work);
221}
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 7c08ed0cd7dd..2516f9646515 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -4,6 +4,7 @@
4 * Copyright (c) 2004 Intel Corporation. All rights reserved. 4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 * Copyright (c) 2005 Cisco Systems. All rights reserved.
7 * 8 *
8 * This software is available to you under a choice of one of two 9 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU 10 * licenses. You may choose to be licensed under the terms of the GNU
@@ -47,10 +48,11 @@ struct ib_pd *ib_alloc_pd(struct ib_device *device)
47{ 48{
48 struct ib_pd *pd; 49 struct ib_pd *pd;
49 50
50 pd = device->alloc_pd(device); 51 pd = device->alloc_pd(device, NULL, NULL);
51 52
52 if (!IS_ERR(pd)) { 53 if (!IS_ERR(pd)) {
53 pd->device = device; 54 pd->device = device;
55 pd->uobject = NULL;
54 atomic_set(&pd->usecnt, 0); 56 atomic_set(&pd->usecnt, 0);
55 } 57 }
56 58
@@ -76,8 +78,9 @@ struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
76 ah = pd->device->create_ah(pd, ah_attr); 78 ah = pd->device->create_ah(pd, ah_attr);
77 79
78 if (!IS_ERR(ah)) { 80 if (!IS_ERR(ah)) {
79 ah->device = pd->device; 81 ah->device = pd->device;
80 ah->pd = pd; 82 ah->pd = pd;
83 ah->uobject = NULL;
81 atomic_inc(&pd->usecnt); 84 atomic_inc(&pd->usecnt);
82 } 85 }
83 86
@@ -122,7 +125,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
122{ 125{
123 struct ib_qp *qp; 126 struct ib_qp *qp;
124 127
125 qp = pd->device->create_qp(pd, qp_init_attr); 128 qp = pd->device->create_qp(pd, qp_init_attr, NULL);
126 129
127 if (!IS_ERR(qp)) { 130 if (!IS_ERR(qp)) {
128 qp->device = pd->device; 131 qp->device = pd->device;
@@ -130,6 +133,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
130 qp->send_cq = qp_init_attr->send_cq; 133 qp->send_cq = qp_init_attr->send_cq;
131 qp->recv_cq = qp_init_attr->recv_cq; 134 qp->recv_cq = qp_init_attr->recv_cq;
132 qp->srq = qp_init_attr->srq; 135 qp->srq = qp_init_attr->srq;
136 qp->uobject = NULL;
133 qp->event_handler = qp_init_attr->event_handler; 137 qp->event_handler = qp_init_attr->event_handler;
134 qp->qp_context = qp_init_attr->qp_context; 138 qp->qp_context = qp_init_attr->qp_context;
135 qp->qp_type = qp_init_attr->qp_type; 139 qp->qp_type = qp_init_attr->qp_type;
@@ -197,10 +201,11 @@ struct ib_cq *ib_create_cq(struct ib_device *device,
197{ 201{
198 struct ib_cq *cq; 202 struct ib_cq *cq;
199 203
200 cq = device->create_cq(device, cqe); 204 cq = device->create_cq(device, cqe, NULL, NULL);
201 205
202 if (!IS_ERR(cq)) { 206 if (!IS_ERR(cq)) {
203 cq->device = device; 207 cq->device = device;
208 cq->uobject = NULL;
204 cq->comp_handler = comp_handler; 209 cq->comp_handler = comp_handler;
205 cq->event_handler = event_handler; 210 cq->event_handler = event_handler;
206 cq->cq_context = cq_context; 211 cq->cq_context = cq_context;
@@ -245,8 +250,9 @@ struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
245 mr = pd->device->get_dma_mr(pd, mr_access_flags); 250 mr = pd->device->get_dma_mr(pd, mr_access_flags);
246 251
247 if (!IS_ERR(mr)) { 252 if (!IS_ERR(mr)) {
248 mr->device = pd->device; 253 mr->device = pd->device;
249 mr->pd = pd; 254 mr->pd = pd;
255 mr->uobject = NULL;
250 atomic_inc(&pd->usecnt); 256 atomic_inc(&pd->usecnt);
251 atomic_set(&mr->usecnt, 0); 257 atomic_set(&mr->usecnt, 0);
252 } 258 }
@@ -267,8 +273,9 @@ struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
267 mr_access_flags, iova_start); 273 mr_access_flags, iova_start);
268 274
269 if (!IS_ERR(mr)) { 275 if (!IS_ERR(mr)) {
270 mr->device = pd->device; 276 mr->device = pd->device;
271 mr->pd = pd; 277 mr->pd = pd;
278 mr->uobject = NULL;
272 atomic_inc(&pd->usecnt); 279 atomic_inc(&pd->usecnt);
273 atomic_set(&mr->usecnt, 0); 280 atomic_set(&mr->usecnt, 0);
274 } 281 }
@@ -344,8 +351,9 @@ struct ib_mw *ib_alloc_mw(struct ib_pd *pd)
344 351
345 mw = pd->device->alloc_mw(pd); 352 mw = pd->device->alloc_mw(pd);
346 if (!IS_ERR(mw)) { 353 if (!IS_ERR(mw)) {
347 mw->device = pd->device; 354 mw->device = pd->device;
348 mw->pd = pd; 355 mw->pd = pd;
356 mw->uobject = NULL;
349 atomic_inc(&pd->usecnt); 357 atomic_inc(&pd->usecnt);
350 } 358 }
351 359
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 766e9031ec45..b5aea7b869f6 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -742,6 +743,7 @@ err_out:
742} 743}
743 744
744int mthca_init_cq(struct mthca_dev *dev, int nent, 745int mthca_init_cq(struct mthca_dev *dev, int nent,
746 struct mthca_ucontext *ctx, u32 pdn,
745 struct mthca_cq *cq) 747 struct mthca_cq *cq)
746{ 748{
747 int size = nent * MTHCA_CQ_ENTRY_SIZE; 749 int size = nent * MTHCA_CQ_ENTRY_SIZE;
@@ -753,30 +755,33 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
753 755
754 might_sleep(); 756 might_sleep();
755 757
756 cq->ibcq.cqe = nent - 1; 758 cq->ibcq.cqe = nent - 1;
759 cq->is_kernel = !ctx;
757 760
758 cq->cqn = mthca_alloc(&dev->cq_table.alloc); 761 cq->cqn = mthca_alloc(&dev->cq_table.alloc);
759 if (cq->cqn == -1) 762 if (cq->cqn == -1)
760 return -ENOMEM; 763 return -ENOMEM;
761 764
762 if (mthca_is_memfree(dev)) { 765 if (mthca_is_memfree(dev)) {
763 cq->arm_sn = 1;
764
765 err = mthca_table_get(dev, dev->cq_table.table, cq->cqn); 766 err = mthca_table_get(dev, dev->cq_table.table, cq->cqn);
766 if (err) 767 if (err)
767 goto err_out; 768 goto err_out;
768 769
769 err = -ENOMEM; 770 if (cq->is_kernel) {
771 cq->arm_sn = 1;
772
773 err = -ENOMEM;
770 774
771 cq->set_ci_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, 775 cq->set_ci_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_SET_CI,
772 cq->cqn, &cq->set_ci_db); 776 cq->cqn, &cq->set_ci_db);
773 if (cq->set_ci_db_index < 0) 777 if (cq->set_ci_db_index < 0)
774 goto err_out_icm; 778 goto err_out_icm;
775 779
776 cq->arm_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_ARM, 780 cq->arm_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_ARM,
777 cq->cqn, &cq->arm_db); 781 cq->cqn, &cq->arm_db);
778 if (cq->arm_db_index < 0) 782 if (cq->arm_db_index < 0)
779 goto err_out_ci; 783 goto err_out_ci;
784 }
780 } 785 }
781 786
782 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); 787 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
@@ -785,12 +790,14 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
785 790
786 cq_context = mailbox->buf; 791 cq_context = mailbox->buf;
787 792
788 err = mthca_alloc_cq_buf(dev, size, cq); 793 if (cq->is_kernel) {
789 if (err) 794 err = mthca_alloc_cq_buf(dev, size, cq);
790 goto err_out_mailbox; 795 if (err)
796 goto err_out_mailbox;
791 797
792 for (i = 0; i < nent; ++i) 798 for (i = 0; i < nent; ++i)
793 set_cqe_hw(get_cqe(cq, i)); 799 set_cqe_hw(get_cqe(cq, i));
800 }
794 801
795 spin_lock_init(&cq->lock); 802 spin_lock_init(&cq->lock);
796 atomic_set(&cq->refcount, 1); 803 atomic_set(&cq->refcount, 1);
@@ -801,11 +808,14 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
801 MTHCA_CQ_STATE_DISARMED | 808 MTHCA_CQ_STATE_DISARMED |
802 MTHCA_CQ_FLAG_TR); 809 MTHCA_CQ_FLAG_TR);
803 cq_context->start = cpu_to_be64(0); 810 cq_context->start = cpu_to_be64(0);
804 cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24 | 811 cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
805 dev->driver_uar.index); 812 if (ctx)
813 cq_context->logsize_usrpage |= cpu_to_be32(ctx->uar.index);
814 else
815 cq_context->logsize_usrpage |= cpu_to_be32(dev->driver_uar.index);
806 cq_context->error_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn); 816 cq_context->error_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn);
807 cq_context->comp_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_COMP].eqn); 817 cq_context->comp_eqn = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_COMP].eqn);
808 cq_context->pd = cpu_to_be32(dev->driver_pd.pd_num); 818 cq_context->pd = cpu_to_be32(pdn);
809 cq_context->lkey = cpu_to_be32(cq->mr.ibmr.lkey); 819 cq_context->lkey = cpu_to_be32(cq->mr.ibmr.lkey);
810 cq_context->cqn = cpu_to_be32(cq->cqn); 820 cq_context->cqn = cpu_to_be32(cq->cqn);
811 821
@@ -843,18 +853,20 @@ int mthca_init_cq(struct mthca_dev *dev, int nent,
843 return 0; 853 return 0;
844 854
845err_out_free_mr: 855err_out_free_mr:
846 mthca_free_mr(dev, &cq->mr); 856 if (cq->is_kernel) {
847 mthca_free_cq_buf(dev, cq); 857 mthca_free_mr(dev, &cq->mr);
858 mthca_free_cq_buf(dev, cq);
859 }
848 860
849err_out_mailbox: 861err_out_mailbox:
850 mthca_free_mailbox(dev, mailbox); 862 mthca_free_mailbox(dev, mailbox);
851 863
852err_out_arm: 864err_out_arm:
853 if (mthca_is_memfree(dev)) 865 if (cq->is_kernel && mthca_is_memfree(dev))
854 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index); 866 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
855 867
856err_out_ci: 868err_out_ci:
857 if (mthca_is_memfree(dev)) 869 if (cq->is_kernel && mthca_is_memfree(dev))
858 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index); 870 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
859 871
860err_out_icm: 872err_out_icm:
@@ -892,7 +904,8 @@ void mthca_free_cq(struct mthca_dev *dev,
892 int j; 904 int j;
893 905
894 printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n", 906 printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n",
895 cq->cqn, cq->cons_index, !!next_cqe_sw(cq)); 907 cq->cqn, cq->cons_index,
908 cq->is_kernel ? !!next_cqe_sw(cq) : 0);
896 for (j = 0; j < 16; ++j) 909 for (j = 0; j < 16; ++j)
897 printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j])); 910 printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j]));
898 } 911 }
@@ -910,12 +923,13 @@ void mthca_free_cq(struct mthca_dev *dev,
910 atomic_dec(&cq->refcount); 923 atomic_dec(&cq->refcount);
911 wait_event(cq->wait, !atomic_read(&cq->refcount)); 924 wait_event(cq->wait, !atomic_read(&cq->refcount));
912 925
913 mthca_free_mr(dev, &cq->mr); 926 if (cq->is_kernel) {
914 mthca_free_cq_buf(dev, cq); 927 mthca_free_mr(dev, &cq->mr);
915 928 mthca_free_cq_buf(dev, cq);
916 if (mthca_is_memfree(dev)) { 929 if (mthca_is_memfree(dev)) {
917 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index); 930 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
918 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index); 931 mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
932 }
919 } 933 }
920 934
921 mthca_table_put(dev, dev->cq_table.table, cq->cqn); 935 mthca_table_put(dev, dev->cq_table.table, cq->cqn);
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 4127f09dc5ec..5ecdd2eeeb0f 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -378,7 +379,7 @@ void mthca_unregister_device(struct mthca_dev *dev);
378int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar); 379int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);
379void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar); 380void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);
380 381
381int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd); 382int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd);
382void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd); 383void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd);
383 384
384struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size); 385struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size);
@@ -413,6 +414,7 @@ int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
413int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify); 414int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
414int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify); 415int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
415int mthca_init_cq(struct mthca_dev *dev, int nent, 416int mthca_init_cq(struct mthca_dev *dev, int nent,
417 struct mthca_ucontext *ctx, u32 pdn,
416 struct mthca_cq *cq); 418 struct mthca_cq *cq);
417void mthca_free_cq(struct mthca_dev *dev, 419void mthca_free_cq(struct mthca_dev *dev,
418 struct mthca_cq *cq); 420 struct mthca_cq *cq);
@@ -438,12 +440,14 @@ int mthca_alloc_qp(struct mthca_dev *dev,
438 struct mthca_cq *recv_cq, 440 struct mthca_cq *recv_cq,
439 enum ib_qp_type type, 441 enum ib_qp_type type,
440 enum ib_sig_type send_policy, 442 enum ib_sig_type send_policy,
443 struct ib_qp_cap *cap,
441 struct mthca_qp *qp); 444 struct mthca_qp *qp);
442int mthca_alloc_sqp(struct mthca_dev *dev, 445int mthca_alloc_sqp(struct mthca_dev *dev,
443 struct mthca_pd *pd, 446 struct mthca_pd *pd,
444 struct mthca_cq *send_cq, 447 struct mthca_cq *send_cq,
445 struct mthca_cq *recv_cq, 448 struct mthca_cq *recv_cq,
446 enum ib_sig_type send_policy, 449 enum ib_sig_type send_policy,
450 struct ib_qp_cap *cap,
447 int qpn, 451 int qpn,
448 int port, 452 int port,
449 struct mthca_sqp *sqp); 453 struct mthca_sqp *sqp);
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 09519b604c08..2ef916859e17 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -665,7 +665,7 @@ static int __devinit mthca_setup_hca(struct mthca_dev *dev)
665 goto err_pd_table_free; 665 goto err_pd_table_free;
666 } 666 }
667 667
668 err = mthca_pd_alloc(dev, &dev->driver_pd); 668 err = mthca_pd_alloc(dev, 1, &dev->driver_pd);
669 if (err) { 669 if (err) {
670 mthca_err(dev, "Failed to create driver PD, " 670 mthca_err(dev, "Failed to create driver PD, "
671 "aborting.\n"); 671 "aborting.\n");
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 6d3b05dd9e3f..2a8646150355 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -47,6 +48,15 @@ enum {
47 MTHCA_TABLE_CHUNK_SIZE = 1 << 18 48 MTHCA_TABLE_CHUNK_SIZE = 1 << 18
48}; 49};
49 50
51struct mthca_user_db_table {
52 struct semaphore mutex;
53 struct {
54 u64 uvirt;
55 struct scatterlist mem;
56 int refcount;
57 } page[0];
58};
59
50void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm) 60void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
51{ 61{
52 struct mthca_icm_chunk *chunk, *tmp; 62 struct mthca_icm_chunk *chunk, *tmp;
@@ -344,13 +354,133 @@ void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table)
344 kfree(table); 354 kfree(table);
345} 355}
346 356
347static u64 mthca_uarc_virt(struct mthca_dev *dev, int page) 357static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int page)
348{ 358{
349 return dev->uar_table.uarc_base + 359 return dev->uar_table.uarc_base +
350 dev->driver_uar.index * dev->uar_table.uarc_size + 360 uar->index * dev->uar_table.uarc_size +
351 page * 4096; 361 page * 4096;
352} 362}
353 363
364int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
365 struct mthca_user_db_table *db_tab, int index, u64 uaddr)
366{
367 int ret = 0;
368 u8 status;
369 int i;
370
371 if (!mthca_is_memfree(dev))
372 return 0;
373
374 if (index < 0 || index > dev->uar_table.uarc_size / 8)
375 return -EINVAL;
376
377 down(&db_tab->mutex);
378
379 i = index / MTHCA_DB_REC_PER_PAGE;
380
381 if ((db_tab->page[i].refcount >= MTHCA_DB_REC_PER_PAGE) ||
382 (db_tab->page[i].uvirt && db_tab->page[i].uvirt != uaddr) ||
383 (uaddr & 4095)) {
384 ret = -EINVAL;
385 goto out;
386 }
387
388 if (db_tab->page[i].refcount) {
389 ++db_tab->page[i].refcount;
390 goto out;
391 }
392
393 ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
394 &db_tab->page[i].mem.page, NULL);
395 if (ret < 0)
396 goto out;
397
398 db_tab->page[i].mem.length = 4096;
399 db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
400
401 ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
402 if (ret < 0) {
403 put_page(db_tab->page[i].mem.page);
404 goto out;
405 }
406
407 ret = mthca_MAP_ICM_page(dev, sg_dma_address(&db_tab->page[i].mem),
408 mthca_uarc_virt(dev, uar, i), &status);
409 if (!ret && status)
410 ret = -EINVAL;
411 if (ret) {
412 pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
413 put_page(db_tab->page[i].mem.page);
414 goto out;
415 }
416
417 db_tab->page[i].uvirt = uaddr;
418 db_tab->page[i].refcount = 1;
419
420out:
421 up(&db_tab->mutex);
422 return ret;
423}
424
425void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
426 struct mthca_user_db_table *db_tab, int index)
427{
428 if (!mthca_is_memfree(dev))
429 return;
430
431 /*
432 * To make our bookkeeping simpler, we don't unmap DB
433 * pages until we clean up the whole db table.
434 */
435
436 down(&db_tab->mutex);
437
438 --db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount;
439
440 up(&db_tab->mutex);
441}
442
443struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
444{
445 struct mthca_user_db_table *db_tab;
446 int npages;
447 int i;
448
449 if (!mthca_is_memfree(dev))
450 return NULL;
451
452 npages = dev->uar_table.uarc_size / 4096;
453 db_tab = kmalloc(sizeof *db_tab + npages * sizeof *db_tab->page, GFP_KERNEL);
454 if (!db_tab)
455 return ERR_PTR(-ENOMEM);
456
457 init_MUTEX(&db_tab->mutex);
458 for (i = 0; i < npages; ++i) {
459 db_tab->page[i].refcount = 0;
460 db_tab->page[i].uvirt = 0;
461 }
462
463 return db_tab;
464}
465
466void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
467 struct mthca_user_db_table *db_tab)
468{
469 int i;
470 u8 status;
471
472 if (!mthca_is_memfree(dev))
473 return;
474
475 for (i = 0; i < dev->uar_table.uarc_size / 4096; ++i) {
476 if (db_tab->page[i].uvirt) {
477 mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
478 pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
479 put_page(db_tab->page[i].mem.page);
480 }
481 }
482}
483
354int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db) 484int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db)
355{ 485{
356 int group; 486 int group;
@@ -407,7 +537,8 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db)
407 } 537 }
408 memset(page->db_rec, 0, 4096); 538 memset(page->db_rec, 0, 4096);
409 539
410 ret = mthca_MAP_ICM_page(dev, page->mapping, mthca_uarc_virt(dev, i), &status); 540 ret = mthca_MAP_ICM_page(dev, page->mapping,
541 mthca_uarc_virt(dev, &dev->driver_uar, i), &status);
411 if (!ret && status) 542 if (!ret && status)
412 ret = -EINVAL; 543 ret = -EINVAL;
413 if (ret) { 544 if (ret) {
@@ -461,7 +592,7 @@ void mthca_free_db(struct mthca_dev *dev, int type, int db_index)
461 592
462 if (bitmap_empty(page->used, MTHCA_DB_REC_PER_PAGE) && 593 if (bitmap_empty(page->used, MTHCA_DB_REC_PER_PAGE) &&
463 i >= dev->db_tab->max_group1 - 1) { 594 i >= dev->db_tab->max_group1 - 1) {
464 mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, i), 1, &status); 595 mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
465 596
466 dma_free_coherent(&dev->pdev->dev, 4096, 597 dma_free_coherent(&dev->pdev->dev, 4096,
467 page->db_rec, page->mapping); 598 page->db_rec, page->mapping);
@@ -530,7 +661,7 @@ void mthca_cleanup_db_tab(struct mthca_dev *dev)
530 if (!bitmap_empty(dev->db_tab->page[i].used, MTHCA_DB_REC_PER_PAGE)) 661 if (!bitmap_empty(dev->db_tab->page[i].used, MTHCA_DB_REC_PER_PAGE))
531 mthca_warn(dev, "Kernel UARC page %d not empty\n", i); 662 mthca_warn(dev, "Kernel UARC page %d not empty\n", i);
532 663
533 mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, i), 1, &status); 664 mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
534 665
535 dma_free_coherent(&dev->pdev->dev, 4096, 666 dma_free_coherent(&dev->pdev->dev, 4096,
536 dev->db_tab->page[i].db_rec, 667 dev->db_tab->page[i].db_rec,
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index fe7be2a6bc4a..4761d844cb5f 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -148,7 +149,7 @@ struct mthca_db_table {
148 struct semaphore mutex; 149 struct semaphore mutex;
149}; 150};
150 151
151enum { 152enum mthca_db_type {
152 MTHCA_DB_TYPE_INVALID = 0x0, 153 MTHCA_DB_TYPE_INVALID = 0x0,
153 MTHCA_DB_TYPE_CQ_SET_CI = 0x1, 154 MTHCA_DB_TYPE_CQ_SET_CI = 0x1,
154 MTHCA_DB_TYPE_CQ_ARM = 0x2, 155 MTHCA_DB_TYPE_CQ_ARM = 0x2,
@@ -158,6 +159,17 @@ enum {
158 MTHCA_DB_TYPE_GROUP_SEP = 0x7 159 MTHCA_DB_TYPE_GROUP_SEP = 0x7
159}; 160};
160 161
162struct mthca_user_db_table;
163struct mthca_uar;
164
165int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
166 struct mthca_user_db_table *db_tab, int index, u64 uaddr);
167void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
168 struct mthca_user_db_table *db_tab, int index);
169struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev);
170void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
171 struct mthca_user_db_table *db_tab);
172
161int mthca_init_db_tab(struct mthca_dev *dev); 173int mthca_init_db_tab(struct mthca_dev *dev);
162void mthca_cleanup_db_tab(struct mthca_dev *dev); 174void mthca_cleanup_db_tab(struct mthca_dev *dev);
163int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db); 175int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db);
diff --git a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c
index ea66847e4ea3..c2c899844e98 100644
--- a/drivers/infiniband/hw/mthca/mthca_pd.c
+++ b/drivers/infiniband/hw/mthca/mthca_pd.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -37,23 +38,27 @@
37 38
38#include "mthca_dev.h" 39#include "mthca_dev.h"
39 40
40int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd) 41int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd)
41{ 42{
42 int err; 43 int err = 0;
43 44
44 might_sleep(); 45 might_sleep();
45 46
47 pd->privileged = privileged;
48
46 atomic_set(&pd->sqp_count, 0); 49 atomic_set(&pd->sqp_count, 0);
47 pd->pd_num = mthca_alloc(&dev->pd_table.alloc); 50 pd->pd_num = mthca_alloc(&dev->pd_table.alloc);
48 if (pd->pd_num == -1) 51 if (pd->pd_num == -1)
49 return -ENOMEM; 52 return -ENOMEM;
50 53
51 err = mthca_mr_alloc_notrans(dev, pd->pd_num, 54 if (privileged) {
52 MTHCA_MPT_FLAG_LOCAL_READ | 55 err = mthca_mr_alloc_notrans(dev, pd->pd_num,
53 MTHCA_MPT_FLAG_LOCAL_WRITE, 56 MTHCA_MPT_FLAG_LOCAL_READ |
54 &pd->ntmr); 57 MTHCA_MPT_FLAG_LOCAL_WRITE,
55 if (err) 58 &pd->ntmr);
56 mthca_free(&dev->pd_table.alloc, pd->pd_num); 59 if (err)
60 mthca_free(&dev->pd_table.alloc, pd->pd_num);
61 }
57 62
58 return err; 63 return err;
59} 64}
@@ -61,7 +66,8 @@ int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd)
61void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd) 66void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd)
62{ 67{
63 might_sleep(); 68 might_sleep();
64 mthca_free_mr(dev, &pd->ntmr); 69 if (pd->privileged)
70 mthca_free_mr(dev, &pd->ntmr);
65 mthca_free(&dev->pd_table.alloc, pd->pd_num); 71 mthca_free(&dev->pd_table.alloc, pd->pd_num);
66} 72}
67 73
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 0b5adfd91597..7a58ce90e179 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -34,9 +35,12 @@
34 */ 35 */
35 36
36#include <ib_smi.h> 37#include <ib_smi.h>
38#include <linux/mm.h>
37 39
38#include "mthca_dev.h" 40#include "mthca_dev.h"
39#include "mthca_cmd.h" 41#include "mthca_cmd.h"
42#include "mthca_user.h"
43#include "mthca_memfree.h"
40 44
41static int mthca_query_device(struct ib_device *ibdev, 45static int mthca_query_device(struct ib_device *ibdev,
42 struct ib_device_attr *props) 46 struct ib_device_attr *props)
@@ -284,7 +288,78 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port,
284 return err; 288 return err;
285} 289}
286 290
287static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev) 291static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev,
292 struct ib_udata *udata)
293{
294 struct mthca_alloc_ucontext_resp uresp;
295 struct mthca_ucontext *context;
296 int err;
297
298 memset(&uresp, 0, sizeof uresp);
299
300 uresp.qp_tab_size = to_mdev(ibdev)->limits.num_qps;
301 if (mthca_is_memfree(to_mdev(ibdev)))
302 uresp.uarc_size = to_mdev(ibdev)->uar_table.uarc_size;
303 else
304 uresp.uarc_size = 0;
305
306 context = kmalloc(sizeof *context, GFP_KERNEL);
307 if (!context)
308 return ERR_PTR(-ENOMEM);
309
310 err = mthca_uar_alloc(to_mdev(ibdev), &context->uar);
311 if (err) {
312 kfree(context);
313 return ERR_PTR(err);
314 }
315
316 context->db_tab = mthca_init_user_db_tab(to_mdev(ibdev));
317 if (IS_ERR(context->db_tab)) {
318 err = PTR_ERR(context->db_tab);
319 mthca_uar_free(to_mdev(ibdev), &context->uar);
320 kfree(context);
321 return ERR_PTR(err);
322 }
323
324 if (ib_copy_to_udata(udata, &uresp, sizeof uresp)) {
325 mthca_cleanup_user_db_tab(to_mdev(ibdev), &context->uar, context->db_tab);
326 mthca_uar_free(to_mdev(ibdev), &context->uar);
327 kfree(context);
328 return ERR_PTR(-EFAULT);
329 }
330
331 return &context->ibucontext;
332}
333
334static int mthca_dealloc_ucontext(struct ib_ucontext *context)
335{
336 mthca_cleanup_user_db_tab(to_mdev(context->device), &to_mucontext(context)->uar,
337 to_mucontext(context)->db_tab);
338 mthca_uar_free(to_mdev(context->device), &to_mucontext(context)->uar);
339 kfree(to_mucontext(context));
340
341 return 0;
342}
343
344static int mthca_mmap_uar(struct ib_ucontext *context,
345 struct vm_area_struct *vma)
346{
347 if (vma->vm_end - vma->vm_start != PAGE_SIZE)
348 return -EINVAL;
349
350 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
351
352 if (remap_pfn_range(vma, vma->vm_start,
353 to_mucontext(context)->uar.pfn,
354 PAGE_SIZE, vma->vm_page_prot))
355 return -EAGAIN;
356
357 return 0;
358}
359
360static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev,
361 struct ib_ucontext *context,
362 struct ib_udata *udata)
288{ 363{
289 struct mthca_pd *pd; 364 struct mthca_pd *pd;
290 int err; 365 int err;
@@ -293,12 +368,20 @@ static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev)
293 if (!pd) 368 if (!pd)
294 return ERR_PTR(-ENOMEM); 369 return ERR_PTR(-ENOMEM);
295 370
296 err = mthca_pd_alloc(to_mdev(ibdev), pd); 371 err = mthca_pd_alloc(to_mdev(ibdev), !context, pd);
297 if (err) { 372 if (err) {
298 kfree(pd); 373 kfree(pd);
299 return ERR_PTR(err); 374 return ERR_PTR(err);
300 } 375 }
301 376
377 if (context) {
378 if (ib_copy_to_udata(udata, &pd->pd_num, sizeof (__u32))) {
379 mthca_pd_free(to_mdev(ibdev), pd);
380 kfree(pd);
381 return ERR_PTR(-EFAULT);
382 }
383 }
384
302 return &pd->ibpd; 385 return &pd->ibpd;
303} 386}
304 387
@@ -338,8 +421,10 @@ static int mthca_ah_destroy(struct ib_ah *ah)
338} 421}
339 422
340static struct ib_qp *mthca_create_qp(struct ib_pd *pd, 423static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
341 struct ib_qp_init_attr *init_attr) 424 struct ib_qp_init_attr *init_attr,
425 struct ib_udata *udata)
342{ 426{
427 struct mthca_create_qp ucmd;
343 struct mthca_qp *qp; 428 struct mthca_qp *qp;
344 int err; 429 int err;
345 430
@@ -348,41 +433,82 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
348 case IB_QPT_UC: 433 case IB_QPT_UC:
349 case IB_QPT_UD: 434 case IB_QPT_UD:
350 { 435 {
436 struct mthca_ucontext *context;
437
351 qp = kmalloc(sizeof *qp, GFP_KERNEL); 438 qp = kmalloc(sizeof *qp, GFP_KERNEL);
352 if (!qp) 439 if (!qp)
353 return ERR_PTR(-ENOMEM); 440 return ERR_PTR(-ENOMEM);
354 441
355 qp->sq.max = init_attr->cap.max_send_wr; 442 if (pd->uobject) {
356 qp->rq.max = init_attr->cap.max_recv_wr; 443 context = to_mucontext(pd->uobject->context);
357 qp->sq.max_gs = init_attr->cap.max_send_sge; 444
358 qp->rq.max_gs = init_attr->cap.max_recv_sge; 445 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
446 return ERR_PTR(-EFAULT);
447
448 err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
449 context->db_tab,
450 ucmd.sq_db_index, ucmd.sq_db_page);
451 if (err) {
452 kfree(qp);
453 return ERR_PTR(err);
454 }
455
456 err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
457 context->db_tab,
458 ucmd.rq_db_index, ucmd.rq_db_page);
459 if (err) {
460 mthca_unmap_user_db(to_mdev(pd->device),
461 &context->uar,
462 context->db_tab,
463 ucmd.sq_db_index);
464 kfree(qp);
465 return ERR_PTR(err);
466 }
467
468 qp->mr.ibmr.lkey = ucmd.lkey;
469 qp->sq.db_index = ucmd.sq_db_index;
470 qp->rq.db_index = ucmd.rq_db_index;
471 }
359 472
360 err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd), 473 err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd),
361 to_mcq(init_attr->send_cq), 474 to_mcq(init_attr->send_cq),
362 to_mcq(init_attr->recv_cq), 475 to_mcq(init_attr->recv_cq),
363 init_attr->qp_type, init_attr->sq_sig_type, 476 init_attr->qp_type, init_attr->sq_sig_type,
364 qp); 477 &init_attr->cap, qp);
478
479 if (err && pd->uobject) {
480 context = to_mucontext(pd->uobject->context);
481
482 mthca_unmap_user_db(to_mdev(pd->device),
483 &context->uar,
484 context->db_tab,
485 ucmd.sq_db_index);
486 mthca_unmap_user_db(to_mdev(pd->device),
487 &context->uar,
488 context->db_tab,
489 ucmd.rq_db_index);
490 }
491
365 qp->ibqp.qp_num = qp->qpn; 492 qp->ibqp.qp_num = qp->qpn;
366 break; 493 break;
367 } 494 }
368 case IB_QPT_SMI: 495 case IB_QPT_SMI:
369 case IB_QPT_GSI: 496 case IB_QPT_GSI:
370 { 497 {
498 /* Don't allow userspace to create special QPs */
499 if (pd->uobject)
500 return ERR_PTR(-EINVAL);
501
371 qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL); 502 qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL);
372 if (!qp) 503 if (!qp)
373 return ERR_PTR(-ENOMEM); 504 return ERR_PTR(-ENOMEM);
374 505
375 qp->sq.max = init_attr->cap.max_send_wr;
376 qp->rq.max = init_attr->cap.max_recv_wr;
377 qp->sq.max_gs = init_attr->cap.max_send_sge;
378 qp->rq.max_gs = init_attr->cap.max_recv_sge;
379
380 qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1; 506 qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1;
381 507
382 err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd), 508 err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd),
383 to_mcq(init_attr->send_cq), 509 to_mcq(init_attr->send_cq),
384 to_mcq(init_attr->recv_cq), 510 to_mcq(init_attr->recv_cq),
385 init_attr->sq_sig_type, 511 init_attr->sq_sig_type, &init_attr->cap,
386 qp->ibqp.qp_num, init_attr->port_num, 512 qp->ibqp.qp_num, init_attr->port_num,
387 to_msqp(qp)); 513 to_msqp(qp));
388 break; 514 break;
@@ -397,42 +523,115 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
397 return ERR_PTR(err); 523 return ERR_PTR(err);
398 } 524 }
399 525
400 init_attr->cap.max_inline_data = 0; 526 init_attr->cap.max_inline_data = 0;
527 init_attr->cap.max_send_wr = qp->sq.max;
528 init_attr->cap.max_recv_wr = qp->rq.max;
529 init_attr->cap.max_send_sge = qp->sq.max_gs;
530 init_attr->cap.max_recv_sge = qp->rq.max_gs;
401 531
402 return &qp->ibqp; 532 return &qp->ibqp;
403} 533}
404 534
405static int mthca_destroy_qp(struct ib_qp *qp) 535static int mthca_destroy_qp(struct ib_qp *qp)
406{ 536{
537 if (qp->uobject) {
538 mthca_unmap_user_db(to_mdev(qp->device),
539 &to_mucontext(qp->uobject->context)->uar,
540 to_mucontext(qp->uobject->context)->db_tab,
541 to_mqp(qp)->sq.db_index);
542 mthca_unmap_user_db(to_mdev(qp->device),
543 &to_mucontext(qp->uobject->context)->uar,
544 to_mucontext(qp->uobject->context)->db_tab,
545 to_mqp(qp)->rq.db_index);
546 }
407 mthca_free_qp(to_mdev(qp->device), to_mqp(qp)); 547 mthca_free_qp(to_mdev(qp->device), to_mqp(qp));
408 kfree(qp); 548 kfree(qp);
409 return 0; 549 return 0;
410} 550}
411 551
412static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries) 552static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
553 struct ib_ucontext *context,
554 struct ib_udata *udata)
413{ 555{
556 struct mthca_create_cq ucmd;
414 struct mthca_cq *cq; 557 struct mthca_cq *cq;
415 int nent; 558 int nent;
416 int err; 559 int err;
417 560
561 if (context) {
562 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
563 return ERR_PTR(-EFAULT);
564
565 err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
566 to_mucontext(context)->db_tab,
567 ucmd.set_db_index, ucmd.set_db_page);
568 if (err)
569 return ERR_PTR(err);
570
571 err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
572 to_mucontext(context)->db_tab,
573 ucmd.arm_db_index, ucmd.arm_db_page);
574 if (err)
575 goto err_unmap_set;
576 }
577
418 cq = kmalloc(sizeof *cq, GFP_KERNEL); 578 cq = kmalloc(sizeof *cq, GFP_KERNEL);
419 if (!cq) 579 if (!cq) {
420 return ERR_PTR(-ENOMEM); 580 err = -ENOMEM;
581 goto err_unmap_arm;
582 }
583
584 if (context) {
585 cq->mr.ibmr.lkey = ucmd.lkey;
586 cq->set_ci_db_index = ucmd.set_db_index;
587 cq->arm_db_index = ucmd.arm_db_index;
588 }
421 589
422 for (nent = 1; nent <= entries; nent <<= 1) 590 for (nent = 1; nent <= entries; nent <<= 1)
423 ; /* nothing */ 591 ; /* nothing */
424 592
425 err = mthca_init_cq(to_mdev(ibdev), nent, cq); 593 err = mthca_init_cq(to_mdev(ibdev), nent,
426 if (err) { 594 context ? to_mucontext(context) : NULL,
427 kfree(cq); 595 context ? ucmd.pdn : to_mdev(ibdev)->driver_pd.pd_num,
428 cq = ERR_PTR(err); 596 cq);
597 if (err)
598 goto err_free;
599
600 if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) {
601 mthca_free_cq(to_mdev(ibdev), cq);
602 goto err_free;
429 } 603 }
430 604
431 return &cq->ibcq; 605 return &cq->ibcq;
606
607err_free:
608 kfree(cq);
609
610err_unmap_arm:
611 if (context)
612 mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
613 to_mucontext(context)->db_tab, ucmd.arm_db_index);
614
615err_unmap_set:
616 if (context)
617 mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
618 to_mucontext(context)->db_tab, ucmd.set_db_index);
619
620 return ERR_PTR(err);
432} 621}
433 622
434static int mthca_destroy_cq(struct ib_cq *cq) 623static int mthca_destroy_cq(struct ib_cq *cq)
435{ 624{
625 if (cq->uobject) {
626 mthca_unmap_user_db(to_mdev(cq->device),
627 &to_mucontext(cq->uobject->context)->uar,
628 to_mucontext(cq->uobject->context)->db_tab,
629 to_mcq(cq)->arm_db_index);
630 mthca_unmap_user_db(to_mdev(cq->device),
631 &to_mucontext(cq->uobject->context)->uar,
632 to_mucontext(cq->uobject->context)->db_tab,
633 to_mcq(cq)->set_ci_db_index);
634 }
436 mthca_free_cq(to_mdev(cq->device), to_mcq(cq)); 635 mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
437 kfree(cq); 636 kfree(cq);
438 637
@@ -568,6 +767,87 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd,
568 return &mr->ibmr; 767 return &mr->ibmr;
569} 768}
570 769
770static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
771 int acc, struct ib_udata *udata)
772{
773 struct mthca_dev *dev = to_mdev(pd->device);
774 struct ib_umem_chunk *chunk;
775 struct mthca_mr *mr;
776 u64 *pages;
777 int shift, n, len;
778 int i, j, k;
779 int err = 0;
780
781 shift = ffs(region->page_size) - 1;
782
783 mr = kmalloc(sizeof *mr, GFP_KERNEL);
784 if (!mr)
785 return ERR_PTR(-ENOMEM);
786
787 n = 0;
788 list_for_each_entry(chunk, &region->chunk_list, list)
789 n += chunk->nents;
790
791 mr->mtt = mthca_alloc_mtt(dev, n);
792 if (IS_ERR(mr->mtt)) {
793 err = PTR_ERR(mr->mtt);
794 goto err;
795 }
796
797 pages = (u64 *) __get_free_page(GFP_KERNEL);
798 if (!pages) {
799 err = -ENOMEM;
800 goto err_mtt;
801 }
802
803 i = n = 0;
804
805 list_for_each_entry(chunk, &region->chunk_list, list)
806 for (j = 0; j < chunk->nmap; ++j) {
807 len = sg_dma_len(&chunk->page_list[j]) >> shift;
808 for (k = 0; k < len; ++k) {
809 pages[i++] = sg_dma_address(&chunk->page_list[j]) +
810 region->page_size * k;
811 /*
812 * Be friendly to WRITE_MTT command
813 * and leave two empty slots for the
814 * index and reserved fields of the
815 * mailbox.
816 */
817 if (i == PAGE_SIZE / sizeof (u64) - 2) {
818 err = mthca_write_mtt(dev, mr->mtt,
819 n, pages, i);
820 if (err)
821 goto mtt_done;
822 n += i;
823 i = 0;
824 }
825 }
826 }
827
828 if (i)
829 err = mthca_write_mtt(dev, mr->mtt, n, pages, i);
830mtt_done:
831 free_page((unsigned long) pages);
832 if (err)
833 goto err_mtt;
834
835 err = mthca_mr_alloc(dev, to_mpd(pd)->pd_num, shift, region->virt_base,
836 region->length, convert_access(acc), mr);
837
838 if (err)
839 goto err_mtt;
840
841 return &mr->ibmr;
842
843err_mtt:
844 mthca_free_mtt(dev, mr->mtt);
845
846err:
847 kfree(mr);
848 return ERR_PTR(err);
849}
850
571static int mthca_dereg_mr(struct ib_mr *mr) 851static int mthca_dereg_mr(struct ib_mr *mr)
572{ 852{
573 struct mthca_mr *mmr = to_mmr(mr); 853 struct mthca_mr *mmr = to_mmr(mr);
@@ -692,6 +972,8 @@ int mthca_register_device(struct mthca_dev *dev)
692 int i; 972 int i;
693 973
694 strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX); 974 strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
975 dev->ib_dev.owner = THIS_MODULE;
976
695 dev->ib_dev.node_type = IB_NODE_CA; 977 dev->ib_dev.node_type = IB_NODE_CA;
696 dev->ib_dev.phys_port_cnt = dev->limits.num_ports; 978 dev->ib_dev.phys_port_cnt = dev->limits.num_ports;
697 dev->ib_dev.dma_device = &dev->pdev->dev; 979 dev->ib_dev.dma_device = &dev->pdev->dev;
@@ -701,6 +983,9 @@ int mthca_register_device(struct mthca_dev *dev)
701 dev->ib_dev.modify_port = mthca_modify_port; 983 dev->ib_dev.modify_port = mthca_modify_port;
702 dev->ib_dev.query_pkey = mthca_query_pkey; 984 dev->ib_dev.query_pkey = mthca_query_pkey;
703 dev->ib_dev.query_gid = mthca_query_gid; 985 dev->ib_dev.query_gid = mthca_query_gid;
986 dev->ib_dev.alloc_ucontext = mthca_alloc_ucontext;
987 dev->ib_dev.dealloc_ucontext = mthca_dealloc_ucontext;
988 dev->ib_dev.mmap = mthca_mmap_uar;
704 dev->ib_dev.alloc_pd = mthca_alloc_pd; 989 dev->ib_dev.alloc_pd = mthca_alloc_pd;
705 dev->ib_dev.dealloc_pd = mthca_dealloc_pd; 990 dev->ib_dev.dealloc_pd = mthca_dealloc_pd;
706 dev->ib_dev.create_ah = mthca_ah_create; 991 dev->ib_dev.create_ah = mthca_ah_create;
@@ -713,6 +998,7 @@ int mthca_register_device(struct mthca_dev *dev)
713 dev->ib_dev.poll_cq = mthca_poll_cq; 998 dev->ib_dev.poll_cq = mthca_poll_cq;
714 dev->ib_dev.get_dma_mr = mthca_get_dma_mr; 999 dev->ib_dev.get_dma_mr = mthca_get_dma_mr;
715 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr; 1000 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr;
1001 dev->ib_dev.reg_user_mr = mthca_reg_user_mr;
716 dev->ib_dev.dereg_mr = mthca_dereg_mr; 1002 dev->ib_dev.dereg_mr = mthca_dereg_mr;
717 1003
718 if (dev->mthca_flags & MTHCA_FLAG_FMR) { 1004 if (dev->mthca_flags & MTHCA_FLAG_FMR) {
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index 4d976cccb1a8..1d032791cc8b 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -54,6 +55,14 @@ struct mthca_uar {
54 int index; 55 int index;
55}; 56};
56 57
58struct mthca_user_db_table;
59
60struct mthca_ucontext {
61 struct ib_ucontext ibucontext;
62 struct mthca_uar uar;
63 struct mthca_user_db_table *db_tab;
64};
65
57struct mthca_mtt; 66struct mthca_mtt;
58 67
59struct mthca_mr { 68struct mthca_mr {
@@ -83,6 +92,7 @@ struct mthca_pd {
83 u32 pd_num; 92 u32 pd_num;
84 atomic_t sqp_count; 93 atomic_t sqp_count;
85 struct mthca_mr ntmr; 94 struct mthca_mr ntmr;
95 int privileged;
86}; 96};
87 97
88struct mthca_eq { 98struct mthca_eq {
@@ -167,6 +177,7 @@ struct mthca_cq {
167 int cqn; 177 int cqn;
168 u32 cons_index; 178 u32 cons_index;
169 int is_direct; 179 int is_direct;
180 int is_kernel;
170 181
171 /* Next fields are Arbel only */ 182 /* Next fields are Arbel only */
172 int set_ci_db_index; 183 int set_ci_db_index;
@@ -236,6 +247,11 @@ struct mthca_sqp {
236 dma_addr_t header_dma; 247 dma_addr_t header_dma;
237}; 248};
238 249
250static inline struct mthca_ucontext *to_mucontext(struct ib_ucontext *ibucontext)
251{
252 return container_of(ibucontext, struct mthca_ucontext, ibucontext);
253}
254
239static inline struct mthca_fmr *to_mfmr(struct ib_fmr *ibmr) 255static inline struct mthca_fmr *to_mfmr(struct ib_fmr *ibmr)
240{ 256{
241 return container_of(ibmr, struct mthca_fmr, ibmr); 257 return container_of(ibmr, struct mthca_fmr, ibmr);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 163a8ef4186f..f7126b14d5ae 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -46,7 +47,9 @@ enum {
46 MTHCA_MAX_DIRECT_QP_SIZE = 4 * PAGE_SIZE, 47 MTHCA_MAX_DIRECT_QP_SIZE = 4 * PAGE_SIZE,
47 MTHCA_ACK_REQ_FREQ = 10, 48 MTHCA_ACK_REQ_FREQ = 10,
48 MTHCA_FLIGHT_LIMIT = 9, 49 MTHCA_FLIGHT_LIMIT = 9,
49 MTHCA_UD_HEADER_SIZE = 72 /* largest UD header possible */ 50 MTHCA_UD_HEADER_SIZE = 72, /* largest UD header possible */
51 MTHCA_INLINE_HEADER_SIZE = 4, /* data segment overhead for inline */
52 MTHCA_INLINE_CHUNK_SIZE = 16 /* inline data segment chunk */
50}; 53};
51 54
52enum { 55enum {
@@ -689,7 +692,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
689 692
690 /* leave arbel_sched_queue as 0 */ 693 /* leave arbel_sched_queue as 0 */
691 694
692 qp_context->usr_page = cpu_to_be32(dev->driver_uar.index); 695 if (qp->ibqp.uobject)
696 qp_context->usr_page =
697 cpu_to_be32(to_mucontext(qp->ibqp.uobject->context)->uar.index);
698 else
699 qp_context->usr_page = cpu_to_be32(dev->driver_uar.index);
693 qp_context->local_qpn = cpu_to_be32(qp->qpn); 700 qp_context->local_qpn = cpu_to_be32(qp->qpn);
694 if (attr_mask & IB_QP_DEST_QPN) { 701 if (attr_mask & IB_QP_DEST_QPN) {
695 qp_context->remote_qpn = cpu_to_be32(attr->dest_qp_num); 702 qp_context->remote_qpn = cpu_to_be32(attr->dest_qp_num);
@@ -954,6 +961,15 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
954 961
955 qp->send_wqe_offset = ALIGN(qp->rq.max << qp->rq.wqe_shift, 962 qp->send_wqe_offset = ALIGN(qp->rq.max << qp->rq.wqe_shift,
956 1 << qp->sq.wqe_shift); 963 1 << qp->sq.wqe_shift);
964
965 /*
966 * If this is a userspace QP, we don't actually have to
967 * allocate anything. All we need is to calculate the WQE
968 * sizes and the send_wqe_offset, so we're done now.
969 */
970 if (pd->ibpd.uobject)
971 return 0;
972
957 size = PAGE_ALIGN(qp->send_wqe_offset + 973 size = PAGE_ALIGN(qp->send_wqe_offset +
958 (qp->sq.max << qp->sq.wqe_shift)); 974 (qp->sq.max << qp->sq.wqe_shift));
959 975
@@ -1053,10 +1069,32 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
1053 return err; 1069 return err;
1054} 1070}
1055 1071
1056static int mthca_alloc_memfree(struct mthca_dev *dev, 1072static void mthca_free_wqe_buf(struct mthca_dev *dev,
1057 struct mthca_qp *qp) 1073 struct mthca_qp *qp)
1058{ 1074{
1059 int ret = 0; 1075 int i;
1076 int size = PAGE_ALIGN(qp->send_wqe_offset +
1077 (qp->sq.max << qp->sq.wqe_shift));
1078
1079 if (qp->is_direct) {
1080 dma_free_coherent(&dev->pdev->dev, size, qp->queue.direct.buf,
1081 pci_unmap_addr(&qp->queue.direct, mapping));
1082 } else {
1083 for (i = 0; i < size / PAGE_SIZE; ++i) {
1084 dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
1085 qp->queue.page_list[i].buf,
1086 pci_unmap_addr(&qp->queue.page_list[i],
1087 mapping));
1088 }
1089 }
1090
1091 kfree(qp->wrid);
1092}
1093
1094static int mthca_map_memfree(struct mthca_dev *dev,
1095 struct mthca_qp *qp)
1096{
1097 int ret;
1060 1098
1061 if (mthca_is_memfree(dev)) { 1099 if (mthca_is_memfree(dev)) {
1062 ret = mthca_table_get(dev, dev->qp_table.qp_table, qp->qpn); 1100 ret = mthca_table_get(dev, dev->qp_table.qp_table, qp->qpn);
@@ -1067,35 +1105,15 @@ static int mthca_alloc_memfree(struct mthca_dev *dev,
1067 if (ret) 1105 if (ret)
1068 goto err_qpc; 1106 goto err_qpc;
1069 1107
1070 ret = mthca_table_get(dev, dev->qp_table.rdb_table, 1108 ret = mthca_table_get(dev, dev->qp_table.rdb_table,
1071 qp->qpn << dev->qp_table.rdb_shift); 1109 qp->qpn << dev->qp_table.rdb_shift);
1072 if (ret) 1110 if (ret)
1073 goto err_eqpc; 1111 goto err_eqpc;
1074
1075 qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
1076 qp->qpn, &qp->rq.db);
1077 if (qp->rq.db_index < 0) {
1078 ret = -ENOMEM;
1079 goto err_rdb;
1080 }
1081 1112
1082 qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
1083 qp->qpn, &qp->sq.db);
1084 if (qp->sq.db_index < 0) {
1085 ret = -ENOMEM;
1086 goto err_rq_db;
1087 }
1088 } 1113 }
1089 1114
1090 return 0; 1115 return 0;
1091 1116
1092err_rq_db:
1093 mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
1094
1095err_rdb:
1096 mthca_table_put(dev, dev->qp_table.rdb_table,
1097 qp->qpn << dev->qp_table.rdb_shift);
1098
1099err_eqpc: 1117err_eqpc:
1100 mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn); 1118 mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
1101 1119
@@ -1105,6 +1123,35 @@ err_qpc:
1105 return ret; 1123 return ret;
1106} 1124}
1107 1125
1126static void mthca_unmap_memfree(struct mthca_dev *dev,
1127 struct mthca_qp *qp)
1128{
1129 mthca_table_put(dev, dev->qp_table.rdb_table,
1130 qp->qpn << dev->qp_table.rdb_shift);
1131 mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
1132 mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn);
1133}
1134
1135static int mthca_alloc_memfree(struct mthca_dev *dev,
1136 struct mthca_qp *qp)
1137{
1138 int ret = 0;
1139
1140 if (mthca_is_memfree(dev)) {
1141 qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
1142 qp->qpn, &qp->rq.db);
1143 if (qp->rq.db_index < 0)
1144 return ret;
1145
1146 qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
1147 qp->qpn, &qp->sq.db);
1148 if (qp->sq.db_index < 0)
1149 mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
1150 }
1151
1152 return ret;
1153}
1154
1108static void mthca_free_memfree(struct mthca_dev *dev, 1155static void mthca_free_memfree(struct mthca_dev *dev,
1109 struct mthca_qp *qp) 1156 struct mthca_qp *qp)
1110{ 1157{
@@ -1112,11 +1159,6 @@ static void mthca_free_memfree(struct mthca_dev *dev,
1112 mthca_free_db(dev, MTHCA_DB_TYPE_SQ, qp->sq.db_index); 1159 mthca_free_db(dev, MTHCA_DB_TYPE_SQ, qp->sq.db_index);
1113 mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index); 1160 mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
1114 } 1161 }
1115
1116 mthca_table_put(dev, dev->qp_table.rdb_table,
1117 qp->qpn << dev->qp_table.rdb_shift);
1118 mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
1119 mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn);
1120} 1162}
1121 1163
1122static void mthca_wq_init(struct mthca_wq* wq) 1164static void mthca_wq_init(struct mthca_wq* wq)
@@ -1147,13 +1189,28 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1147 mthca_wq_init(&qp->sq); 1189 mthca_wq_init(&qp->sq);
1148 mthca_wq_init(&qp->rq); 1190 mthca_wq_init(&qp->rq);
1149 1191
1150 ret = mthca_alloc_memfree(dev, qp); 1192 ret = mthca_map_memfree(dev, qp);
1151 if (ret) 1193 if (ret)
1152 return ret; 1194 return ret;
1153 1195
1154 ret = mthca_alloc_wqe_buf(dev, pd, qp); 1196 ret = mthca_alloc_wqe_buf(dev, pd, qp);
1155 if (ret) { 1197 if (ret) {
1156 mthca_free_memfree(dev, qp); 1198 mthca_unmap_memfree(dev, qp);
1199 return ret;
1200 }
1201
1202 /*
1203 * If this is a userspace QP, we're done now. The doorbells
1204 * will be allocated and buffers will be initialized in
1205 * userspace.
1206 */
1207 if (pd->ibpd.uobject)
1208 return 0;
1209
1210 ret = mthca_alloc_memfree(dev, qp);
1211 if (ret) {
1212 mthca_free_wqe_buf(dev, qp);
1213 mthca_unmap_memfree(dev, qp);
1157 return ret; 1214 return ret;
1158 } 1215 }
1159 1216
@@ -1186,22 +1243,39 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1186 return 0; 1243 return 0;
1187} 1244}
1188 1245
1189static void mthca_align_qp_size(struct mthca_dev *dev, struct mthca_qp *qp) 1246static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
1247 struct mthca_qp *qp)
1190{ 1248{
1191 int i; 1249 /* Sanity check QP size before proceeding */
1192 1250 if (cap->max_send_wr > 65536 || cap->max_recv_wr > 65536 ||
1193 if (!mthca_is_memfree(dev)) 1251 cap->max_send_sge > 64 || cap->max_recv_sge > 64)
1194 return; 1252 return -EINVAL;
1195 1253
1196 for (i = 0; 1 << i < qp->rq.max; ++i) 1254 if (mthca_is_memfree(dev)) {
1197 ; /* nothing */ 1255 qp->rq.max = cap->max_recv_wr ?
1256 roundup_pow_of_two(cap->max_recv_wr) : 0;
1257 qp->sq.max = cap->max_send_wr ?
1258 roundup_pow_of_two(cap->max_send_wr) : 0;
1259 } else {
1260 qp->rq.max = cap->max_recv_wr;
1261 qp->sq.max = cap->max_send_wr;
1262 }
1198 1263
1199 qp->rq.max = 1 << i; 1264 qp->rq.max_gs = cap->max_recv_sge;
1265 qp->sq.max_gs = max_t(int, cap->max_send_sge,
1266 ALIGN(cap->max_inline_data + MTHCA_INLINE_HEADER_SIZE,
1267 MTHCA_INLINE_CHUNK_SIZE) /
1268 sizeof (struct mthca_data_seg));
1200 1269
1201 for (i = 0; 1 << i < qp->sq.max; ++i) 1270 /*
1202 ; /* nothing */ 1271 * For MLX transport we need 2 extra S/G entries:
1272 * one for the header and one for the checksum at the end
1273 */
1274 if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) ||
1275 qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg)
1276 return -EINVAL;
1203 1277
1204 qp->sq.max = 1 << i; 1278 return 0;
1205} 1279}
1206 1280
1207int mthca_alloc_qp(struct mthca_dev *dev, 1281int mthca_alloc_qp(struct mthca_dev *dev,
@@ -1210,11 +1284,14 @@ int mthca_alloc_qp(struct mthca_dev *dev,
1210 struct mthca_cq *recv_cq, 1284 struct mthca_cq *recv_cq,
1211 enum ib_qp_type type, 1285 enum ib_qp_type type,
1212 enum ib_sig_type send_policy, 1286 enum ib_sig_type send_policy,
1287 struct ib_qp_cap *cap,
1213 struct mthca_qp *qp) 1288 struct mthca_qp *qp)
1214{ 1289{
1215 int err; 1290 int err;
1216 1291
1217 mthca_align_qp_size(dev, qp); 1292 err = mthca_set_qp_size(dev, cap, qp);
1293 if (err)
1294 return err;
1218 1295
1219 switch (type) { 1296 switch (type) {
1220 case IB_QPT_RC: qp->transport = RC; break; 1297 case IB_QPT_RC: qp->transport = RC; break;
@@ -1247,14 +1324,17 @@ int mthca_alloc_sqp(struct mthca_dev *dev,
1247 struct mthca_cq *send_cq, 1324 struct mthca_cq *send_cq,
1248 struct mthca_cq *recv_cq, 1325 struct mthca_cq *recv_cq,
1249 enum ib_sig_type send_policy, 1326 enum ib_sig_type send_policy,
1327 struct ib_qp_cap *cap,
1250 int qpn, 1328 int qpn,
1251 int port, 1329 int port,
1252 struct mthca_sqp *sqp) 1330 struct mthca_sqp *sqp)
1253{ 1331{
1254 int err = 0;
1255 u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1; 1332 u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1;
1333 int err;
1256 1334
1257 mthca_align_qp_size(dev, &sqp->qp); 1335 err = mthca_set_qp_size(dev, cap, &sqp->qp);
1336 if (err)
1337 return err;
1258 1338
1259 sqp->header_buf_size = sqp->qp.sq.max * MTHCA_UD_HEADER_SIZE; 1339 sqp->header_buf_size = sqp->qp.sq.max * MTHCA_UD_HEADER_SIZE;
1260 sqp->header_buf = dma_alloc_coherent(&dev->pdev->dev, sqp->header_buf_size, 1340 sqp->header_buf = dma_alloc_coherent(&dev->pdev->dev, sqp->header_buf_size,
@@ -1313,8 +1393,6 @@ void mthca_free_qp(struct mthca_dev *dev,
1313 struct mthca_qp *qp) 1393 struct mthca_qp *qp)
1314{ 1394{
1315 u8 status; 1395 u8 status;
1316 int size;
1317 int i;
1318 struct mthca_cq *send_cq; 1396 struct mthca_cq *send_cq;
1319 struct mthca_cq *recv_cq; 1397 struct mthca_cq *recv_cq;
1320 1398
@@ -1344,31 +1422,22 @@ void mthca_free_qp(struct mthca_dev *dev,
1344 if (qp->state != IB_QPS_RESET) 1422 if (qp->state != IB_QPS_RESET)
1345 mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status); 1423 mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status);
1346 1424
1347 mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn); 1425 /*
1348 if (qp->ibqp.send_cq != qp->ibqp.recv_cq) 1426 * If this is a userspace QP, the buffers, MR, CQs and so on
1349 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn); 1427 * will be cleaned up in userspace, so all we have to do is
1350 1428 * unref the mem-free tables and free the QPN in our table.
1351 mthca_free_mr(dev, &qp->mr); 1429 */
1352 1430 if (!qp->ibqp.uobject) {
1353 size = PAGE_ALIGN(qp->send_wqe_offset + 1431 mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn);
1354 (qp->sq.max << qp->sq.wqe_shift)); 1432 if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
1433 mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn);
1355 1434
1356 if (qp->is_direct) { 1435 mthca_free_mr(dev, &qp->mr);
1357 pci_free_consistent(dev->pdev, size, 1436 mthca_free_memfree(dev, qp);
1358 qp->queue.direct.buf, 1437 mthca_free_wqe_buf(dev, qp);
1359 pci_unmap_addr(&qp->queue.direct, mapping));
1360 } else {
1361 for (i = 0; i < size / PAGE_SIZE; ++i) {
1362 pci_free_consistent(dev->pdev, PAGE_SIZE,
1363 qp->queue.page_list[i].buf,
1364 pci_unmap_addr(&qp->queue.page_list[i],
1365 mapping));
1366 }
1367 } 1438 }
1368 1439
1369 kfree(qp->wrid); 1440 mthca_unmap_memfree(dev, qp);
1370
1371 mthca_free_memfree(dev, qp);
1372 1441
1373 if (is_sqp(dev, qp)) { 1442 if (is_sqp(dev, qp)) {
1374 atomic_dec(&(to_mpd(qp->ibqp.pd)->sqp_count)); 1443 atomic_dec(&(to_mpd(qp->ibqp.pd)->sqp_count));
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h
new file mode 100644
index 000000000000..3024c1b4547d
--- /dev/null
+++ b/drivers/infiniband/hw/mthca/mthca_user.h
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35#ifndef MTHCA_USER_H
36#define MTHCA_USER_H
37
38#include <linux/types.h>
39
40/*
41 * Make sure that all structs defined in this file remain laid out so
42 * that they pack the same way on 32-bit and 64-bit architectures (to
43 * avoid incompatibility between 32-bit userspace and 64-bit kernels).
44 * In particular do not use pointer types -- pass pointers in __u64
45 * instead.
46 */
47
48struct mthca_alloc_ucontext_resp {
49 __u32 qp_tab_size;
50 __u32 uarc_size;
51};
52
53struct mthca_alloc_pd_resp {
54 __u32 pdn;
55 __u32 reserved;
56};
57
58struct mthca_create_cq {
59 __u32 lkey;
60 __u32 pdn;
61 __u64 arm_db_page;
62 __u64 set_db_page;
63 __u32 arm_db_index;
64 __u32 set_db_index;
65};
66
67struct mthca_create_cq_resp {
68 __u32 cqn;
69 __u32 reserved;
70};
71
72struct mthca_create_qp {
73 __u32 lkey;
74 __u32 reserved;
75 __u64 sq_db_page;
76 __u64 rq_db_page;
77 __u32 sq_db_index;
78 __u32 rq_db_index;
79};
80
81#endif /* MTHCA_USER_H */
diff --git a/drivers/infiniband/include/ib_user_verbs.h b/drivers/infiniband/include/ib_user_verbs.h
new file mode 100644
index 000000000000..7c613706af72
--- /dev/null
+++ b/drivers/infiniband/include/ib_user_verbs.h
@@ -0,0 +1,389 @@
1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 * $Id: ib_user_verbs.h 2708 2005-06-24 17:27:21Z roland $
34 */
35
36#ifndef IB_USER_VERBS_H
37#define IB_USER_VERBS_H
38
39#include <linux/types.h>
40
41/*
42 * Increment this value if any changes that break userspace ABI
43 * compatibility are made.
44 */
45#define IB_USER_VERBS_ABI_VERSION 1
46
47enum {
48 IB_USER_VERBS_CMD_QUERY_PARAMS,
49 IB_USER_VERBS_CMD_GET_CONTEXT,
50 IB_USER_VERBS_CMD_QUERY_DEVICE,
51 IB_USER_VERBS_CMD_QUERY_PORT,
52 IB_USER_VERBS_CMD_QUERY_GID,
53 IB_USER_VERBS_CMD_QUERY_PKEY,
54 IB_USER_VERBS_CMD_ALLOC_PD,
55 IB_USER_VERBS_CMD_DEALLOC_PD,
56 IB_USER_VERBS_CMD_CREATE_AH,
57 IB_USER_VERBS_CMD_MODIFY_AH,
58 IB_USER_VERBS_CMD_QUERY_AH,
59 IB_USER_VERBS_CMD_DESTROY_AH,
60 IB_USER_VERBS_CMD_REG_MR,
61 IB_USER_VERBS_CMD_REG_SMR,
62 IB_USER_VERBS_CMD_REREG_MR,
63 IB_USER_VERBS_CMD_QUERY_MR,
64 IB_USER_VERBS_CMD_DEREG_MR,
65 IB_USER_VERBS_CMD_ALLOC_MW,
66 IB_USER_VERBS_CMD_BIND_MW,
67 IB_USER_VERBS_CMD_DEALLOC_MW,
68 IB_USER_VERBS_CMD_CREATE_CQ,
69 IB_USER_VERBS_CMD_RESIZE_CQ,
70 IB_USER_VERBS_CMD_DESTROY_CQ,
71 IB_USER_VERBS_CMD_POLL_CQ,
72 IB_USER_VERBS_CMD_PEEK_CQ,
73 IB_USER_VERBS_CMD_REQ_NOTIFY_CQ,
74 IB_USER_VERBS_CMD_CREATE_QP,
75 IB_USER_VERBS_CMD_QUERY_QP,
76 IB_USER_VERBS_CMD_MODIFY_QP,
77 IB_USER_VERBS_CMD_DESTROY_QP,
78 IB_USER_VERBS_CMD_POST_SEND,
79 IB_USER_VERBS_CMD_POST_RECV,
80 IB_USER_VERBS_CMD_ATTACH_MCAST,
81 IB_USER_VERBS_CMD_DETACH_MCAST
82};
83
84/*
85 * Make sure that all structs defined in this file remain laid out so
86 * that they pack the same way on 32-bit and 64-bit architectures (to
87 * avoid incompatibility between 32-bit userspace and 64-bit kernels).
88 * In particular do not use pointer types -- pass pointers in __u64
89 * instead.
90 */
91
92struct ib_uverbs_async_event_desc {
93 __u64 element;
94 __u32 event_type; /* enum ib_event_type */
95 __u32 reserved;
96};
97
98struct ib_uverbs_comp_event_desc {
99 __u64 cq_handle;
100};
101
102/*
103 * All commands from userspace should start with a __u32 command field
104 * followed by __u16 in_words and out_words fields (which give the
105 * length of the command block and response buffer if any in 32-bit
106 * words). The kernel driver will read these fields first and read
107 * the rest of the command struct based on these value.
108 */
109
110struct ib_uverbs_cmd_hdr {
111 __u32 command;
112 __u16 in_words;
113 __u16 out_words;
114};
115
116/*
117 * No driver_data for "query params" command, since this is intended
118 * to be a core function with no possible device dependence.
119 */
120struct ib_uverbs_query_params {
121 __u64 response;
122};
123
124struct ib_uverbs_query_params_resp {
125 __u32 num_cq_events;
126};
127
128struct ib_uverbs_get_context {
129 __u64 response;
130 __u64 cq_fd_tab;
131 __u64 driver_data[0];
132};
133
134struct ib_uverbs_get_context_resp {
135 __u32 async_fd;
136 __u32 reserved;
137};
138
139struct ib_uverbs_query_device {
140 __u64 response;
141 __u64 driver_data[0];
142};
143
144struct ib_uverbs_query_device_resp {
145 __u64 fw_ver;
146 __u64 node_guid;
147 __u64 sys_image_guid;
148 __u64 max_mr_size;
149 __u64 page_size_cap;
150 __u32 vendor_id;
151 __u32 vendor_part_id;
152 __u32 hw_ver;
153 __u32 max_qp;
154 __u32 max_qp_wr;
155 __u32 device_cap_flags;
156 __u32 max_sge;
157 __u32 max_sge_rd;
158 __u32 max_cq;
159 __u32 max_cqe;
160 __u32 max_mr;
161 __u32 max_pd;
162 __u32 max_qp_rd_atom;
163 __u32 max_ee_rd_atom;
164 __u32 max_res_rd_atom;
165 __u32 max_qp_init_rd_atom;
166 __u32 max_ee_init_rd_atom;
167 __u32 atomic_cap;
168 __u32 max_ee;
169 __u32 max_rdd;
170 __u32 max_mw;
171 __u32 max_raw_ipv6_qp;
172 __u32 max_raw_ethy_qp;
173 __u32 max_mcast_grp;
174 __u32 max_mcast_qp_attach;
175 __u32 max_total_mcast_qp_attach;
176 __u32 max_ah;
177 __u32 max_fmr;
178 __u32 max_map_per_fmr;
179 __u32 max_srq;
180 __u32 max_srq_wr;
181 __u32 max_srq_sge;
182 __u16 max_pkeys;
183 __u8 local_ca_ack_delay;
184 __u8 phys_port_cnt;
185 __u8 reserved[4];
186};
187
188struct ib_uverbs_query_port {
189 __u64 response;
190 __u8 port_num;
191 __u8 reserved[7];
192 __u64 driver_data[0];
193};
194
195struct ib_uverbs_query_port_resp {
196 __u32 port_cap_flags;
197 __u32 max_msg_sz;
198 __u32 bad_pkey_cntr;
199 __u32 qkey_viol_cntr;
200 __u32 gid_tbl_len;
201 __u16 pkey_tbl_len;
202 __u16 lid;
203 __u16 sm_lid;
204 __u8 state;
205 __u8 max_mtu;
206 __u8 active_mtu;
207 __u8 lmc;
208 __u8 max_vl_num;
209 __u8 sm_sl;
210 __u8 subnet_timeout;
211 __u8 init_type_reply;
212 __u8 active_width;
213 __u8 active_speed;
214 __u8 phys_state;
215 __u8 reserved[3];
216};
217
218struct ib_uverbs_query_gid {
219 __u64 response;
220 __u8 port_num;
221 __u8 index;
222 __u8 reserved[6];
223 __u64 driver_data[0];
224};
225
226struct ib_uverbs_query_gid_resp {
227 __u8 gid[16];
228};
229
230struct ib_uverbs_query_pkey {
231 __u64 response;
232 __u8 port_num;
233 __u8 index;
234 __u8 reserved[6];
235 __u64 driver_data[0];
236};
237
238struct ib_uverbs_query_pkey_resp {
239 __u16 pkey;
240 __u16 reserved;
241};
242
243struct ib_uverbs_alloc_pd {
244 __u64 response;
245 __u64 driver_data[0];
246};
247
248struct ib_uverbs_alloc_pd_resp {
249 __u32 pd_handle;
250};
251
252struct ib_uverbs_dealloc_pd {
253 __u32 pd_handle;
254};
255
256struct ib_uverbs_reg_mr {
257 __u64 response;
258 __u64 start;
259 __u64 length;
260 __u64 hca_va;
261 __u32 pd_handle;
262 __u32 access_flags;
263 __u64 driver_data[0];
264};
265
266struct ib_uverbs_reg_mr_resp {
267 __u32 mr_handle;
268 __u32 lkey;
269 __u32 rkey;
270};
271
272struct ib_uverbs_dereg_mr {
273 __u32 mr_handle;
274};
275
276struct ib_uverbs_create_cq {
277 __u64 response;
278 __u64 user_handle;
279 __u32 cqe;
280 __u32 event_handler;
281 __u64 driver_data[0];
282};
283
284struct ib_uverbs_create_cq_resp {
285 __u32 cq_handle;
286 __u32 cqe;
287};
288
289struct ib_uverbs_destroy_cq {
290 __u32 cq_handle;
291};
292
293struct ib_uverbs_create_qp {
294 __u64 response;
295 __u64 user_handle;
296 __u32 pd_handle;
297 __u32 send_cq_handle;
298 __u32 recv_cq_handle;
299 __u32 srq_handle;
300 __u32 max_send_wr;
301 __u32 max_recv_wr;
302 __u32 max_send_sge;
303 __u32 max_recv_sge;
304 __u32 max_inline_data;
305 __u8 sq_sig_all;
306 __u8 qp_type;
307 __u8 is_srq;
308 __u8 reserved;
309 __u64 driver_data[0];
310};
311
312struct ib_uverbs_create_qp_resp {
313 __u32 qp_handle;
314 __u32 qpn;
315};
316
317/*
318 * This struct needs to remain a multiple of 8 bytes to keep the
319 * alignment of the modify QP parameters.
320 */
321struct ib_uverbs_qp_dest {
322 __u8 dgid[16];
323 __u32 flow_label;
324 __u16 dlid;
325 __u16 reserved;
326 __u8 sgid_index;
327 __u8 hop_limit;
328 __u8 traffic_class;
329 __u8 sl;
330 __u8 src_path_bits;
331 __u8 static_rate;
332 __u8 is_global;
333 __u8 port_num;
334};
335
336struct ib_uverbs_modify_qp {
337 struct ib_uverbs_qp_dest dest;
338 struct ib_uverbs_qp_dest alt_dest;
339 __u32 qp_handle;
340 __u32 attr_mask;
341 __u32 qkey;
342 __u32 rq_psn;
343 __u32 sq_psn;
344 __u32 dest_qp_num;
345 __u32 qp_access_flags;
346 __u16 pkey_index;
347 __u16 alt_pkey_index;
348 __u8 qp_state;
349 __u8 cur_qp_state;
350 __u8 path_mtu;
351 __u8 path_mig_state;
352 __u8 en_sqd_async_notify;
353 __u8 max_rd_atomic;
354 __u8 max_dest_rd_atomic;
355 __u8 min_rnr_timer;
356 __u8 port_num;
357 __u8 timeout;
358 __u8 retry_cnt;
359 __u8 rnr_retry;
360 __u8 alt_port_num;
361 __u8 alt_timeout;
362 __u8 reserved[2];
363 __u64 driver_data[0];
364};
365
366struct ib_uverbs_modify_qp_resp {
367};
368
369struct ib_uverbs_destroy_qp {
370 __u32 qp_handle;
371};
372
373struct ib_uverbs_attach_mcast {
374 __u8 gid[16];
375 __u32 qp_handle;
376 __u16 mlid;
377 __u16 reserved;
378 __u64 driver_data[0];
379};
380
381struct ib_uverbs_detach_mcast {
382 __u8 gid[16];
383 __u32 qp_handle;
384 __u16 mlid;
385 __u16 reserved;
386 __u64 driver_data[0];
387};
388
389#endif /* IB_USER_VERBS_H */
diff --git a/drivers/infiniband/include/ib_verbs.h b/drivers/infiniband/include/ib_verbs.h
index cf01f044a223..e5bd9a10c201 100644
--- a/drivers/infiniband/include/ib_verbs.h
+++ b/drivers/infiniband/include/ib_verbs.h
@@ -4,6 +4,7 @@
4 * Copyright (c) 2004 Intel Corporation. All rights reserved. 4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 * Copyright (c) 2005 Cisco Systems. All rights reserved.
7 * 8 *
8 * This software is available to you under a choice of one of two 9 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU 10 * licenses. You may choose to be licensed under the terms of the GNU
@@ -41,7 +42,10 @@
41 42
42#include <linux/types.h> 43#include <linux/types.h>
43#include <linux/device.h> 44#include <linux/device.h>
45
44#include <asm/atomic.h> 46#include <asm/atomic.h>
47#include <asm/scatterlist.h>
48#include <asm/uaccess.h>
45 49
46union ib_gid { 50union ib_gid {
47 u8 raw[16]; 51 u8 raw[16];
@@ -544,7 +548,7 @@ struct ib_send_wr {
544 int num_sge; 548 int num_sge;
545 enum ib_wr_opcode opcode; 549 enum ib_wr_opcode opcode;
546 int send_flags; 550 int send_flags;
547 u32 imm_data; 551 __be32 imm_data;
548 union { 552 union {
549 struct { 553 struct {
550 u64 remote_addr; 554 u64 remote_addr;
@@ -618,29 +622,86 @@ struct ib_fmr_attr {
618 u8 page_size; 622 u8 page_size;
619}; 623};
620 624
625struct ib_ucontext {
626 struct ib_device *device;
627 struct list_head pd_list;
628 struct list_head mr_list;
629 struct list_head mw_list;
630 struct list_head cq_list;
631 struct list_head qp_list;
632 struct list_head srq_list;
633 struct list_head ah_list;
634 spinlock_t lock;
635};
636
637struct ib_uobject {
638 u64 user_handle; /* handle given to us by userspace */
639 struct ib_ucontext *context; /* associated user context */
640 struct list_head list; /* link to context's list */
641 u32 id; /* index into kernel idr */
642};
643
644struct ib_umem {
645 unsigned long user_base;
646 unsigned long virt_base;
647 size_t length;
648 int offset;
649 int page_size;
650 int writable;
651 struct list_head chunk_list;
652};
653
654struct ib_umem_chunk {
655 struct list_head list;
656 int nents;
657 int nmap;
658 struct scatterlist page_list[0];
659};
660
661struct ib_udata {
662 void __user *inbuf;
663 void __user *outbuf;
664 size_t inlen;
665 size_t outlen;
666};
667
668#define IB_UMEM_MAX_PAGE_CHUNK \
669 ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \
670 ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \
671 (void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
672
673struct ib_umem_object {
674 struct ib_uobject uobject;
675 struct ib_umem umem;
676};
677
621struct ib_pd { 678struct ib_pd {
622 struct ib_device *device; 679 struct ib_device *device;
623 atomic_t usecnt; /* count all resources */ 680 struct ib_uobject *uobject;
681 atomic_t usecnt; /* count all resources */
624}; 682};
625 683
626struct ib_ah { 684struct ib_ah {
627 struct ib_device *device; 685 struct ib_device *device;
628 struct ib_pd *pd; 686 struct ib_pd *pd;
687 struct ib_uobject *uobject;
629}; 688};
630 689
631typedef void (*ib_comp_handler)(struct ib_cq *cq, void *cq_context); 690typedef void (*ib_comp_handler)(struct ib_cq *cq, void *cq_context);
632 691
633struct ib_cq { 692struct ib_cq {
634 struct ib_device *device; 693 struct ib_device *device;
635 ib_comp_handler comp_handler; 694 struct ib_uobject *uobject;
636 void (*event_handler)(struct ib_event *, void *); 695 ib_comp_handler comp_handler;
637 void * cq_context; 696 void (*event_handler)(struct ib_event *, void *);
638 int cqe; 697 void * cq_context;
639 atomic_t usecnt; /* count number of work queues */ 698 int cqe;
699 atomic_t usecnt; /* count number of work queues */
640}; 700};
641 701
642struct ib_srq { 702struct ib_srq {
643 struct ib_device *device; 703 struct ib_device *device;
704 struct ib_uobject *uobject;
644 struct ib_pd *pd; 705 struct ib_pd *pd;
645 void *srq_context; 706 void *srq_context;
646 atomic_t usecnt; 707 atomic_t usecnt;
@@ -652,6 +713,7 @@ struct ib_qp {
652 struct ib_cq *send_cq; 713 struct ib_cq *send_cq;
653 struct ib_cq *recv_cq; 714 struct ib_cq *recv_cq;
654 struct ib_srq *srq; 715 struct ib_srq *srq;
716 struct ib_uobject *uobject;
655 void (*event_handler)(struct ib_event *, void *); 717 void (*event_handler)(struct ib_event *, void *);
656 void *qp_context; 718 void *qp_context;
657 u32 qp_num; 719 u32 qp_num;
@@ -659,16 +721,18 @@ struct ib_qp {
659}; 721};
660 722
661struct ib_mr { 723struct ib_mr {
662 struct ib_device *device; 724 struct ib_device *device;
663 struct ib_pd *pd; 725 struct ib_pd *pd;
664 u32 lkey; 726 struct ib_uobject *uobject;
665 u32 rkey; 727 u32 lkey;
666 atomic_t usecnt; /* count number of MWs */ 728 u32 rkey;
729 atomic_t usecnt; /* count number of MWs */
667}; 730};
668 731
669struct ib_mw { 732struct ib_mw {
670 struct ib_device *device; 733 struct ib_device *device;
671 struct ib_pd *pd; 734 struct ib_pd *pd;
735 struct ib_uobject *uobject;
672 u32 rkey; 736 u32 rkey;
673}; 737};
674 738
@@ -737,7 +801,14 @@ struct ib_device {
737 int (*modify_port)(struct ib_device *device, 801 int (*modify_port)(struct ib_device *device,
738 u8 port_num, int port_modify_mask, 802 u8 port_num, int port_modify_mask,
739 struct ib_port_modify *port_modify); 803 struct ib_port_modify *port_modify);
740 struct ib_pd * (*alloc_pd)(struct ib_device *device); 804 struct ib_ucontext * (*alloc_ucontext)(struct ib_device *device,
805 struct ib_udata *udata);
806 int (*dealloc_ucontext)(struct ib_ucontext *context);
807 int (*mmap)(struct ib_ucontext *context,
808 struct vm_area_struct *vma);
809 struct ib_pd * (*alloc_pd)(struct ib_device *device,
810 struct ib_ucontext *context,
811 struct ib_udata *udata);
741 int (*dealloc_pd)(struct ib_pd *pd); 812 int (*dealloc_pd)(struct ib_pd *pd);
742 struct ib_ah * (*create_ah)(struct ib_pd *pd, 813 struct ib_ah * (*create_ah)(struct ib_pd *pd,
743 struct ib_ah_attr *ah_attr); 814 struct ib_ah_attr *ah_attr);
@@ -747,7 +818,8 @@ struct ib_device {
747 struct ib_ah_attr *ah_attr); 818 struct ib_ah_attr *ah_attr);
748 int (*destroy_ah)(struct ib_ah *ah); 819 int (*destroy_ah)(struct ib_ah *ah);
749 struct ib_qp * (*create_qp)(struct ib_pd *pd, 820 struct ib_qp * (*create_qp)(struct ib_pd *pd,
750 struct ib_qp_init_attr *qp_init_attr); 821 struct ib_qp_init_attr *qp_init_attr,
822 struct ib_udata *udata);
751 int (*modify_qp)(struct ib_qp *qp, 823 int (*modify_qp)(struct ib_qp *qp,
752 struct ib_qp_attr *qp_attr, 824 struct ib_qp_attr *qp_attr,
753 int qp_attr_mask); 825 int qp_attr_mask);
@@ -762,8 +834,9 @@ struct ib_device {
762 int (*post_recv)(struct ib_qp *qp, 834 int (*post_recv)(struct ib_qp *qp,
763 struct ib_recv_wr *recv_wr, 835 struct ib_recv_wr *recv_wr,
764 struct ib_recv_wr **bad_recv_wr); 836 struct ib_recv_wr **bad_recv_wr);
765 struct ib_cq * (*create_cq)(struct ib_device *device, 837 struct ib_cq * (*create_cq)(struct ib_device *device, int cqe,
766 int cqe); 838 struct ib_ucontext *context,
839 struct ib_udata *udata);
767 int (*destroy_cq)(struct ib_cq *cq); 840 int (*destroy_cq)(struct ib_cq *cq);
768 int (*resize_cq)(struct ib_cq *cq, int *cqe); 841 int (*resize_cq)(struct ib_cq *cq, int *cqe);
769 int (*poll_cq)(struct ib_cq *cq, int num_entries, 842 int (*poll_cq)(struct ib_cq *cq, int num_entries,
@@ -780,6 +853,10 @@ struct ib_device {
780 int num_phys_buf, 853 int num_phys_buf,
781 int mr_access_flags, 854 int mr_access_flags,
782 u64 *iova_start); 855 u64 *iova_start);
856 struct ib_mr * (*reg_user_mr)(struct ib_pd *pd,
857 struct ib_umem *region,
858 int mr_access_flags,
859 struct ib_udata *udata);
783 int (*query_mr)(struct ib_mr *mr, 860 int (*query_mr)(struct ib_mr *mr,
784 struct ib_mr_attr *mr_attr); 861 struct ib_mr_attr *mr_attr);
785 int (*dereg_mr)(struct ib_mr *mr); 862 int (*dereg_mr)(struct ib_mr *mr);
@@ -817,6 +894,7 @@ struct ib_device {
817 struct ib_mad *in_mad, 894 struct ib_mad *in_mad,
818 struct ib_mad *out_mad); 895 struct ib_mad *out_mad);
819 896
897 struct module *owner;
820 struct class_device class_dev; 898 struct class_device class_dev;
821 struct kobject ports_parent; 899 struct kobject ports_parent;
822 struct list_head port_list; 900 struct list_head port_list;
@@ -852,6 +930,16 @@ void *ib_get_client_data(struct ib_device *device, struct ib_client *client);
852void ib_set_client_data(struct ib_device *device, struct ib_client *client, 930void ib_set_client_data(struct ib_device *device, struct ib_client *client,
853 void *data); 931 void *data);
854 932
933static inline int ib_copy_from_udata(void *dest, struct ib_udata *udata, size_t len)
934{
935 return copy_from_user(dest, udata->inbuf, len) ? -EFAULT : 0;
936}
937
938static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len)
939{
940 return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
941}
942
855int ib_register_event_handler (struct ib_event_handler *event_handler); 943int ib_register_event_handler (struct ib_event_handler *event_handler);
856int ib_unregister_event_handler(struct ib_event_handler *event_handler); 944int ib_unregister_event_handler(struct ib_event_handler *event_handler);
857void ib_dispatch_event(struct ib_event *event); 945void ib_dispatch_event(struct ib_event *event);
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index ee750e9456dd..db9bad2b3d16 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -22,7 +22,6 @@
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/system.h> 23#include <asm/system.h>
24 24
25#include <pcmcia/version.h>
26#include <pcmcia/cs_types.h> 25#include <pcmcia/cs_types.h>
27#include <pcmcia/cs.h> 26#include <pcmcia/cs.h>
28#include <pcmcia/cistpl.h> 27#include <pcmcia/cistpl.h>
@@ -161,11 +160,6 @@ static dev_link_t *avmcs_attach(void)
161 link->next = dev_list; 160 link->next = dev_list;
162 dev_list = link; 161 dev_list = link;
163 client_reg.dev_info = &dev_info; 162 client_reg.dev_info = &dev_info;
164 client_reg.EventMask =
165 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
166 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
167 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
168 client_reg.event_handler = &avmcs_event;
169 client_reg.Version = 0x0210; 163 client_reg.Version = 0x0210;
170 client_reg.event_callback_args.client_data = link; 164 client_reg.event_callback_args.client_data = link;
171 ret = pcmcia_register_client(&link->handle, &client_reg); 165 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -500,6 +494,7 @@ static struct pcmcia_driver avmcs_driver = {
500 .name = "avm_cs", 494 .name = "avm_cs",
501 }, 495 },
502 .attach = avmcs_attach, 496 .attach = avmcs_attach,
497 .event = avmcs_event,
503 .detach = avmcs_detach, 498 .detach = avmcs_detach,
504 .id_table = avmcs_ids, 499 .id_table = avmcs_ids,
505}; 500};
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 67c60e04a37b..0e22991635e7 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -21,7 +21,6 @@
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/system.h> 22#include <asm/system.h>
23 23
24#include <pcmcia/version.h>
25#include <pcmcia/cs_types.h> 24#include <pcmcia/cs_types.h>
26#include <pcmcia/cs.h> 25#include <pcmcia/cs.h>
27#include <pcmcia/cistpl.h> 26#include <pcmcia/cistpl.h>
@@ -183,11 +182,6 @@ static dev_link_t *avma1cs_attach(void)
183 link->next = dev_list; 182 link->next = dev_list;
184 dev_list = link; 183 dev_list = link;
185 client_reg.dev_info = &dev_info; 184 client_reg.dev_info = &dev_info;
186 client_reg.EventMask =
187 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
188 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
189 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
190 client_reg.event_handler = &avma1cs_event;
191 client_reg.Version = 0x0210; 185 client_reg.Version = 0x0210;
192 client_reg.event_callback_args.client_data = link; 186 client_reg.event_callback_args.client_data = link;
193 ret = pcmcia_register_client(&link->handle, &client_reg); 187 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -514,6 +508,7 @@ static struct pcmcia_driver avma1cs_driver = {
514 .name = "avma1_cs", 508 .name = "avma1_cs",
515 }, 509 },
516 .attach = avma1cs_attach, 510 .attach = avma1cs_attach,
511 .event = avma1cs_event,
517 .detach = avma1cs_detach, 512 .detach = avma1cs_detach,
518 .id_table = avma1cs_ids, 513 .id_table = avma1cs_ids,
519}; 514};
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 9146be547044..6fc6868de0b0 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -47,7 +47,6 @@
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/system.h> 48#include <asm/system.h>
49 49
50#include <pcmcia/version.h>
51#include <pcmcia/cs_types.h> 50#include <pcmcia/cs_types.h>
52#include <pcmcia/cs.h> 51#include <pcmcia/cs.h>
53#include <pcmcia/cistpl.h> 52#include <pcmcia/cistpl.h>
@@ -212,11 +211,6 @@ static dev_link_t *elsa_cs_attach(void)
212 link->next = dev_list; 211 link->next = dev_list;
213 dev_list = link; 212 dev_list = link;
214 client_reg.dev_info = &dev_info; 213 client_reg.dev_info = &dev_info;
215 client_reg.EventMask =
216 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
217 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
218 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
219 client_reg.event_handler = &elsa_cs_event;
220 client_reg.Version = 0x0210; 214 client_reg.Version = 0x0210;
221 client_reg.event_callback_args.client_data = link; 215 client_reg.event_callback_args.client_data = link;
222 ret = pcmcia_register_client(&link->handle, &client_reg); 216 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -521,6 +515,7 @@ static struct pcmcia_driver elsa_cs_driver = {
521 .name = "elsa_cs", 515 .name = "elsa_cs",
522 }, 516 },
523 .attach = elsa_cs_attach, 517 .attach = elsa_cs_attach,
518 .event = elsa_cs_event,
524 .detach = elsa_cs_detach, 519 .detach = elsa_cs_detach,
525 .id_table = elsa_ids, 520 .id_table = elsa_ids,
526}; 521};
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 058147a69576..c6b5bf7d2aca 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -47,7 +47,6 @@
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/system.h> 48#include <asm/system.h>
49 49
50#include <pcmcia/version.h>
51#include <pcmcia/cs_types.h> 50#include <pcmcia/cs_types.h>
52#include <pcmcia/cs.h> 51#include <pcmcia/cs.h>
53#include <pcmcia/cistpl.h> 52#include <pcmcia/cistpl.h>
@@ -226,11 +225,6 @@ static dev_link_t *sedlbauer_attach(void)
226 link->next = dev_list; 225 link->next = dev_list;
227 dev_list = link; 226 dev_list = link;
228 client_reg.dev_info = &dev_info; 227 client_reg.dev_info = &dev_info;
229 client_reg.EventMask =
230 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
231 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
232 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
233 client_reg.event_handler = &sedlbauer_event;
234 client_reg.Version = 0x0210; 228 client_reg.Version = 0x0210;
235 client_reg.event_callback_args.client_data = link; 229 client_reg.event_callback_args.client_data = link;
236 ret = pcmcia_register_client(&link->handle, &client_reg); 230 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -634,6 +628,7 @@ static struct pcmcia_driver sedlbauer_driver = {
634 .name = "sedlbauer_cs", 628 .name = "sedlbauer_cs",
635 }, 629 },
636 .attach = sedlbauer_attach, 630 .attach = sedlbauer_attach,
631 .event = sedlbauer_event,
637 .detach = sedlbauer_detach, 632 .detach = sedlbauer_detach,
638 .id_table = sedlbauer_ids, 633 .id_table = sedlbauer_ids,
639}; 634};
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 107376ff5b9b..0ddef1bf778b 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -28,7 +28,6 @@
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/system.h> 29#include <asm/system.h>
30 30
31#include <pcmcia/version.h>
32#include <pcmcia/cs_types.h> 31#include <pcmcia/cs_types.h>
33#include <pcmcia/cs.h> 32#include <pcmcia/cs.h>
34#include <pcmcia/cistpl.h> 33#include <pcmcia/cistpl.h>
@@ -193,11 +192,6 @@ static dev_link_t *teles_attach(void)
193 link->next = dev_list; 192 link->next = dev_list;
194 dev_list = link; 193 dev_list = link;
195 client_reg.dev_info = &dev_info; 194 client_reg.dev_info = &dev_info;
196 client_reg.EventMask =
197 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
198 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
199 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
200 client_reg.event_handler = &teles_cs_event;
201 client_reg.Version = 0x0210; 195 client_reg.Version = 0x0210;
202 client_reg.event_callback_args.client_data = link; 196 client_reg.event_callback_args.client_data = link;
203 ret = pcmcia_register_client(&link->handle, &client_reg); 197 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -501,6 +495,7 @@ static struct pcmcia_driver teles_cs_driver = {
501 .name = "teles_cs", 495 .name = "teles_cs",
502 }, 496 },
503 .attach = teles_attach, 497 .attach = teles_attach,
498 .event = teles_cs_event,
504 .detach = teles_detach, 499 .detach = teles_detach,
505 .id_table = teles_ids, 500 .id_table = teles_ids,
506}; 501};
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 6e3cf7e13451..12031c9d3f1e 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1060,6 +1060,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1060 } 1060 }
1061 1061
1062 ti->private = ms; 1062 ti->private = ms;
1063 ti->split_io = ms->rh.region_size;
1063 1064
1064 r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client); 1065 r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
1065 if (r) { 1066 if (r) {
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 50e8b8654018..cd5828b5e9e3 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -62,13 +62,15 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
62int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop) 62int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
63{ 63{
64 unsigned long start; 64 unsigned long start;
65 int err;
65 66
66 /* wait for registers to be programmed */ 67 /* wait for registers to be programmed */
67 start = jiffies; 68 start = jiffies;
68 while (1) { 69 while (1) {
69 if (saa7146_read(dev, MC2) & 2) 70 err = time_after(jiffies, start + HZ/20);
70 break; 71 if (saa7146_read(dev, MC2) & 2)
71 if (time_after(jiffies, start + HZ/20)) { 72 break;
73 if (err) {
72 DEB_S(("timed out while waiting for registers getting programmed\n")); 74 DEB_S(("timed out while waiting for registers getting programmed\n"));
73 return -ETIMEDOUT; 75 return -ETIMEDOUT;
74 } 76 }
@@ -79,10 +81,11 @@ int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
79 /* wait for transfer to complete */ 81 /* wait for transfer to complete */
80 start = jiffies; 82 start = jiffies;
81 while (1) { 83 while (1) {
84 err = time_after(jiffies, start + HZ/4);
82 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) 85 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
83 break; 86 break;
84 saa7146_read(dev, MC2); 87 saa7146_read(dev, MC2);
85 if (time_after(jiffies, start + HZ/4)) { 88 if (err) {
86 DEB_S(("timed out while waiting for transfer completion\n")); 89 DEB_S(("timed out while waiting for transfer completion\n"));
87 return -ETIMEDOUT; 90 return -ETIMEDOUT;
88 } 91 }
@@ -512,7 +515,7 @@ int saa7146_register_extension(struct saa7146_extension* ext)
512 ext->driver.remove = saa7146_remove_one; 515 ext->driver.remove = saa7146_remove_one;
513 516
514 printk("saa7146: register extension '%s'.\n",ext->name); 517 printk("saa7146: register extension '%s'.\n",ext->name);
515 return pci_module_init(&ext->driver); 518 return pci_register_driver(&ext->driver);
516} 519}
517 520
518int saa7146_unregister_extension(struct saa7146_extension* ext) 521int saa7146_unregister_extension(struct saa7146_extension* ext)
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 01387f883cdf..3f0ec6be03ae 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -40,6 +40,10 @@ comment "Supported BT878 Adapters"
40 depends on DVB_CORE && PCI 40 depends on DVB_CORE && PCI
41source "drivers/media/dvb/bt8xx/Kconfig" 41source "drivers/media/dvb/bt8xx/Kconfig"
42 42
43comment "Supported Pluto2 Adapters"
44 depends on DVB_CORE && PCI
45source "drivers/media/dvb/pluto2/Kconfig"
46
43comment "Supported DVB Frontends" 47comment "Supported DVB Frontends"
44 depends on DVB_CORE 48 depends on DVB_CORE
45source "drivers/media/dvb/frontends/Kconfig" 49source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 3c6ff1619103..a7ad0841e6fc 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/ cinergyT2/ dvb-usb/ 5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index fafd0ab3a28f..d7417eac2aba 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -35,17 +35,3 @@ config DVB_B2C2_FLEXCOP_DEBUG
35 help 35 help
36 Say Y if you want to enable the module option to control debug messages 36 Say Y if you want to enable the module option to control debug messages
37 of all B2C2 FlexCop drivers. 37 of all B2C2 FlexCop drivers.
38
39config DVB_B2C2_SKYSTAR
40 tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
41 depends on DVB_CORE && PCI
42 select DVB_STV0299
43 select DVB_MT352
44 select DVB_MT312
45 select DVB_NXT2002
46 help
47 Support for the Skystar2 PCI DVB card by Technisat, which
48 is equipped with the FlexCopII chipset by B2C2, and
49 for the B2C2/BBTI Air2PC-ATSC card.
50
51 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 7703812af34f..1a1c3bca55fa 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -9,6 +9,4 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
9b2c2-flexcop-usb-objs = flexcop-usb.o 9b2c2-flexcop-usb-objs = flexcop-usb.o
10obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o 10obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
11 11
12obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
13
14EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 12EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 773d158032df..a94912ac1872 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -108,6 +108,8 @@ void flexcop_device_kfree(struct flexcop_device*);
108int flexcop_device_initialize(struct flexcop_device*); 108int flexcop_device_initialize(struct flexcop_device*);
109void flexcop_device_exit(struct flexcop_device *fc); 109void flexcop_device_exit(struct flexcop_device *fc);
110 110
111void flexcop_reset_block_300(struct flexcop_device *fc);
112
111/* from flexcop-dma.c */ 113/* from flexcop-dma.c */
112int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size); 114int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
113void flexcop_dma_free(struct flexcop_dma *dma); 115void flexcop_dma_free(struct flexcop_dma *dma);
@@ -115,7 +117,8 @@ void flexcop_dma_free(struct flexcop_dma *dma);
115int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); 117int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
116int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); 118int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
117int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); 119int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
118int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index); 120int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
121int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
119int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); 122int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
120int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets); 123int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
121 124
@@ -151,6 +154,7 @@ int flexcop_sram_init(struct flexcop_device *fc);
151/* from flexcop-misc.c */ 154/* from flexcop-misc.c */
152void flexcop_determine_revision(struct flexcop_device *fc); 155void flexcop_determine_revision(struct flexcop_device *fc);
153void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix); 156void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
157void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
154 158
155/* from flexcop-hw-filter.c */ 159/* from flexcop-hw-filter.c */
156int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff); 160int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index 8d2706075360..cf4ed1df6086 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -37,22 +37,90 @@ void flexcop_dma_free(struct flexcop_dma *dma)
37} 37}
38EXPORT_SYMBOL(flexcop_dma_free); 38EXPORT_SYMBOL(flexcop_dma_free);
39 39
40int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) 40int flexcop_dma_config(struct flexcop_device *fc,
41 struct flexcop_dma *dma,
42 flexcop_dma_index_t dma_idx)
41{ 43{
42 flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); 44 flexcop_ibi_value v0x0,v0x4,v0xc;
45 v0x0.raw = v0x4.raw = v0xc.raw = 0;
43 46
44 if (no & FC_DMA_1) 47 v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
45 v.ctrl_208.DMA1_Timer_Enable_sig = onoff; 48 v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
49 v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
46 50
47 if (no & FC_DMA_2) 51 if ((dma_idx & FC_DMA_1) == dma_idx) {
48 v.ctrl_208.DMA2_Timer_Enable_sig = onoff; 52 fc->write_ibi_reg(fc,dma1_000,v0x0);
53 fc->write_ibi_reg(fc,dma1_004,v0x4);
54 fc->write_ibi_reg(fc,dma1_00c,v0xc);
55 } else if ((dma_idx & FC_DMA_2) == dma_idx) {
56 fc->write_ibi_reg(fc,dma2_010,v0x0);
57 fc->write_ibi_reg(fc,dma2_014,v0x4);
58 fc->write_ibi_reg(fc,dma2_01c,v0xc);
59 } else {
60 err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
61 return -EINVAL;
62 }
49 63
50 fc->write_ibi_reg(fc,ctrl_208,v);
51 return 0; 64 return 0;
52} 65}
53EXPORT_SYMBOL(flexcop_dma_control_timer_irq); 66EXPORT_SYMBOL(flexcop_dma_config);
67
68/* start the DMA transfers, but not the DMA IRQs */
69int flexcop_dma_xfer_control(struct flexcop_device *fc,
70 flexcop_dma_index_t dma_idx,
71 flexcop_dma_addr_index_t index,
72 int onoff)
73{
74 flexcop_ibi_value v0x0,v0xc;
75 flexcop_ibi_register r0x0,r0xc;
76
77 if ((dma_idx & FC_DMA_1) == dma_idx) {
78 r0x0 = dma1_000;
79 r0xc = dma1_00c;
80 } else if ((dma_idx & FC_DMA_2) == dma_idx) {
81 r0x0 = dma2_010;
82 r0xc = dma2_01c;
83 } else {
84 err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
85 return -EINVAL;
86 }
87
88 v0x0 = fc->read_ibi_reg(fc,r0x0);
89 v0xc = fc->read_ibi_reg(fc,r0xc);
90
91 deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
92 deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
93
94 if (index & FC_DMA_SUBADDR_0)
95 v0x0.dma_0x0.dma_0start = onoff;
96
97 if (index & FC_DMA_SUBADDR_1)
98 v0xc.dma_0xc.dma_1start = onoff;
99
100 fc->write_ibi_reg(fc,r0x0,v0x0);
101 fc->write_ibi_reg(fc,r0xc,v0xc);
102
103 deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
104 deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
105 return 0;
106}
107EXPORT_SYMBOL(flexcop_dma_xfer_control);
108
109static int flexcop_dma_remap(struct flexcop_device *fc,
110 flexcop_dma_index_t dma_idx,
111 int onoff)
112{
113 flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
114 flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
115 deb_info("%s\n",__FUNCTION__);
116 v.dma_0xc.remap_enable = onoff;
117 fc->write_ibi_reg(fc,r,v);
118 return 0;
119}
54 120
55int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) 121int flexcop_dma_control_size_irq(struct flexcop_device *fc,
122 flexcop_dma_index_t no,
123 int onoff)
56{ 124{
57 flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); 125 flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
58 126
@@ -67,75 +135,64 @@ int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t
67} 135}
68EXPORT_SYMBOL(flexcop_dma_control_size_irq); 136EXPORT_SYMBOL(flexcop_dma_control_size_irq);
69 137
70int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) 138int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
139 flexcop_dma_index_t no,
140 int onoff)
71{ 141{
72 flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); 142 flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
73 143
74 if (no & FC_DMA_1) 144 if (no & FC_DMA_1)
75 v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff; 145 v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
76 146
77 if (no & FC_DMA_2) 147 if (no & FC_DMA_2)
78 v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff; 148 v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
79 149
80 fc->write_ibi_reg(fc,ctrl_208,v); 150 fc->write_ibi_reg(fc,ctrl_208,v);
81 return 0; 151 return 0;
82} 152}
83EXPORT_SYMBOL(flexcop_dma_control_packet_irq); 153EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
84 154
85int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index) 155/* 1 cycles = 1.97 msec */
156int flexcop_dma_config_timer(struct flexcop_device *fc,
157 flexcop_dma_index_t dma_idx,
158 u8 cycles)
86{ 159{
160 flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
161 flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
87 162
88 flexcop_ibi_value v0x0,v0x4,v0xc; 163 flexcop_dma_remap(fc,dma_idx,0);
89 v0x0.raw = v0x4.raw = v0xc.raw = 0;
90
91 v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
92 v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
93 v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
94
95 if (index & FC_DMA_SUBADDR_0)
96 v0x0.dma_0x0.dma_0start = 1;
97
98 if (index & FC_DMA_SUBADDR_1)
99 v0xc.dma_0xc.dma_1start = 1;
100
101 if (dma_idx & FC_DMA_1) {
102 fc->write_ibi_reg(fc,dma1_000,v0x0);
103 fc->write_ibi_reg(fc,dma1_004,v0x4);
104 fc->write_ibi_reg(fc,dma1_00c,v0xc);
105 } else { /* (dma_idx & FC_DMA_2) */
106 fc->write_ibi_reg(fc,dma2_010,v0x0);
107 fc->write_ibi_reg(fc,dma2_014,v0x4);
108 fc->write_ibi_reg(fc,dma2_01c,v0xc);
109 }
110
111 return 0;
112}
113EXPORT_SYMBOL(flexcop_dma_config);
114 164
115static int flexcop_dma_remap(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, int onoff) 165 deb_info("%s\n",__FUNCTION__);
116{ 166 v.dma_0x4_write.dmatimer = cycles;
117 flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
118 flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
119 v.dma_0xc.remap_enable = onoff;
120 fc->write_ibi_reg(fc,r,v); 167 fc->write_ibi_reg(fc,r,v);
121 return 0; 168 return 0;
122} 169}
170EXPORT_SYMBOL(flexcop_dma_config_timer);
123 171
124/* 1 cycles = 1.97 msec */ 172/* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */
125int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles) 173int flexcop_dma_control_packet_irq(struct flexcop_device *fc,
174 flexcop_dma_index_t no,
175 int onoff)
126{ 176{
127 flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; 177 flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
128 flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
129 178
130 flexcop_dma_remap(fc,dma_idx,0); 179 deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
180 if (no & FC_DMA_1)
181 v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
182
183 if (no & FC_DMA_2)
184 v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
185
186 fc->write_ibi_reg(fc,ctrl_208,v);
187 deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
131 188
132 v.dma_0x4_write.dmatimer = cycles >> 1;
133 fc->write_ibi_reg(fc,r,v);
134 return 0; 189 return 0;
135} 190}
136EXPORT_SYMBOL(flexcop_dma_config_timer); 191EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
137 192
138int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets) 193int flexcop_dma_config_packet_count(struct flexcop_device *fc,
194 flexcop_dma_index_t dma_idx,
195 u8 packets)
139{ 196{
140 flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; 197 flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
141 flexcop_ibi_value v = fc->read_ibi_reg(fc,r); 198 flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 2baf43d3ce8f..75cf237196eb 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -10,6 +10,8 @@
10static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff) 10static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
11{ 11{
12 flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff); 12 flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
13
14 deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
13} 15}
14 16
15void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) 17void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
@@ -151,7 +153,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
151{ 153{
152 int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; 154 int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
153 155
154 fc->feedcount += onoff ? 1 : -1; 156 fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
155 if (dvbdmxfeed->index >= max_pid_filter) 157 if (dvbdmxfeed->index >= max_pid_filter)
156 fc->extra_feedcount += onoff ? 1 : -1; 158 fc->extra_feedcount += onoff ? 1 : -1;
157 159
@@ -178,8 +180,14 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
178 /* if it was the first or last feed request change the stream-status */ 180 /* if it was the first or last feed request change the stream-status */
179 if (fc->feedcount == onoff) { 181 if (fc->feedcount == onoff) {
180 flexcop_rcv_data_ctrl(fc,onoff); 182 flexcop_rcv_data_ctrl(fc,onoff);
181 if (fc->stream_control) 183 if (fc->stream_control) /* device specific stream control */
182 fc->stream_control(fc,onoff); 184 fc->stream_control(fc,onoff);
185
186 /* feeding stopped -> reset the flexcop filter*/
187 if (onoff == 0) {
188 flexcop_reset_block_300(fc);
189 flexcop_hw_filter_init(fc);
190 }
183 } 191 }
184 192
185 return 0; 193 return 0;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 23082545651f..3a08d38b318a 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -65,3 +65,15 @@ void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
65 flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type], 65 flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
66 flexcop_revision_names[fc->rev],suffix); 66 flexcop_revision_names[fc->rev],suffix);
67} 67}
68
69void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
70{
71 flexcop_ibi_value v;
72 int i;
73 for (i = 0; i < num; i++) {
74 v = fc->read_ibi_reg(fc,reg+4*i);
75 deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
76 }
77 deb_rdump("\n");
78}
79EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index ed717c0073d5..2f76eb3fea40 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -13,6 +13,10 @@ static int enable_pid_filtering = 1;
13module_param(enable_pid_filtering, int, 0444); 13module_param(enable_pid_filtering, int, 0444);
14MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); 14MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
15 15
16static int irq_chk_intv;
17module_param(irq_chk_intv, int, 0644);
18MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging).");
19
16#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG 20#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
17#define dprintk(level,args...) \ 21#define dprintk(level,args...) \
18 do { if ((debug & level)) printk(args); } while (0) 22 do { if ((debug & level)) printk(args); } while (0)
@@ -26,6 +30,7 @@ MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported
26#define deb_reg(args...) dprintk(0x02,args) 30#define deb_reg(args...) dprintk(0x02,args)
27#define deb_ts(args...) dprintk(0x04,args) 31#define deb_ts(args...) dprintk(0x04,args)
28#define deb_irq(args...) dprintk(0x08,args) 32#define deb_irq(args...) dprintk(0x08,args)
33#define deb_chk(args...) dprintk(0x10,args)
29 34
30static int debug = 0; 35static int debug = 0;
31module_param(debug, int, 0644); 36module_param(debug, int, 0644);
@@ -56,6 +61,10 @@ struct flexcop_pci {
56 61
57 spinlock_t irq_lock; 62 spinlock_t irq_lock;
58 63
64 unsigned long last_irq;
65
66 struct work_struct irq_check_work;
67
59 struct flexcop_device *fc_dev; 68 struct flexcop_device *fc_dev;
60}; 69};
61 70
@@ -88,18 +97,55 @@ static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi
88 return 0; 97 return 0;
89} 98}
90 99
100static void flexcop_pci_irq_check_work(void *data)
101{
102 struct flexcop_pci *fc_pci = data;
103 struct flexcop_device *fc = fc_pci->fc_dev;
104
105 flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
106
107 flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4);
108
109 if (v.sram_dest_reg_714.net_ovflow_error)
110 deb_chk("sram net_ovflow_error\n");
111 if (v.sram_dest_reg_714.media_ovflow_error)
112 deb_chk("sram media_ovflow_error\n");
113 if (v.sram_dest_reg_714.cai_ovflow_error)
114 deb_chk("sram cai_ovflow_error\n");
115 if (v.sram_dest_reg_714.cai_ovflow_error)
116 deb_chk("sram cai_ovflow_error\n");
117
118 schedule_delayed_work(&fc_pci->irq_check_work,
119 msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
120}
121
91/* When PID filtering is turned on, we use the timer IRQ, because small amounts 122/* When PID filtering is turned on, we use the timer IRQ, because small amounts
92 * of data need to be passed to the user space instantly as well. When PID 123 * of data need to be passed to the user space instantly as well. When PID
93 * filtering is turned off, we use the page-change-IRQ */ 124 * filtering is turned off, we use the page-change-IRQ */
94static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs) 125static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs)
95{ 126{
96 struct flexcop_pci *fc_pci = dev_id; 127 struct flexcop_pci *fc_pci = dev_id;
97 struct flexcop_device *fc = fc_pci->fc_dev; 128 struct flexcop_device *fc = fc_pci->fc_dev;
98 flexcop_ibi_value v = fc->read_ibi_reg(fc,irq_20c); 129 flexcop_ibi_value v;
99 irqreturn_t ret = IRQ_HANDLED; 130 irqreturn_t ret = IRQ_HANDLED;
100 131
101 spin_lock_irq(&fc_pci->irq_lock); 132 spin_lock_irq(&fc_pci->irq_lock);
102 133
134 v = fc->read_ibi_reg(fc,irq_20c);
135
136 /* errors */
137 if (v.irq_20c.Data_receiver_error)
138 deb_chk("data receiver error\n");
139 if (v.irq_20c.Continuity_error_flag)
140 deb_chk("Contunuity error flag is set\n");
141 if (v.irq_20c.LLC_SNAP_FLAG_set)
142 deb_chk("LLC_SNAP_FLAG_set is set\n");
143 if (v.irq_20c.Transport_Error)
144 deb_chk("Transport error\n");
145
146 if ((fc_pci->count % 1000) == 0)
147 deb_chk("%d valid irq took place so far\n",fc_pci->count);
148
103 if (v.irq_20c.DMA1_IRQ_Status == 1) { 149 if (v.irq_20c.DMA1_IRQ_Status == 1) {
104 if (fc_pci->active_dma1_addr == 0) 150 if (fc_pci->active_dma1_addr == 0)
105 flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188); 151 flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
@@ -115,8 +161,9 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
115 fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; 161 fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
116 u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; 162 u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
117 163
118 deb_irq("irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ", 164 deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
119 v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos); 165 jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
166 fc_pci->last_irq = jiffies;
120 167
121 /* buffer end was reached, restarted from the beginning 168 /* buffer end was reached, restarted from the beginning
122 * pass the data from last_cur_pos to the buffer end to the demux 169 * pass the data from last_cur_pos to the buffer end to the demux
@@ -127,7 +174,6 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
127 fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, 174 fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
128 (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos); 175 (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
129 fc_pci->last_dma1_cur_pos = 0; 176 fc_pci->last_dma1_cur_pos = 0;
130 fc_pci->count = 0;
131 } 177 }
132 178
133 if (cur_pos > fc_pci->last_dma1_cur_pos) { 179 if (cur_pos > fc_pci->last_dma1_cur_pos) {
@@ -139,16 +185,14 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
139 deb_irq("\n"); 185 deb_irq("\n");
140 186
141 fc_pci->last_dma1_cur_pos = cur_pos; 187 fc_pci->last_dma1_cur_pos = cur_pos;
142 } else 188 fc_pci->count++;
189 } else {
190 deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
143 ret = IRQ_NONE; 191 ret = IRQ_NONE;
192 }
144 193
145 spin_unlock_irq(&fc_pci->irq_lock); 194 spin_unlock_irq(&fc_pci->irq_lock);
146 195
147/* packet count would be ideal for hw filtering, but it isn't working. Either
148 * the data book is wrong, or I'm unable to read it correctly */
149
150/* if (v.irq_20c.DMA1_Size_IRQ_Status == 1) { packet counter */
151
152 return ret; 196 return ret;
153} 197}
154 198
@@ -156,30 +200,35 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
156{ 200{
157 struct flexcop_pci *fc_pci = fc->bus_specific; 201 struct flexcop_pci *fc_pci = fc->bus_specific;
158 if (onoff) { 202 if (onoff) {
159 flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1); 203 flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
160 flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1); 204 flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
161 flexcop_dma_config_timer(fc,FC_DMA_1,1);
162 205
163 if (fc_pci->fc_dev->pid_filtering) { 206 flexcop_dma_config_timer(fc,FC_DMA_1,0);
164 fc_pci->last_dma1_cur_pos = 0;
165 flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
166 } else {
167 fc_pci->active_dma1_addr = 0;
168 flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
169 }
170 207
171/* flexcop_dma_config_packet_count(fc,FC_DMA_1,0xc0); 208 flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
172 flexcop_dma_control_packet_irq(fc,FC_DMA_1,1); */ 209 deb_irq("DMA xfer enabled\n");
173 210
174 deb_irq("irqs enabled\n"); 211 fc_pci->last_dma1_cur_pos = 0;
212 flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
213 deb_irq("IRQ enabled\n");
214
215// fc_pci->active_dma1_addr = 0;
216// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
217
218 if (irq_chk_intv > 0)
219 schedule_delayed_work(&fc_pci->irq_check_work,
220 msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
175 } else { 221 } else {
176 if (fc_pci->fc_dev->pid_filtering) 222 if (irq_chk_intv > 0)
177 flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); 223 cancel_delayed_work(&fc_pci->irq_check_work);
178 else 224
179 flexcop_dma_control_size_irq(fc,FC_DMA_1,0); 225 flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
226 deb_irq("IRQ disabled\n");
180 227
181// flexcop_dma_control_packet_irq(fc,FC_DMA_1,0); 228// flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
182 deb_irq("irqs disabled\n"); 229
230 flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
231 deb_irq("DMA xfer disabled\n");
183 } 232 }
184 233
185 return 0; 234 return 0;
@@ -198,6 +247,7 @@ static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
198 flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); 247 flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
199 248
200 fc_pci->init_state |= FC_PCI_DMA_INIT; 249 fc_pci->init_state |= FC_PCI_DMA_INIT;
250
201 goto success; 251 goto success;
202dma1_free: 252dma1_free:
203 flexcop_dma_free(&fc_pci->dma[0]); 253 flexcop_dma_free(&fc_pci->dma[0]);
@@ -244,7 +294,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
244 294
245 pci_set_drvdata(fc_pci->pdev, fc_pci); 295 pci_set_drvdata(fc_pci->pdev, fc_pci);
246 296
247 if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_irq, 297 if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
248 SA_SHIRQ, DRIVER_NAME, fc_pci)) != 0) 298 SA_SHIRQ, DRIVER_NAME, fc_pci)) != 0)
249 goto err_pci_iounmap; 299 goto err_pci_iounmap;
250 300
@@ -324,6 +374,8 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
324 if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) 374 if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
325 goto err_fc_exit; 375 goto err_fc_exit;
326 376
377 INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci);
378
327 goto success; 379 goto success;
328err_fc_exit: 380err_fc_exit:
329 flexcop_device_exit(fc); 381 flexcop_device_exit(fc);
@@ -350,17 +402,17 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
350 402
351static struct pci_device_id flexcop_pci_tbl[] = { 403static struct pci_device_id flexcop_pci_tbl[] = {
352 { PCI_DEVICE(0x13d0, 0x2103) }, 404 { PCI_DEVICE(0x13d0, 0x2103) },
353/* { PCI_DEVICE(0x13d0, 0x2200) }, PCI FlexCopIII ? */ 405/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */
354 { }, 406 { },
355}; 407};
356 408
357MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl); 409MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
358 410
359static struct pci_driver flexcop_pci_driver = { 411static struct pci_driver flexcop_pci_driver = {
360 .name = "Technisat/B2C2 FlexCop II/IIb/III PCI", 412 .name = "b2c2_flexcop_pci",
361 .id_table = flexcop_pci_tbl, 413 .id_table = flexcop_pci_tbl,
362 .probe = flexcop_pci_probe, 414 .probe = flexcop_pci_probe,
363 .remove = flexcop_pci_remove, 415 .remove = flexcop_pci_remove,
364}; 416};
365 417
366static int __init flexcop_pci_module_init(void) 418static int __init flexcop_pci_module_init(void)
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 75b50f21afe6..4ae1eb5bfe98 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -36,555 +36,21 @@ typedef enum {
36extern const char *flexcop_device_names[]; 36extern const char *flexcop_device_names[];
37 37
38/* FlexCop IBI Registers */ 38/* FlexCop IBI Registers */
39#if defined(__LITTLE_ENDIAN)
40 #include "flexcop_ibi_value_le.h"
41#elif defined(__BIG_ENDIAN)
42 #include "flexcop_ibi_value_be.h"
43#else
44 #error no endian defined
45#endif
39 46
40/* flexcop_ibi_reg - a huge union representing the register structure */
41typedef union {
42 u32 raw;
43
44/* DMA 0x000 to 0x01c
45 * DMA1 0x000 to 0x00c
46 * DMA2 0x010 to 0x01c
47 */
48 struct {
49 u32 dma_0start : 1; /* set: data will be delivered to dma1_address0 */
50 u32 dma_0No_update : 1; /* set: dma1_cur_address will be updated, unset: no update */
51 u32 dma_address0 :30; /* physical/virtual host memory address0 DMA */
52 } dma_0x0;
53
54 struct {
55 u32 DMA_maxpackets : 8; /* (remapped) PCI DMA1 Packet Count Interrupt. This variable
56 is able to be read and written while bit(1) of register
57 0x00c (remap_enable) is set. This variable represents
58 the number of packets that will be transmitted to the PCI
59 host using PCI DMA1 before an interrupt to the PCI is
60 asserted. This functionality may be enabled using bit(20)
61 of register 0x208. N=0 disables the IRQ. */
62 u32 dma_addr_size :24; /* size of memory buffer in DWORDs (bytesize / 4) for DMA */
63 } dma_0x4_remap;
64
65 struct {
66 u32 dma1timer : 7; /* reading PCI DMA1 timer ... when remap_enable is 0 */
67 u32 unused : 1;
68 u32 dma_addr_size :24;
69 } dma_0x4_read;
70
71 struct {
72 u32 unused : 1;
73 u32 dmatimer : 7; /* writing PCI DMA1 timer ... when remap_enable is 0 */
74 u32 dma_addr_size :24;
75 } dma_0x4_write;
76
77 struct {
78 u32 unused : 2;
79 u32 dma_cur_addr :30; /* current physical host memory address pointer for DMA */
80 } dma_0x8;
81
82 struct {
83 u32 dma_1start : 1; /* set: data will be delivered to dma_address1, when dma_address0 is full */
84 u32 remap_enable : 1; /* remap enable for 0x0x4(7:0) */
85 u32 dma_address1 :30; /* Physical/virtual address 1 on DMA */
86 } dma_0xc;
87
88/* Two-wire Serial Master and Clock 0x100-0x110 */
89 struct {
90// u32 slave_transmitter : 1; /* ???*/
91 u32 chipaddr : 7; /* two-line serial address of the target slave */
92 u32 reserved1 : 1;
93 u32 baseaddr : 8; /* address of the location of the read/write operation */
94 u32 data1_reg : 8; /* first byte in two-line serial read/write operation */
95 u32 working_start : 1; /* when doing a write operation this indicator is 0 when ready
96 * set to 1 when doing a write operation */
97 u32 twoWS_rw : 1; /* read/write indicator (1 = read, 0 write) */
98 u32 total_bytes : 2; /* number of data bytes in each two-line serial transaction (0 = 1 byte, 11 = 4byte)*/
99 u32 twoWS_port_reg : 2; /* port selection: 01 - Front End/Demod, 10 - EEPROM, 11 - Tuner */
100 u32 no_base_addr_ack_error : 1; /* writing: write-req: frame is produced w/o baseaddr, read-req: read-cycles w/o
101 * preceding address assignment write frame
102 * ACK_ERROR = 1 when no ACK from slave in the last transaction */
103 u32 st_done : 1; /* indicator for transaction is done */
104 } tw_sm_c_100;
105
106 struct {
107 u32 data2_reg : 8; /* 2nd data byte */
108 u32 data3_reg : 8; /* 3rd data byte */
109 u32 data4_reg : 8; /* 4th data byte */
110 u32 exlicit_stops : 1; /* when set, transactions are produced w/o trailing STOP flag, then send isolated STOP flags */
111 u32 force_stop : 1; /* isolated stop flag */
112 u32 unused : 6;
113 } tw_sm_c_104;
114
115/* Clock. The register allows the FCIII to convert an incoming Master clock
116 * (MCLK) signal into a lower frequency clock through the use of a LowCounter
117 * (TLO) and a High- Counter (THI). The time counts for THI and TLO are
118 * measured in MCLK; each count represents 4 MCLK input clock cycles.
119 *
120 * The default output for port #1 is set for Front End Demod communication. (0x108)
121 * The default output for port #2 is set for EEPROM communication. (0x10c)
122 * The default output for port #3 is set for Tuner communication. (0x110)
123 */
124 struct {
125 u32 thi1 : 6; /* Thi for port #1 (def: 100110b; 38) */
126 u32 reserved1 : 2;
127 u32 tlo1 : 5; /* Tlo for port #1 (def: 11100b; 28) */
128 u32 reserved2 :19;
129 } tw_sm_c_108;
130
131 struct {
132 u32 thi1 : 6; /* Thi for port #2 (def: 111001b; 57) */
133 u32 reserved1 : 2;
134 u32 tlo1 : 5; /* Tlo for port #2 (def: 11100b; 28) */
135 u32 reserved2 :19;
136 } tw_sm_c_10c;
137
138 struct {
139 u32 thi1 : 6; /* Thi for port #3 (def: 111001b; 57) */
140 u32 reserved1 : 2;
141 u32 tlo1 : 5; /* Tlo for port #3 (def: 11100b; 28) */
142 u32 reserved2 :19;
143 } tw_sm_c_110;
144
145/* LNB Switch Frequency 0x200
146 * Clock that creates the LNB switch tone. The default is set to have a fixed
147 * low output (not oscillating) to the LNB_CTL line.
148 */
149 struct {
150 u32 LNB_CTLHighCount_sig :15; /* It is the number of pre-scaled clock cycles that will be low. */
151 u32 LNB_CTLLowCount_sig :15; /* For example, to obtain a 22KHz output given a 45 Mhz Master
152 Clock signal (MCLK), set PreScalar=01 and LowCounter value to 0x1ff. */
153 u32 LNB_CTLPrescaler_sig : 2; /* pre-scaler divides MCLK: 00 (no division), 01 by 2, 10 by 4, 11 by 12 */
154 } lnb_switch_freq_200;
155
156/* ACPI, Peripheral Reset, LNB Polarity
157 * ACPI power conservation mode, LNB polarity selection (low or high voltage),
158 * and peripheral reset.
159 */
160 struct {
161 u32 ACPI1_sig : 1; /* turn of the power of tuner and LNB, not implemented in FCIII */
162 u32 ACPI3_sig : 1; /* turn of power of the complete satelite receiver board (except FCIII) */
163 u32 LNB_L_H_sig : 1; /* low or high voltage for LNB. (0 = low, 1 = high) */
164 u32 Per_reset_sig : 1; /* misc. init reset (default: 1), to reset set to low and back to high */
165 u32 reserved :20;
166 u32 Rev_N_sig_revision_hi : 4;/* 0xc in case of FCIII */
167 u32 Rev_N_sig_reserved1 : 2;
168 u32 Rev_N_sig_caps : 1; /* if 1, FCIII has 32 PID- and MAC-filters and is capable of IP multicast */
169 u32 Rev_N_sig_reserved2 : 1;
170 } misc_204;
171
172/* Control and Status 0x208 to 0x21c */
173/* Gross enable and disable control */
174 struct {
175 u32 Stream1_filter_sig : 1; /* Stream1 PID filtering */
176 u32 Stream2_filter_sig : 1; /* Stream2 PID filtering */
177 u32 PCR_filter_sig : 1; /* PCR PID filter */
178 u32 PMT_filter_sig : 1; /* PMT PID filter */
179
180 u32 EMM_filter_sig : 1; /* EMM PID filter */
181 u32 ECM_filter_sig : 1; /* ECM PID filter */
182 u32 Null_filter_sig : 1; /* Filters null packets, PID=0x1fff. */
183 u32 Mask_filter_sig : 1; /* mask PID filter */
184
185 u32 WAN_Enable_sig : 1; /* WAN output line through V8 memory space is activated. */
186 u32 WAN_CA_Enable_sig : 1; /* not in FCIII */
187 u32 CA_Enable_sig : 1; /* not in FCIII */
188 u32 SMC_Enable_sig : 1; /* CI stream data (CAI) goes directly to the smart card intf (opposed IBI 0x600 or SC-cmd buf). */
189
190 u32 Per_CA_Enable_sig : 1; /* not in FCIII */
191 u32 Multi2_Enable_sig : 1; /* ? */
192 u32 MAC_filter_Mode_sig : 1; /* (MAC_filter_enable) Globally enables MAC filters for Net PID filteres. */
193 u32 Rcv_Data_sig : 1; /* PID filtering module enable. When this bit is a one, the PID filter will
194 examine and process packets according to all other (individual) PID
195 filtering controls. If it a zero, no packet processing of any kind will
196 take place. All data from the tuner will be thrown away. */
197
198 u32 DMA1_IRQ_Enable_sig : 1; /* When set, a DWORD counter is enabled on PCI DMA1 that asserts the PCI
199 * interrupt after the specified count for filling the buffer. */
200 u32 DMA1_Timer_Enable_sig : 1; /* When set, a timer is enabled on PCI DMA1 that asserts the PCI interrupt
201 after a specified amount of time. */
202 u32 DMA2_IRQ_Enable_sig : 1; /* same as DMA1_IRQ_Enable_sig but for DMA2 */
203 u32 DMA2_Timer_Enable_sig : 1; /* same as DMA1_Timer_Enable_sig but for DMA2 */
204
205 u32 DMA1_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA1 that asserts the PCI interrupt. */
206 u32 DMA2_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA2 that asserts the PCI interrupt. */
207 u32 Mailbox_from_V8_Enable_sig: 1; /* When set, writes to the mailbox register produce an interrupt to the
208 PCI host to indicate that mailbox data is available. */
209
210 u32 unused : 9;
211 } ctrl_208;
212
213/* General status. When a PCI interrupt occurs, this register is read to
214 * discover the reason for the interrupt.
215 */
216 struct {
217 u32 DMA1_IRQ_Status : 1; /* When set(1) the DMA1 counter had generated an IRQ. Read Only. */
218 u32 DMA1_Timer_Status : 1; /* When set(1) the DMA1 timer had generated an IRQ. Read Only. */
219 u32 DMA2_IRQ_Status : 1; /* When set(1) the DMA2 counter had generated an IRQ. Read Only. */
220 u32 DMA2_Timer_Status : 1; /* When set(1) the DMA2 timer had generated an IRQ. Read Only. */
221 u32 DMA1_Size_IRQ_Status : 1; /* (Read only). This register is read after an interrupt to */
222 u32 DMA2_Size_IRQ_Status : 1; /* find out why we had an IRQ. Reading this register will clear this bit. Packet count*/
223 u32 Mailbox_from_V8_Status_sig: 1; /* Same as above. Reading this register will clear this bit. */
224 u32 Data_receiver_error : 1; /* 1 indicate an error in the receiver Front End (Tuner module) */
225 u32 Continuity_error_flag : 1; /* 1 indicates a continuity error in the TS stream. */
226 u32 LLC_SNAP_FLAG_set : 1; /* 1 indicates that the LCC_SNAP_FLAG was set. */
227 u32 Transport_Error : 1; /* When set indicates that an unexpected packet was received. */
228 u32 reserved :21;
229 } irq_20c;
230
231
232/* Software reset register */
233 struct {
234 u32 reset_blocks : 8; /* Enabled when Block_reset_enable = 0xB2 and 0x208 bits 15:8 = 0x00.
235 Each bit location represents a 0x100 block of registers. Writing
236 a one in a bit location resets that block of registers and the logic
237 that it controls. */
238 u32 Block_reset_enable : 8; /* This variable is set to 0xB2 when the register is written. */
239 u32 Special_controls :16; /* Asserts Reset_V8 => 0xC258; Turns on pci encryption => 0xC25A;
240 Turns off pci encryption => 0xC259 Note: pci_encryption default
241 at power-up is ON. */
242 } sw_reset_210;
243
244 struct {
245 u32 vuart_oe_sig : 1; /* When clear, the V8 processor has sole control of the serial UART
246 (RS-232 Smart Card interface). When set, the IBI interface
247 defined by register 0x600 controls the serial UART. */
248 u32 v2WS_oe_sig : 1; /* When clear, the V8 processor has direct control of the Two-line
249 Serial Master EEPROM target. When set, the Two-line Serial Master
250 EEPROM target interface is controlled by IBI register 0x100. */
251 u32 halt_V8_sig : 1; /* When set, contiguous wait states are applied to the V8-space
252 bus masters. Once this signal is cleared, normal V8-space
253 operations resume. */
254 u32 section_pkg_enable_sig: 1; /* When set, this signal enables the front end translation circuitry
255 to process section packed transport streams. */
256 u32 s2p_sel_sig : 1; /* Serial to parallel conversion. When set, polarized transport data
257 within the FlexCop3 front end circuitry is converted from a serial
258 stream into parallel data before downstream processing otherwise
259 interprets the data. */
260 u32 unused1 : 3;
261 u32 polarity_PS_CLK_sig: 1; /* This signal is used to invert the input polarity of the tranport
262 stream CLOCK signal before any processing occurs on the transport
263 stream within FlexCop3. */
264 u32 polarity_PS_VALID_sig: 1; /* This signal is used to invert the input polarity of the tranport
265 stream VALID signal before any processing occurs on the transport
266 stream within FlexCop3. */
267 u32 polarity_PS_SYNC_sig: 1; /* This signal is used to invert the input polarity of the tranport
268 stream SYNC signal before any processing occurs on the transport
269 stream within FlexCop3. */
270 u32 polarity_PS_ERR_sig: 1; /* This signal is used to invert the input polarity of the tranport
271 stream ERROR signal before any processing occurs on the transport
272 stream within FlexCop3. */
273 u32 unused2 :20;
274 } misc_214;
275
276/* Mailbox from V8 to host */
277 struct {
278 u32 Mailbox_from_V8 :32; /* When this register is written by either the V8 processor or by an
279 end host, an interrupt is generated to the PCI host to indicate
280 that mailbox data is available. Reading register 20c will clear
281 the IRQ. */
282 } mbox_v8_to_host_218;
283
284/* Mailbox from host to v8 Mailbox_to_V8
285 * Mailbox_to_V8 mailbox storage register
286 * used to send messages from PCI to V8. Writing to this register will send an
287 * IRQ to the V8. Then it can read the data from here. Reading this register
288 * will clear the IRQ. If the V8 is halted and bit 31 of this register is set,
289 * then this register is used instead as a direct interface to access the
290 * V8space memory.
291 */
292 struct {
293 u32 sysramaccess_data : 8; /* Data byte written or read from the specified address in V8 SysRAM. */
294 u32 sysramaccess_addr :15; /* 15 bit address used to access V8 Sys-RAM. */
295 u32 unused : 7;
296 u32 sysramaccess_write: 1; /* Write flag used to latch data into the V8 SysRAM. */
297 u32 sysramaccess_busmuster: 1; /* Setting this bit when the V8 is halted at 0x214 Bit(2) allows
298 this IBI register interface to directly drive the V8-space memory. */
299 } mbox_host_to_v8_21c;
300
301
302/* PIDs, Translation Bit, SMC Filter Select 0x300 to 0x31c */
303 struct {
304 u32 Stream1_PID :13; /* Primary use is receiving Net data, so these 13 bits normally
305 hold the PID value for the desired network stream. */
306 u32 Stream1_trans : 1; /* When set, Net translation will take place for Net data ferried in TS packets. */
307 u32 MAC_Multicast_filter : 1; /* When clear, multicast MAC filtering is not allowed for Stream1 and PID_n filters. */
308 u32 debug_flag_pid_saved : 1;
309 u32 Stream2_PID :13; /* 13 bits for Stream 2 PID filter value. General use. */
310 u32 Stream2_trans : 1; /* When set Tables/CAI translation will take place for the data ferried in
311 Stream2_PID TS packets. */
312 u32 debug_flag_write_status00 : 1;
313 u32 debug_fifo_problem : 1;
314 } pid_filter_300;
315
316 struct {
317 u32 PCR_PID :13; /* PCR stream PID filter value. Primary use is Program Clock Reference stream filtering. */
318 u32 PCR_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
319 u32 debug_overrun3 : 1;
320 u32 debug_overrun2 : 1;
321 u32 PMT_PID :13; /* stream PID filter value. Primary use is Program Management Table segment filtering. */
322 u32 PMT_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
323 u32 reserved : 2;
324 } pid_filter_304;
325
326 struct {
327 u32 EMM_PID :13; /* EMM PID filter value. Primary use is Entitlement Management Messaging for
328 conditional access-related data. */
329 u32 EMM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
330 u32 EMM_filter_4 : 1; /* When set will pass only EMM data possessing the same ID code as the
331 first four bytes (32 bits) of the end-user s 6-byte Smart Card ID number Select */
332 u32 EMM_filter_6 : 1; /* When set will pass only EMM data possessing the same 6-byte code as the end-users
333 complete 6-byte Smart Card ID number. */
334 u32 ECM_PID :13; /* ECM PID filter value. Primary use is Entitlement Control Messaging for conditional
335 access-related data. */
336 u32 ECM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
337 u32 reserved : 2;
338 } pid_filter_308;
339
340 struct {
341 u32 Group_PID :13; /* PID value for group filtering. */
342 u32 Group_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
343 u32 unused1 : 2;
344 u32 Group_mask :13; /* Mask value used in logical "and" equation that defines group filtering */
345 u32 unused2 : 3;
346 } pid_filter_30c_ext_ind_0_7;
347
348 struct {
349 u32 net_master_read :17;
350 u32 unused :15;
351 } pid_filter_30c_ext_ind_1;
352
353 struct {
354 u32 net_master_write :17;
355 u32 unused :15;
356 } pid_filter_30c_ext_ind_2;
357
358 struct {
359 u32 next_net_master_write :17;
360 u32 unused :15;
361 } pid_filter_30c_ext_ind_3;
362
363 struct {
364 u32 unused1 : 1;
365 u32 state_write :10;
366 u32 reserved1 : 6; /* default: 000100 */
367 u32 stack_read :10;
368 u32 reserved2 : 5; /* default: 00100 */
369 } pid_filter_30c_ext_ind_4;
370
371 struct {
372 u32 stack_cnt :10;
373 u32 unused :22;
374 } pid_filter_30c_ext_ind_5;
375
376 struct {
377 u32 pid_fsm_save_reg0 : 2;
378 u32 pid_fsm_save_reg1 : 2;
379 u32 pid_fsm_save_reg2 : 2;
380 u32 pid_fsm_save_reg3 : 2;
381 u32 pid_fsm_save_reg4 : 2;
382 u32 pid_fsm_save_reg300 : 2;
383 u32 write_status1 : 2;
384 u32 write_status4 : 2;
385 u32 data_size_reg :12;
386 u32 unused : 4;
387 } pid_filter_30c_ext_ind_6;
388
389 struct {
390 u32 index_reg : 5; /* (Index pointer) Points at an internal PIDn register. A binary code
391 representing one of 32 internal PIDn registers as well as its
392 corresponding internal MAC_lown register. */
393 u32 extra_index_reg : 3; /* This vector is used to select between sets of debug signals routed to register 0x30c. */
394 u32 AB_select : 1; /* Used in conjunction with 0x31c. read/write to the MAC_highA or MAC_highB register
395 0=MAC_highB register, 1=MAC_highA */
396 u32 pass_alltables : 1; /* 1=Net packets are not filtered against the Network Table ID found in register 0x400.
397 All types of networks (DVB, ATSC, ISDB) are passed. */
398 u32 unused :22;
399 } index_reg_310;
400
401 struct {
402 u32 PID :13; /* PID value */
403 u32 PID_trans : 1; /* translation will take place for packets filtered */
404 u32 PID_enable_bit : 1; /* When set this PID filter is enabled */
405 u32 reserved :17;
406 } pid_n_reg_314;
407
408 struct {
409 u32 A4_byte : 8;
410 u32 A5_byte : 8;
411 u32 A6_byte : 8;
412 u32 Enable_bit : 1; /* enabled (1) or disabled (1) */
413 u32 HighAB_bit : 1; /* use MAC_highA (1) or MAC_highB (0) as MSB */
414 u32 reserved : 6;
415 } mac_low_reg_318;
416
417 struct {
418 u32 A1_byte : 8;
419 u32 A2_byte : 8;
420 u32 A3_byte : 8;
421 u32 reserved : 8;
422 } mac_high_reg_31c;
423
424/* Table, SMCID,MACDestination Filters 0x400 to 0x41c */
425 struct {
426 u32 reserved :16;
427#define fc_data_Tag_ID_DVB 0x3e 47#define fc_data_Tag_ID_DVB 0x3e
428#define fc_data_Tag_ID_ATSC 0x3f 48#define fc_data_Tag_ID_ATSC 0x3f
429#define fc_data_Tag_ID_IDSB 0x8b 49#define fc_data_Tag_ID_IDSB 0x8b
430 u32 data_Tag_ID :16;
431 } data_tag_400;
432
433 struct {
434 u32 Card_IDbyte6 : 8;
435 u32 Card_IDbyte5 : 8;
436 u32 Card_IDbyte4 : 8;
437 u32 Card_IDbyte3 : 8;
438 } card_id_408;
439
440 struct {
441 u32 Card_IDbyte2 : 8;
442 u32 Card_IDbyte1 : 8;
443 } card_id_40c;
444
445 /* holding the unique mac address of the receiver which houses the FlexCopIII */
446 struct {
447 u32 MAC1 : 8;
448 u32 MAC2 : 8;
449 u32 MAC3 : 8;
450 u32 MAC6 : 8;
451 } mac_address_418;
452
453 struct {
454 u32 MAC7 : 8;
455 u32 MAC8 : 8;
456 u32 reserved : 16;
457 } mac_address_41c;
458
459 struct {
460 u32 transmitter_data_byte : 8;
461 u32 ReceiveDataReady : 1;
462 u32 ReceiveByteFrameError: 1;
463 u32 txbuffempty : 1;
464 u32 reserved :21;
465 } ci_600;
466
467 struct {
468 u32 pi_d : 8;
469 u32 pi_ha :20;
470 u32 pi_rw : 1;
471 u32 pi_component_reg : 3;
472 } pi_604;
473
474 struct {
475 u32 serialReset : 1;
476 u32 oncecycle_read : 1;
477 u32 Timer_Read_req : 1;
478 u32 Timer_Load_req : 1;
479 u32 timer_data : 7;
480 u32 unused : 1; /* ??? not mentioned in data book */
481 u32 Timer_addr : 5;
482 u32 reserved : 3;
483 u32 pcmcia_a_mod_pwr_n : 1;
484 u32 pcmcia_b_mod_pwr_n : 1;
485 u32 config_Done_stat : 1;
486 u32 config_Init_stat : 1;
487 u32 config_Prog_n : 1;
488 u32 config_wr_n : 1;
489 u32 config_cs_n : 1;
490 u32 config_cclk : 1;
491 u32 pi_CiMax_IRQ_n : 1;
492 u32 pi_timeout_status : 1;
493 u32 pi_wait_n : 1;
494 u32 pi_busy_n : 1;
495 } pi_608;
496 50
497 struct {
498 u32 PID :13;
499 u32 key_enable : 1;
500#define fc_key_code_default 0x1 51#define fc_key_code_default 0x1
501#define fc_key_code_even 0x2 52#define fc_key_code_even 0x2
502#define fc_key_code_odd 0x3 53#define fc_key_code_odd 0x3
503 u32 key_code : 2;
504 u32 key_array_col : 3;
505 u32 key_array_row : 5;
506 u32 dvb_en : 1; /* 0=TS bypasses the Descrambler */
507 u32 rw_flag : 1;
508 u32 reserved : 6;
509 } dvb_reg_60c;
510
511/* SRAM and Output Destination 0x700 to 0x714 */
512 struct {
513 u32 sram_addr :15;
514 u32 sram_rw : 1; /* 0=write, 1=read */
515 u32 sram_data : 8;
516 u32 sc_xfer_bit : 1;
517 u32 reserved1 : 3;
518 u32 oe_pin_reg : 1;
519 u32 ce_pin_reg : 1;
520 u32 reserved2 : 1;
521 u32 start_sram_ibi : 1;
522 } sram_ctrl_reg_700;
523
524 struct {
525 u32 net_addr_read :16;
526 u32 net_addr_write :16;
527 } net_buf_reg_704;
528
529 struct {
530 u32 cai_read :11;
531 u32 reserved1 : 5;
532 u32 cai_write :11;
533 u32 reserved2 : 6;
534 u32 cai_cnt : 4;
535 } cai_buf_reg_708;
536
537 struct {
538 u32 cao_read :11;
539 u32 reserved1 : 5;
540 u32 cap_write :11;
541 u32 reserved2 : 6;
542 u32 cao_cnt : 4;
543 } cao_buf_reg_70c;
544
545 struct {
546 u32 media_read :11;
547 u32 reserved1 : 5;
548 u32 media_write :11;
549 u32 reserved2 : 6;
550 u32 media_cnt : 4;
551 } media_buf_reg_710;
552
553 struct {
554 u32 NET_Dest : 2;
555 u32 CAI_Dest : 2;
556 u32 CAO_Dest : 2;
557 u32 MEDIA_Dest : 2;
558 u32 net_ovflow_error : 1;
559 u32 media_ovflow_error : 1;
560 u32 cai_ovflow_error : 1;
561 u32 cao_ovflow_error : 1;
562 u32 ctrl_usb_wan : 1;
563 u32 ctrl_sramdma : 1;
564 u32 ctrl_maximumfill : 1;
565 u32 reserved :17;
566 } sram_dest_reg_714;
567
568 struct {
569 u32 net_cnt :12;
570 u32 reserved1 : 4;
571 u32 net_addr_read : 1;
572 u32 reserved2 : 3;
573 u32 net_addr_write : 1;
574 u32 reserved3 :11;
575 } net_buf_reg_718;
576
577 struct {
578 u32 wan_speed_sig : 2;
579 u32 reserved1 : 6;
580 u32 wan_wait_state : 8;
581 u32 sram_chip : 2;
582 u32 sram_memmap : 2;
583 u32 reserved2 : 4;
584 u32 wan_pkt_frame : 4;
585 u32 reserved3 : 4;
586 } wan_ctrl_reg_71c;
587} flexcop_ibi_value;
588 54
589extern flexcop_ibi_value ibi_zero; 55extern flexcop_ibi_value ibi_zero;
590 56
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index 0113449abd15..0a78ba3737a5 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -545,7 +545,7 @@ static struct usb_device_id flexcop_usb_table [] = {
545/* usb specific object needed to register this driver with the usb subsystem */ 545/* usb specific object needed to register this driver with the usb subsystem */
546static struct usb_driver flexcop_usb_driver = { 546static struct usb_driver flexcop_usb_driver = {
547 .owner = THIS_MODULE, 547 .owner = THIS_MODULE,
548 .name = "Technisat/B2C2 FlexCop II/IIb/III USB", 548 .name = "b2c2_flexcop_usb",
549 .probe = flexcop_usb_probe, 549 .probe = flexcop_usb_probe,
550 .disconnect = flexcop_usb_disconnect, 550 .disconnect = flexcop_usb_disconnect,
551 .id_table = flexcop_usb_table, 551 .id_table = flexcop_usb_table,
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 8b5d14dd36e3..12873d435406 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -46,7 +46,7 @@
46 46
47int b2c2_flexcop_debug; 47int b2c2_flexcop_debug;
48module_param_named(debug, b2c2_flexcop_debug, int, 0644); 48module_param_named(debug, b2c2_flexcop_debug, int, 0644);
49MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram (|-able))." DEBSTATUS); 49MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
50#undef DEBSTATUS 50#undef DEBSTATUS
51 51
52/* global zero for ibi values */ 52/* global zero for ibi values */
@@ -173,9 +173,20 @@ static void flexcop_reset(struct flexcop_device *fc)
173 fc->write_ibi_reg(fc,ctrl_208,ibi_zero); 173 fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
174 174
175 v210.raw = 0; 175 v210.raw = 0;
176 v210.sw_reset_210.reset_blocks = 0xff; 176 v210.sw_reset_210.reset_block_000 = 1;
177 v210.sw_reset_210.reset_block_100 = 1;
178 v210.sw_reset_210.reset_block_200 = 1;
179 v210.sw_reset_210.reset_block_300 = 1;
180 v210.sw_reset_210.reset_block_400 = 1;
181 v210.sw_reset_210.reset_block_500 = 1;
182 v210.sw_reset_210.reset_block_600 = 1;
183 v210.sw_reset_210.reset_block_700 = 1;
177 v210.sw_reset_210.Block_reset_enable = 0xb2; 184 v210.sw_reset_210.Block_reset_enable = 0xb2;
185
186 v210.sw_reset_210.Special_controls = 0xc259;
187
178 fc->write_ibi_reg(fc,sw_reset_210,v210); 188 fc->write_ibi_reg(fc,sw_reset_210,v210);
189 msleep(1);
179 190
180/* reset the periphical devices */ 191/* reset the periphical devices */
181 192
@@ -186,6 +197,25 @@ static void flexcop_reset(struct flexcop_device *fc)
186 fc->write_ibi_reg(fc,misc_204,v204); 197 fc->write_ibi_reg(fc,misc_204,v204);
187} 198}
188 199
200void flexcop_reset_block_300(struct flexcop_device *fc)
201{
202 flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
203 v210 = fc->read_ibi_reg(fc,sw_reset_210);
204
205 deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
206
207 fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
208
209 v210.sw_reset_210.reset_block_300 = 1;
210 v210.sw_reset_210.Block_reset_enable = 0xb2;
211
212 fc->write_ibi_reg(fc,sw_reset_210,v210);
213 msleep(1);
214
215 fc->write_ibi_reg(fc,ctrl_208,v208_save);
216}
217EXPORT_SYMBOL(flexcop_reset_block_300);
218
189struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len) 219struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
190{ 220{
191 void *bus; 221 void *bus;
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
index caa343a97bdc..0cebe1d92e0b 100644
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -26,5 +26,6 @@ extern int b2c2_flexcop_debug;
26#define deb_i2c(args...) dprintk(0x04,args) 26#define deb_i2c(args...) dprintk(0x04,args)
27#define deb_ts(args...) dprintk(0x08,args) 27#define deb_ts(args...) dprintk(0x08,args)
28#define deb_sram(args...) dprintk(0x10,args) 28#define deb_sram(args...) dprintk(0x10,args)
29#define deb_rdump(args...) dprintk(0x20,args)
29 30
30#endif 31#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
new file mode 100644
index 000000000000..ed9a6756b194
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -0,0 +1,458 @@
1/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2 *
3 * register descriptions
4 *
5 * see flexcop.c for copyright information.
6 */
7
8/* This file is automatically generated, do not edit things here. */
9#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
10#define __FLEXCOP_IBI_VALUE_INCLUDED__
11
12typedef union {
13 u32 raw;
14
15 struct {
16 u32 dma_address0 :30;
17 u32 dma_0No_update : 1;
18 u32 dma_0start : 1;
19 } dma_0x0;
20
21 struct {
22 u32 dma_addr_size :24;
23 u32 DMA_maxpackets : 8;
24 } dma_0x4_remap;
25
26 struct {
27 u32 dma_addr_size :24;
28 u32 unused : 1;
29 u32 dma1timer : 7;
30 } dma_0x4_read;
31
32 struct {
33 u32 dma_addr_size :24;
34 u32 dmatimer : 7;
35 u32 unused : 1;
36 } dma_0x4_write;
37
38 struct {
39 u32 dma_cur_addr :30;
40 u32 unused : 2;
41 } dma_0x8;
42
43 struct {
44 u32 dma_address1 :30;
45 u32 remap_enable : 1;
46 u32 dma_1start : 1;
47 } dma_0xc;
48
49 struct {
50 u32 st_done : 1;
51 u32 no_base_addr_ack_error : 1;
52 u32 twoWS_port_reg : 2;
53 u32 total_bytes : 2;
54 u32 twoWS_rw : 1;
55 u32 working_start : 1;
56 u32 data1_reg : 8;
57 u32 baseaddr : 8;
58 u32 reserved1 : 1;
59 u32 chipaddr : 7;
60 } tw_sm_c_100;
61
62 struct {
63 u32 unused : 6;
64 u32 force_stop : 1;
65 u32 exlicit_stops : 1;
66 u32 data4_reg : 8;
67 u32 data3_reg : 8;
68 u32 data2_reg : 8;
69 } tw_sm_c_104;
70
71 struct {
72 u32 reserved2 :19;
73 u32 tlo1 : 5;
74 u32 reserved1 : 2;
75 u32 thi1 : 6;
76 } tw_sm_c_108;
77
78 struct {
79 u32 reserved2 :19;
80 u32 tlo1 : 5;
81 u32 reserved1 : 2;
82 u32 thi1 : 6;
83 } tw_sm_c_10c;
84
85 struct {
86 u32 reserved2 :19;
87 u32 tlo1 : 5;
88 u32 reserved1 : 2;
89 u32 thi1 : 6;
90 } tw_sm_c_110;
91
92 struct {
93 u32 LNB_CTLPrescaler_sig : 2;
94 u32 LNB_CTLLowCount_sig :15;
95 u32 LNB_CTLHighCount_sig :15;
96 } lnb_switch_freq_200;
97
98 struct {
99 u32 Rev_N_sig_reserved2 : 1;
100 u32 Rev_N_sig_caps : 1;
101 u32 Rev_N_sig_reserved1 : 2;
102 u32 Rev_N_sig_revision_hi : 4;
103 u32 reserved :20;
104 u32 Per_reset_sig : 1;
105 u32 LNB_L_H_sig : 1;
106 u32 ACPI3_sig : 1;
107 u32 ACPI1_sig : 1;
108 } misc_204;
109
110 struct {
111 u32 unused : 9;
112 u32 Mailbox_from_V8_Enable_sig : 1;
113 u32 DMA2_Size_IRQ_Enable_sig : 1;
114 u32 DMA1_Size_IRQ_Enable_sig : 1;
115 u32 DMA2_Timer_Enable_sig : 1;
116 u32 DMA2_IRQ_Enable_sig : 1;
117 u32 DMA1_Timer_Enable_sig : 1;
118 u32 DMA1_IRQ_Enable_sig : 1;
119 u32 Rcv_Data_sig : 1;
120 u32 MAC_filter_Mode_sig : 1;
121 u32 Multi2_Enable_sig : 1;
122 u32 Per_CA_Enable_sig : 1;
123 u32 SMC_Enable_sig : 1;
124 u32 CA_Enable_sig : 1;
125 u32 WAN_CA_Enable_sig : 1;
126 u32 WAN_Enable_sig : 1;
127 u32 Mask_filter_sig : 1;
128 u32 Null_filter_sig : 1;
129 u32 ECM_filter_sig : 1;
130 u32 EMM_filter_sig : 1;
131 u32 PMT_filter_sig : 1;
132 u32 PCR_filter_sig : 1;
133 u32 Stream2_filter_sig : 1;
134 u32 Stream1_filter_sig : 1;
135 } ctrl_208;
136
137 struct {
138 u32 reserved :21;
139 u32 Transport_Error : 1;
140 u32 LLC_SNAP_FLAG_set : 1;
141 u32 Continuity_error_flag : 1;
142 u32 Data_receiver_error : 1;
143 u32 Mailbox_from_V8_Status_sig : 1;
144 u32 DMA2_Size_IRQ_Status : 1;
145 u32 DMA1_Size_IRQ_Status : 1;
146 u32 DMA2_Timer_Status : 1;
147 u32 DMA2_IRQ_Status : 1;
148 u32 DMA1_Timer_Status : 1;
149 u32 DMA1_IRQ_Status : 1;
150 } irq_20c;
151
152 struct {
153 u32 Special_controls :16;
154 u32 Block_reset_enable : 8;
155 u32 reset_block_700 : 1;
156 u32 reset_block_600 : 1;
157 u32 reset_block_500 : 1;
158 u32 reset_block_400 : 1;
159 u32 reset_block_300 : 1;
160 u32 reset_block_200 : 1;
161 u32 reset_block_100 : 1;
162 u32 reset_block_000 : 1;
163 } sw_reset_210;
164
165 struct {
166 u32 unused2 :20;
167 u32 polarity_PS_ERR_sig : 1;
168 u32 polarity_PS_SYNC_sig : 1;
169 u32 polarity_PS_VALID_sig : 1;
170 u32 polarity_PS_CLK_sig : 1;
171 u32 unused1 : 3;
172 u32 s2p_sel_sig : 1;
173 u32 section_pkg_enable_sig : 1;
174 u32 halt_V8_sig : 1;
175 u32 v2WS_oe_sig : 1;
176 u32 vuart_oe_sig : 1;
177 } misc_214;
178
179 struct {
180 u32 Mailbox_from_V8 :32;
181 } mbox_v8_to_host_218;
182
183 struct {
184 u32 sysramaccess_busmuster : 1;
185 u32 sysramaccess_write : 1;
186 u32 unused : 7;
187 u32 sysramaccess_addr :15;
188 u32 sysramaccess_data : 8;
189 } mbox_host_to_v8_21c;
190
191 struct {
192 u32 debug_fifo_problem : 1;
193 u32 debug_flag_write_status00 : 1;
194 u32 Stream2_trans : 1;
195 u32 Stream2_PID :13;
196 u32 debug_flag_pid_saved : 1;
197 u32 MAC_Multicast_filter : 1;
198 u32 Stream1_trans : 1;
199 u32 Stream1_PID :13;
200 } pid_filter_300;
201
202 struct {
203 u32 reserved : 2;
204 u32 PMT_trans : 1;
205 u32 PMT_PID :13;
206 u32 debug_overrun2 : 1;
207 u32 debug_overrun3 : 1;
208 u32 PCR_trans : 1;
209 u32 PCR_PID :13;
210 } pid_filter_304;
211
212 struct {
213 u32 reserved : 2;
214 u32 ECM_trans : 1;
215 u32 ECM_PID :13;
216 u32 EMM_filter_6 : 1;
217 u32 EMM_filter_4 : 1;
218 u32 EMM_trans : 1;
219 u32 EMM_PID :13;
220 } pid_filter_308;
221
222 struct {
223 u32 unused2 : 3;
224 u32 Group_mask :13;
225 u32 unused1 : 2;
226 u32 Group_trans : 1;
227 u32 Group_PID :13;
228 } pid_filter_30c_ext_ind_0_7;
229
230 struct {
231 u32 unused :15;
232 u32 net_master_read :17;
233 } pid_filter_30c_ext_ind_1;
234
235 struct {
236 u32 unused :15;
237 u32 net_master_write :17;
238 } pid_filter_30c_ext_ind_2;
239
240 struct {
241 u32 unused :15;
242 u32 next_net_master_write :17;
243 } pid_filter_30c_ext_ind_3;
244
245 struct {
246 u32 reserved2 : 5;
247 u32 stack_read :10;
248 u32 reserved1 : 6;
249 u32 state_write :10;
250 u32 unused1 : 1;
251 } pid_filter_30c_ext_ind_4;
252
253 struct {
254 u32 unused :22;
255 u32 stack_cnt :10;
256 } pid_filter_30c_ext_ind_5;
257
258 struct {
259 u32 unused : 4;
260 u32 data_size_reg :12;
261 u32 write_status4 : 2;
262 u32 write_status1 : 2;
263 u32 pid_fsm_save_reg300 : 2;
264 u32 pid_fsm_save_reg4 : 2;
265 u32 pid_fsm_save_reg3 : 2;
266 u32 pid_fsm_save_reg2 : 2;
267 u32 pid_fsm_save_reg1 : 2;
268 u32 pid_fsm_save_reg0 : 2;
269 } pid_filter_30c_ext_ind_6;
270
271 struct {
272 u32 unused :22;
273 u32 pass_alltables : 1;
274 u32 AB_select : 1;
275 u32 extra_index_reg : 3;
276 u32 index_reg : 5;
277 } index_reg_310;
278
279 struct {
280 u32 reserved :17;
281 u32 PID_enable_bit : 1;
282 u32 PID_trans : 1;
283 u32 PID :13;
284 } pid_n_reg_314;
285
286 struct {
287 u32 reserved : 6;
288 u32 HighAB_bit : 1;
289 u32 Enable_bit : 1;
290 u32 A6_byte : 8;
291 u32 A5_byte : 8;
292 u32 A4_byte : 8;
293 } mac_low_reg_318;
294
295 struct {
296 u32 reserved : 8;
297 u32 A3_byte : 8;
298 u32 A2_byte : 8;
299 u32 A1_byte : 8;
300 } mac_high_reg_31c;
301
302 struct {
303 u32 data_Tag_ID :16;
304 u32 reserved :16;
305 } data_tag_400;
306
307 struct {
308 u32 Card_IDbyte3 : 8;
309 u32 Card_IDbyte4 : 8;
310 u32 Card_IDbyte5 : 8;
311 u32 Card_IDbyte6 : 8;
312 } card_id_408;
313
314 struct {
315 u32 Card_IDbyte1 : 8;
316 u32 Card_IDbyte2 : 8;
317 } card_id_40c;
318
319 struct {
320 u32 MAC6 : 8;
321 u32 MAC3 : 8;
322 u32 MAC2 : 8;
323 u32 MAC1 : 8;
324 } mac_address_418;
325
326 struct {
327 u32 reserved :16;
328 u32 MAC8 : 8;
329 u32 MAC7 : 8;
330 } mac_address_41c;
331
332 struct {
333 u32 reserved :21;
334 u32 txbuffempty : 1;
335 u32 ReceiveByteFrameError : 1;
336 u32 ReceiveDataReady : 1;
337 u32 transmitter_data_byte : 8;
338 } ci_600;
339
340 struct {
341 u32 pi_component_reg : 3;
342 u32 pi_rw : 1;
343 u32 pi_ha :20;
344 u32 pi_d : 8;
345 } pi_604;
346
347 struct {
348 u32 pi_busy_n : 1;
349 u32 pi_wait_n : 1;
350 u32 pi_timeout_status : 1;
351 u32 pi_CiMax_IRQ_n : 1;
352 u32 config_cclk : 1;
353 u32 config_cs_n : 1;
354 u32 config_wr_n : 1;
355 u32 config_Prog_n : 1;
356 u32 config_Init_stat : 1;
357 u32 config_Done_stat : 1;
358 u32 pcmcia_b_mod_pwr_n : 1;
359 u32 pcmcia_a_mod_pwr_n : 1;
360 u32 reserved : 3;
361 u32 Timer_addr : 5;
362 u32 unused : 1;
363 u32 timer_data : 7;
364 u32 Timer_Load_req : 1;
365 u32 Timer_Read_req : 1;
366 u32 oncecycle_read : 1;
367 u32 serialReset : 1;
368 } pi_608;
369
370 struct {
371 u32 reserved : 6;
372 u32 rw_flag : 1;
373 u32 dvb_en : 1;
374 u32 key_array_row : 5;
375 u32 key_array_col : 3;
376 u32 key_code : 2;
377 u32 key_enable : 1;
378 u32 PID :13;
379 } dvb_reg_60c;
380
381 struct {
382 u32 start_sram_ibi : 1;
383 u32 reserved2 : 1;
384 u32 ce_pin_reg : 1;
385 u32 oe_pin_reg : 1;
386 u32 reserved1 : 3;
387 u32 sc_xfer_bit : 1;
388 u32 sram_data : 8;
389 u32 sram_rw : 1;
390 u32 sram_addr :15;
391 } sram_ctrl_reg_700;
392
393 struct {
394 u32 net_addr_write :16;
395 u32 net_addr_read :16;
396 } net_buf_reg_704;
397
398 struct {
399 u32 cai_cnt : 4;
400 u32 reserved2 : 6;
401 u32 cai_write :11;
402 u32 reserved1 : 5;
403 u32 cai_read :11;
404 } cai_buf_reg_708;
405
406 struct {
407 u32 cao_cnt : 4;
408 u32 reserved2 : 6;
409 u32 cap_write :11;
410 u32 reserved1 : 5;
411 u32 cao_read :11;
412 } cao_buf_reg_70c;
413
414 struct {
415 u32 media_cnt : 4;
416 u32 reserved2 : 6;
417 u32 media_write :11;
418 u32 reserved1 : 5;
419 u32 media_read :11;
420 } media_buf_reg_710;
421
422 struct {
423 u32 reserved :17;
424 u32 ctrl_maximumfill : 1;
425 u32 ctrl_sramdma : 1;
426 u32 ctrl_usb_wan : 1;
427 u32 cao_ovflow_error : 1;
428 u32 cai_ovflow_error : 1;
429 u32 media_ovflow_error : 1;
430 u32 net_ovflow_error : 1;
431 u32 MEDIA_Dest : 2;
432 u32 CAO_Dest : 2;
433 u32 CAI_Dest : 2;
434 u32 NET_Dest : 2;
435 } sram_dest_reg_714;
436
437 struct {
438 u32 reserved3 :11;
439 u32 net_addr_write : 1;
440 u32 reserved2 : 3;
441 u32 net_addr_read : 1;
442 u32 reserved1 : 4;
443 u32 net_cnt :12;
444 } net_buf_reg_718;
445
446 struct {
447 u32 reserved3 : 4;
448 u32 wan_pkt_frame : 4;
449 u32 reserved2 : 4;
450 u32 sram_memmap : 2;
451 u32 sram_chip : 2;
452 u32 wan_wait_state : 8;
453 u32 reserved1 : 6;
454 u32 wan_speed_sig : 2;
455 } wan_ctrl_reg_71c;
456} flexcop_ibi_value;
457
458#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
new file mode 100644
index 000000000000..49f2315b6e58
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -0,0 +1,458 @@
1/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2 *
3 * register descriptions
4 *
5 * see flexcop.c for copyright information.
6 */
7
8/* This file is automatically generated, do not edit things here. */
9#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
10#define __FLEXCOP_IBI_VALUE_INCLUDED__
11
12typedef union {
13 u32 raw;
14
15 struct {
16 u32 dma_0start : 1;
17 u32 dma_0No_update : 1;
18 u32 dma_address0 :30;
19 } dma_0x0;
20
21 struct {
22 u32 DMA_maxpackets : 8;
23 u32 dma_addr_size :24;
24 } dma_0x4_remap;
25
26 struct {
27 u32 dma1timer : 7;
28 u32 unused : 1;
29 u32 dma_addr_size :24;
30 } dma_0x4_read;
31
32 struct {
33 u32 unused : 1;
34 u32 dmatimer : 7;
35 u32 dma_addr_size :24;
36 } dma_0x4_write;
37
38 struct {
39 u32 unused : 2;
40 u32 dma_cur_addr :30;
41 } dma_0x8;
42
43 struct {
44 u32 dma_1start : 1;
45 u32 remap_enable : 1;
46 u32 dma_address1 :30;
47 } dma_0xc;
48
49 struct {
50 u32 chipaddr : 7;
51 u32 reserved1 : 1;
52 u32 baseaddr : 8;
53 u32 data1_reg : 8;
54 u32 working_start : 1;
55 u32 twoWS_rw : 1;
56 u32 total_bytes : 2;
57 u32 twoWS_port_reg : 2;
58 u32 no_base_addr_ack_error : 1;
59 u32 st_done : 1;
60 } tw_sm_c_100;
61
62 struct {
63 u32 data2_reg : 8;
64 u32 data3_reg : 8;
65 u32 data4_reg : 8;
66 u32 exlicit_stops : 1;
67 u32 force_stop : 1;
68 u32 unused : 6;
69 } tw_sm_c_104;
70
71 struct {
72 u32 thi1 : 6;
73 u32 reserved1 : 2;
74 u32 tlo1 : 5;
75 u32 reserved2 :19;
76 } tw_sm_c_108;
77
78 struct {
79 u32 thi1 : 6;
80 u32 reserved1 : 2;
81 u32 tlo1 : 5;
82 u32 reserved2 :19;
83 } tw_sm_c_10c;
84
85 struct {
86 u32 thi1 : 6;
87 u32 reserved1 : 2;
88 u32 tlo1 : 5;
89 u32 reserved2 :19;
90 } tw_sm_c_110;
91
92 struct {
93 u32 LNB_CTLHighCount_sig :15;
94 u32 LNB_CTLLowCount_sig :15;
95 u32 LNB_CTLPrescaler_sig : 2;
96 } lnb_switch_freq_200;
97
98 struct {
99 u32 ACPI1_sig : 1;
100 u32 ACPI3_sig : 1;
101 u32 LNB_L_H_sig : 1;
102 u32 Per_reset_sig : 1;
103 u32 reserved :20;
104 u32 Rev_N_sig_revision_hi : 4;
105 u32 Rev_N_sig_reserved1 : 2;
106 u32 Rev_N_sig_caps : 1;
107 u32 Rev_N_sig_reserved2 : 1;
108 } misc_204;
109
110 struct {
111 u32 Stream1_filter_sig : 1;
112 u32 Stream2_filter_sig : 1;
113 u32 PCR_filter_sig : 1;
114 u32 PMT_filter_sig : 1;
115 u32 EMM_filter_sig : 1;
116 u32 ECM_filter_sig : 1;
117 u32 Null_filter_sig : 1;
118 u32 Mask_filter_sig : 1;
119 u32 WAN_Enable_sig : 1;
120 u32 WAN_CA_Enable_sig : 1;
121 u32 CA_Enable_sig : 1;
122 u32 SMC_Enable_sig : 1;
123 u32 Per_CA_Enable_sig : 1;
124 u32 Multi2_Enable_sig : 1;
125 u32 MAC_filter_Mode_sig : 1;
126 u32 Rcv_Data_sig : 1;
127 u32 DMA1_IRQ_Enable_sig : 1;
128 u32 DMA1_Timer_Enable_sig : 1;
129 u32 DMA2_IRQ_Enable_sig : 1;
130 u32 DMA2_Timer_Enable_sig : 1;
131 u32 DMA1_Size_IRQ_Enable_sig : 1;
132 u32 DMA2_Size_IRQ_Enable_sig : 1;
133 u32 Mailbox_from_V8_Enable_sig : 1;
134 u32 unused : 9;
135 } ctrl_208;
136
137 struct {
138 u32 DMA1_IRQ_Status : 1;
139 u32 DMA1_Timer_Status : 1;
140 u32 DMA2_IRQ_Status : 1;
141 u32 DMA2_Timer_Status : 1;
142 u32 DMA1_Size_IRQ_Status : 1;
143 u32 DMA2_Size_IRQ_Status : 1;
144 u32 Mailbox_from_V8_Status_sig : 1;
145 u32 Data_receiver_error : 1;
146 u32 Continuity_error_flag : 1;
147 u32 LLC_SNAP_FLAG_set : 1;
148 u32 Transport_Error : 1;
149 u32 reserved :21;
150 } irq_20c;
151
152 struct {
153 u32 reset_block_000 : 1;
154 u32 reset_block_100 : 1;
155 u32 reset_block_200 : 1;
156 u32 reset_block_300 : 1;
157 u32 reset_block_400 : 1;
158 u32 reset_block_500 : 1;
159 u32 reset_block_600 : 1;
160 u32 reset_block_700 : 1;
161 u32 Block_reset_enable : 8;
162 u32 Special_controls :16;
163 } sw_reset_210;
164
165 struct {
166 u32 vuart_oe_sig : 1;
167 u32 v2WS_oe_sig : 1;
168 u32 halt_V8_sig : 1;
169 u32 section_pkg_enable_sig : 1;
170 u32 s2p_sel_sig : 1;
171 u32 unused1 : 3;
172 u32 polarity_PS_CLK_sig : 1;
173 u32 polarity_PS_VALID_sig : 1;
174 u32 polarity_PS_SYNC_sig : 1;
175 u32 polarity_PS_ERR_sig : 1;
176 u32 unused2 :20;
177 } misc_214;
178
179 struct {
180 u32 Mailbox_from_V8 :32;
181 } mbox_v8_to_host_218;
182
183 struct {
184 u32 sysramaccess_data : 8;
185 u32 sysramaccess_addr :15;
186 u32 unused : 7;
187 u32 sysramaccess_write : 1;
188 u32 sysramaccess_busmuster : 1;
189 } mbox_host_to_v8_21c;
190
191 struct {
192 u32 Stream1_PID :13;
193 u32 Stream1_trans : 1;
194 u32 MAC_Multicast_filter : 1;
195 u32 debug_flag_pid_saved : 1;
196 u32 Stream2_PID :13;
197 u32 Stream2_trans : 1;
198 u32 debug_flag_write_status00 : 1;
199 u32 debug_fifo_problem : 1;
200 } pid_filter_300;
201
202 struct {
203 u32 PCR_PID :13;
204 u32 PCR_trans : 1;
205 u32 debug_overrun3 : 1;
206 u32 debug_overrun2 : 1;
207 u32 PMT_PID :13;
208 u32 PMT_trans : 1;
209 u32 reserved : 2;
210 } pid_filter_304;
211
212 struct {
213 u32 EMM_PID :13;
214 u32 EMM_trans : 1;
215 u32 EMM_filter_4 : 1;
216 u32 EMM_filter_6 : 1;
217 u32 ECM_PID :13;
218 u32 ECM_trans : 1;
219 u32 reserved : 2;
220 } pid_filter_308;
221
222 struct {
223 u32 Group_PID :13;
224 u32 Group_trans : 1;
225 u32 unused1 : 2;
226 u32 Group_mask :13;
227 u32 unused2 : 3;
228 } pid_filter_30c_ext_ind_0_7;
229
230 struct {
231 u32 net_master_read :17;
232 u32 unused :15;
233 } pid_filter_30c_ext_ind_1;
234
235 struct {
236 u32 net_master_write :17;
237 u32 unused :15;
238 } pid_filter_30c_ext_ind_2;
239
240 struct {
241 u32 next_net_master_write :17;
242 u32 unused :15;
243 } pid_filter_30c_ext_ind_3;
244
245 struct {
246 u32 unused1 : 1;
247 u32 state_write :10;
248 u32 reserved1 : 6;
249 u32 stack_read :10;
250 u32 reserved2 : 5;
251 } pid_filter_30c_ext_ind_4;
252
253 struct {
254 u32 stack_cnt :10;
255 u32 unused :22;
256 } pid_filter_30c_ext_ind_5;
257
258 struct {
259 u32 pid_fsm_save_reg0 : 2;
260 u32 pid_fsm_save_reg1 : 2;
261 u32 pid_fsm_save_reg2 : 2;
262 u32 pid_fsm_save_reg3 : 2;
263 u32 pid_fsm_save_reg4 : 2;
264 u32 pid_fsm_save_reg300 : 2;
265 u32 write_status1 : 2;
266 u32 write_status4 : 2;
267 u32 data_size_reg :12;
268 u32 unused : 4;
269 } pid_filter_30c_ext_ind_6;
270
271 struct {
272 u32 index_reg : 5;
273 u32 extra_index_reg : 3;
274 u32 AB_select : 1;
275 u32 pass_alltables : 1;
276 u32 unused :22;
277 } index_reg_310;
278
279 struct {
280 u32 PID :13;
281 u32 PID_trans : 1;
282 u32 PID_enable_bit : 1;
283 u32 reserved :17;
284 } pid_n_reg_314;
285
286 struct {
287 u32 A4_byte : 8;
288 u32 A5_byte : 8;
289 u32 A6_byte : 8;
290 u32 Enable_bit : 1;
291 u32 HighAB_bit : 1;
292 u32 reserved : 6;
293 } mac_low_reg_318;
294
295 struct {
296 u32 A1_byte : 8;
297 u32 A2_byte : 8;
298 u32 A3_byte : 8;
299 u32 reserved : 8;
300 } mac_high_reg_31c;
301
302 struct {
303 u32 reserved :16;
304 u32 data_Tag_ID :16;
305 } data_tag_400;
306
307 struct {
308 u32 Card_IDbyte6 : 8;
309 u32 Card_IDbyte5 : 8;
310 u32 Card_IDbyte4 : 8;
311 u32 Card_IDbyte3 : 8;
312 } card_id_408;
313
314 struct {
315 u32 Card_IDbyte2 : 8;
316 u32 Card_IDbyte1 : 8;
317 } card_id_40c;
318
319 struct {
320 u32 MAC1 : 8;
321 u32 MAC2 : 8;
322 u32 MAC3 : 8;
323 u32 MAC6 : 8;
324 } mac_address_418;
325
326 struct {
327 u32 MAC7 : 8;
328 u32 MAC8 : 8;
329 u32 reserved :16;
330 } mac_address_41c;
331
332 struct {
333 u32 transmitter_data_byte : 8;
334 u32 ReceiveDataReady : 1;
335 u32 ReceiveByteFrameError : 1;
336 u32 txbuffempty : 1;
337 u32 reserved :21;
338 } ci_600;
339
340 struct {
341 u32 pi_d : 8;
342 u32 pi_ha :20;
343 u32 pi_rw : 1;
344 u32 pi_component_reg : 3;
345 } pi_604;
346
347 struct {
348 u32 serialReset : 1;
349 u32 oncecycle_read : 1;
350 u32 Timer_Read_req : 1;
351 u32 Timer_Load_req : 1;
352 u32 timer_data : 7;
353 u32 unused : 1;
354 u32 Timer_addr : 5;
355 u32 reserved : 3;
356 u32 pcmcia_a_mod_pwr_n : 1;
357 u32 pcmcia_b_mod_pwr_n : 1;
358 u32 config_Done_stat : 1;
359 u32 config_Init_stat : 1;
360 u32 config_Prog_n : 1;
361 u32 config_wr_n : 1;
362 u32 config_cs_n : 1;
363 u32 config_cclk : 1;
364 u32 pi_CiMax_IRQ_n : 1;
365 u32 pi_timeout_status : 1;
366 u32 pi_wait_n : 1;
367 u32 pi_busy_n : 1;
368 } pi_608;
369
370 struct {
371 u32 PID :13;
372 u32 key_enable : 1;
373 u32 key_code : 2;
374 u32 key_array_col : 3;
375 u32 key_array_row : 5;
376 u32 dvb_en : 1;
377 u32 rw_flag : 1;
378 u32 reserved : 6;
379 } dvb_reg_60c;
380
381 struct {
382 u32 sram_addr :15;
383 u32 sram_rw : 1;
384 u32 sram_data : 8;
385 u32 sc_xfer_bit : 1;
386 u32 reserved1 : 3;
387 u32 oe_pin_reg : 1;
388 u32 ce_pin_reg : 1;
389 u32 reserved2 : 1;
390 u32 start_sram_ibi : 1;
391 } sram_ctrl_reg_700;
392
393 struct {
394 u32 net_addr_read :16;
395 u32 net_addr_write :16;
396 } net_buf_reg_704;
397
398 struct {
399 u32 cai_read :11;
400 u32 reserved1 : 5;
401 u32 cai_write :11;
402 u32 reserved2 : 6;
403 u32 cai_cnt : 4;
404 } cai_buf_reg_708;
405
406 struct {
407 u32 cao_read :11;
408 u32 reserved1 : 5;
409 u32 cap_write :11;
410 u32 reserved2 : 6;
411 u32 cao_cnt : 4;
412 } cao_buf_reg_70c;
413
414 struct {
415 u32 media_read :11;
416 u32 reserved1 : 5;
417 u32 media_write :11;
418 u32 reserved2 : 6;
419 u32 media_cnt : 4;
420 } media_buf_reg_710;
421
422 struct {
423 u32 NET_Dest : 2;
424 u32 CAI_Dest : 2;
425 u32 CAO_Dest : 2;
426 u32 MEDIA_Dest : 2;
427 u32 net_ovflow_error : 1;
428 u32 media_ovflow_error : 1;
429 u32 cai_ovflow_error : 1;
430 u32 cao_ovflow_error : 1;
431 u32 ctrl_usb_wan : 1;
432 u32 ctrl_sramdma : 1;
433 u32 ctrl_maximumfill : 1;
434 u32 reserved :17;
435 } sram_dest_reg_714;
436
437 struct {
438 u32 net_cnt :12;
439 u32 reserved1 : 4;
440 u32 net_addr_read : 1;
441 u32 reserved2 : 3;
442 u32 net_addr_write : 1;
443 u32 reserved3 :11;
444 } net_buf_reg_718;
445
446 struct {
447 u32 wan_speed_sig : 2;
448 u32 reserved1 : 6;
449 u32 wan_wait_state : 8;
450 u32 sram_chip : 2;
451 u32 sram_memmap : 2;
452 u32 reserved2 : 4;
453 u32 wan_pkt_frame : 4;
454 u32 reserved3 : 4;
455 } wan_ctrl_reg_71c;
456} flexcop_ibi_value;
457
458#endif
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
deleted file mode 100644
index acbc4c34f72a..000000000000
--- a/drivers/media/dvb/b2c2/skystar2.c
+++ /dev/null
@@ -1,2644 +0,0 @@
1/*
2 * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
3 * based on the FlexCopII by B2C2,Inc.
4 *
5 * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
6 *
7 * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
8 * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
9 * Vincenzo Di Massa, hawk.it at tiscalinet.it
10 *
11 * Converted to Linux coding style
12 * Misc reorganization, polishing, restyling
13 * Roberto Ragusa, skystar2-c5b8 at robertoragusa dot it
14 *
15 * Added hardware filtering support,
16 * Niklas Peinecke, peinecke at gdv.uni-hannover.de
17 *
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 */
33
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include <linux/delay.h>
37#include <linux/pci.h>
38#include <linux/init.h>
39#include <linux/version.h>
40
41#include <asm/io.h>
42
43#include "dvb_frontend.h"
44
45#include <linux/dvb/frontend.h>
46#include <linux/dvb/dmx.h>
47#include "dvb_demux.h"
48#include "dmxdev.h"
49#include "dvb_filter.h"
50#include "dvbdev.h"
51#include "demux.h"
52#include "dvb_net.h"
53#include "stv0299.h"
54#include "mt352.h"
55#include "mt312.h"
56#include "nxt2002.h"
57
58static int debug;
59static int enable_hw_filters = 2;
60
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "Set debugging level (0 = default, 1 = most messages, 2 = all messages).");
63module_param(enable_hw_filters, int, 0444);
64MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters: supported values: 0 (none), 1, 2");
65
66#define dprintk(x...) do { if (debug>=1) printk(x); } while (0)
67#define ddprintk(x...) do { if (debug>=2) printk(x); } while (0)
68
69#define SIZE_OF_BUF_DMA1 0x3ac00
70#define SIZE_OF_BUF_DMA2 0x758
71
72#define MAX_N_HW_FILTERS (6+32)
73#define N_PID_SLOTS 256
74
75struct dmaq {
76 u32 bus_addr;
77 u32 head;
78 u32 tail;
79 u32 buffer_size;
80 u8 *buffer;
81};
82
83#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
84#define __iomem
85#endif
86
87struct adapter {
88 struct pci_dev *pdev;
89
90 u8 card_revision;
91 u32 b2c2_revision;
92 u32 pid_filter_max;
93 u32 mac_filter_max;
94 u32 irq;
95 void __iomem *io_mem;
96 unsigned long io_port;
97 u8 mac_addr[8];
98 u32 dw_sram_type;
99
100 struct dvb_adapter dvb_adapter;
101 struct dvb_demux demux;
102 struct dmxdev dmxdev;
103 struct dmx_frontend hw_frontend;
104 struct dmx_frontend mem_frontend;
105 struct i2c_adapter i2c_adap;
106 struct dvb_net dvbnet;
107
108 struct semaphore i2c_sem;
109
110 struct dmaq dmaq1;
111 struct dmaq dmaq2;
112
113 u32 dma_ctrl;
114 u32 dma_status;
115
116 int capturing;
117
118 spinlock_t lock;
119
120 int useable_hw_filters;
121 u16 hw_pids[MAX_N_HW_FILTERS];
122 u16 pid_list[N_PID_SLOTS];
123 int pid_rc[N_PID_SLOTS]; // ref counters for the pids
124 int pid_count;
125 int whole_bandwidth_count;
126 u32 mac_filter;
127
128 struct dvb_frontend* fe;
129 int (*fe_sleep)(struct dvb_frontend* fe);
130};
131
132#define write_reg_dw(adapter,reg,value) writel(value, adapter->io_mem + reg)
133#define read_reg_dw(adapter,reg) readl(adapter->io_mem + reg)
134
135static void write_reg_bitfield(struct adapter *adapter, u32 reg, u32 zeromask, u32 orvalue)
136{
137 u32 tmp;
138
139 tmp = read_reg_dw(adapter, reg);
140 tmp = (tmp & ~zeromask) | orvalue;
141 write_reg_dw(adapter, reg, tmp);
142}
143
144/* i2c functions */
145static int i2c_main_write_for_flex2(struct adapter *adapter, u32 command, u8 *buf, int retries)
146{
147 int i;
148 u32 value;
149
150 write_reg_dw(adapter, 0x100, 0);
151 write_reg_dw(adapter, 0x100, command);
152
153 for (i = 0; i < retries; i++) {
154 value = read_reg_dw(adapter, 0x100);
155
156 if ((value & 0x40000000) == 0) {
157 if ((value & 0x81000000) == 0x80000000) {
158 if (buf != 0)
159 *buf = (value >> 0x10) & 0xff;
160
161 return 1;
162 }
163 } else {
164 write_reg_dw(adapter, 0x100, 0);
165 write_reg_dw(adapter, 0x100, command);
166 }
167 }
168
169 return 0;
170}
171
172/* device = 0x10000000 for tuner, 0x20000000 for eeprom */
173static void i2c_main_setup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
174{
175 *command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
176
177 if (op != 0)
178 *command = *command | 0x03000000;
179 else
180 *command = *command | 0x01000000;
181}
182
183static int flex_i2c_read4(struct adapter *adapter, u32 device, u32 chip_addr, u16 addr, u8 *buf, u8 len)
184{
185 u32 command;
186 u32 value;
187
188 int result, i;
189
190 i2c_main_setup(device, chip_addr, 1, addr, 0, len, &command);
191
192 result = i2c_main_write_for_flex2(adapter, command, buf, 100000);
193
194 if ((result & 0xff) != 0) {
195 if (len > 1) {
196 value = read_reg_dw(adapter, 0x104);
197
198 for (i = 1; i < len; i++) {
199 buf[i] = value & 0xff;
200 value = value >> 8;
201 }
202 }
203 }
204
205 return result;
206}
207
208static int flex_i2c_write4(struct adapter *adapter, u32 device, u32 chip_addr, u32 addr, u8 *buf, u8 len)
209{
210 u32 command;
211 u32 value;
212 int i;
213
214 if (len > 1) {
215 value = 0;
216
217 for (i = len; i > 1; i--) {
218 value = value << 8;
219 value = value | buf[i - 1];
220 }
221
222 write_reg_dw(adapter, 0x104, value);
223 }
224
225 i2c_main_setup(device, chip_addr, 0, addr, buf[0], len, &command);
226
227 return i2c_main_write_for_flex2(adapter, command, NULL, 100000);
228}
229
230static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
231{
232 if (device == 0x20000000)
233 *ret = bus | ((addr >> 8) & 3);
234 else
235 *ret = bus;
236}
237
238static u32 flex_i2c_read(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
239{
240 u32 chipaddr;
241 u32 bytes_to_transfer;
242 u8 *start;
243
244 ddprintk("%s:\n", __FUNCTION__);
245
246 start = buf;
247
248 while (len != 0) {
249 bytes_to_transfer = len;
250
251 if (bytes_to_transfer > 4)
252 bytes_to_transfer = 4;
253
254 fixchipaddr(device, bus, addr, &chipaddr);
255
256 if (flex_i2c_read4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
257 return buf - start;
258
259 buf = buf + bytes_to_transfer;
260 addr = addr + bytes_to_transfer;
261 len = len - bytes_to_transfer;
262 };
263
264 return buf - start;
265}
266
267static u32 flex_i2c_write(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
268{
269 u32 chipaddr;
270 u32 bytes_to_transfer;
271 u8 *start;
272
273 ddprintk("%s:\n", __FUNCTION__);
274
275 start = buf;
276
277 while (len != 0) {
278 bytes_to_transfer = len;
279
280 if (bytes_to_transfer > 4)
281 bytes_to_transfer = 4;
282
283 fixchipaddr(device, bus, addr, &chipaddr);
284
285 if (flex_i2c_write4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
286 return buf - start;
287
288 buf = buf + bytes_to_transfer;
289 addr = addr + bytes_to_transfer;
290 len = len - bytes_to_transfer;
291 }
292
293 return buf - start;
294}
295
296static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msgs, int num)
297{
298 struct adapter *tmp = i2c_get_adapdata(adapter);
299 int i, ret = 0;
300
301 if (down_interruptible(&tmp->i2c_sem))
302 return -ERESTARTSYS;
303
304 ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
305
306 for (i = 0; i < num; i++) {
307 ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
308 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
309 }
310
311 // read command
312 if ((num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && (msgs[0].buf != NULL) && (msgs[1].buf != NULL)) {
313
314 ret = flex_i2c_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
315
316 up(&tmp->i2c_sem);
317
318 if (ret != msgs[1].len) {
319 dprintk("%s: read error !\n", __FUNCTION__);
320
321 for (i = 0; i < 2; i++) {
322 dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
323 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
324 }
325
326 return -EREMOTEIO;
327 }
328
329 return num;
330 }
331 // write command
332 for (i = 0; i < num; i++) {
333
334 if ((msgs[i].flags != 0) || (msgs[i].buf == NULL) || (msgs[i].len < 2))
335 return -EINVAL;
336
337 ret = flex_i2c_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
338
339 up(&tmp->i2c_sem);
340
341 if (ret != msgs[0].len - 1) {
342 dprintk("%s: write error %i !\n", __FUNCTION__, ret);
343
344 dprintk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
345 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
346
347 return -EREMOTEIO;
348 }
349
350 return num;
351 }
352
353 printk("%s: unknown command format !\n", __FUNCTION__);
354
355 return -EINVAL;
356}
357
358/* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
359 but it seems that FlexCopII can work with more than one chip) */
360static void sram_set_net_dest(struct adapter *adapter, u8 dest)
361{
362 u32 tmp;
363
364 udelay(1000);
365
366 tmp = (read_reg_dw(adapter, 0x714) & 0xfffffffc) | (dest & 3);
367
368 udelay(1000);
369
370 write_reg_dw(adapter, 0x714, tmp);
371 write_reg_dw(adapter, 0x714, tmp);
372
373 udelay(1000);
374
375 /* return value is never used? */
376/* return tmp; */
377}
378
379static void sram_set_cai_dest(struct adapter *adapter, u8 dest)
380{
381 u32 tmp;
382
383 udelay(1000);
384
385 tmp = (read_reg_dw(adapter, 0x714) & 0xfffffff3) | ((dest & 3) << 2);
386
387 udelay(1000);
388 udelay(1000);
389
390 write_reg_dw(adapter, 0x714, tmp);
391 write_reg_dw(adapter, 0x714, tmp);
392
393 udelay(1000);
394
395 /* return value is never used? */
396/* return tmp; */
397}
398
399static void sram_set_cao_dest(struct adapter *adapter, u8 dest)
400{
401 u32 tmp;
402
403 udelay(1000);
404
405 tmp = (read_reg_dw(adapter, 0x714) & 0xffffffcf) | ((dest & 3) << 4);
406
407 udelay(1000);
408 udelay(1000);
409
410 write_reg_dw(adapter, 0x714, tmp);
411 write_reg_dw(adapter, 0x714, tmp);
412
413 udelay(1000);
414
415 /* return value is never used? */
416/* return tmp; */
417}
418
419static void sram_set_media_dest(struct adapter *adapter, u8 dest)
420{
421 u32 tmp;
422
423 udelay(1000);
424
425 tmp = (read_reg_dw(adapter, 0x714) & 0xffffff3f) | ((dest & 3) << 6);
426
427 udelay(1000);
428 udelay(1000);
429
430 write_reg_dw(adapter, 0x714, tmp);
431 write_reg_dw(adapter, 0x714, tmp);
432
433 udelay(1000);
434
435 /* return value is never used? */
436/* return tmp; */
437}
438
439/* SRAM memory is accessed through a buffer register in the FlexCop
440 chip (0x700). This register has the following structure:
441 bits 0-14 : address
442 bit 15 : read/write flag
443 bits 16-23 : 8-bit word to write
444 bits 24-27 : = 4
445 bits 28-29 : memory bank selector
446 bit 31 : busy flag
447*/
448static void flex_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
449{
450 int i, retries;
451 u32 command;
452
453 for (i = 0; i < len; i++) {
454 command = bank | addr | 0x04000000 | (*buf << 0x10);
455
456 retries = 2;
457
458 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
459 mdelay(1);
460 retries--;
461 };
462
463 if (retries == 0)
464 printk("%s: SRAM timeout\n", __FUNCTION__);
465
466 write_reg_dw(adapter, 0x700, command);
467
468 buf++;
469 addr++;
470 }
471}
472
473static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
474{
475 int i, retries;
476 u32 command, value;
477
478 for (i = 0; i < len; i++) {
479 command = bank | addr | 0x04008000;
480
481 retries = 10000;
482
483 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
484 mdelay(1);
485 retries--;
486 };
487
488 if (retries == 0)
489 printk("%s: SRAM timeout\n", __FUNCTION__);
490
491 write_reg_dw(adapter, 0x700, command);
492
493 retries = 10000;
494
495 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
496 mdelay(1);
497 retries--;
498 };
499
500 if (retries == 0)
501 printk("%s: SRAM timeout\n", __FUNCTION__);
502
503 value = read_reg_dw(adapter, 0x700) >> 0x10;
504
505 *buf = (value & 0xff);
506
507 addr++;
508 buf++;
509 }
510}
511
512static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
513{
514 u32 bank;
515
516 bank = 0;
517
518 if (adapter->dw_sram_type == 0x20000) {
519 bank = (addr & 0x18000) << 0x0d;
520 }
521
522 if (adapter->dw_sram_type == 0x00000) {
523 if ((addr >> 0x0f) == 0)
524 bank = 0x20000000;
525 else
526 bank = 0x10000000;
527 }
528
529 flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
530}
531
532static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
533{
534 u32 bank;
535
536 bank = 0;
537
538 if (adapter->dw_sram_type == 0x20000) {
539 bank = (addr & 0x18000) << 0x0d;
540 }
541
542 if (adapter->dw_sram_type == 0x00000) {
543 if ((addr >> 0x0f) == 0)
544 bank = 0x20000000;
545 else
546 bank = 0x10000000;
547 }
548
549 flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
550}
551
552static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
553{
554 u32 length;
555
556 while (len != 0) {
557 length = len;
558
559 // check if the address range belongs to the same
560 // 32K memory chip. If not, the data is read from
561 // one chip at a time.
562 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
563 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
564 }
565
566 sram_read_chunk(adapter, addr, buf, length);
567
568 addr = addr + length;
569 buf = buf + length;
570 len = len - length;
571 }
572}
573
574static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
575{
576 u32 length;
577
578 while (len != 0) {
579 length = len;
580
581 // check if the address range belongs to the same
582 // 32K memory chip. If not, the data is written to
583 // one chip at a time.
584 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
585 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
586 }
587
588 sram_write_chunk(adapter, addr, buf, length);
589
590 addr = addr + length;
591 buf = buf + length;
592 len = len - length;
593 }
594}
595
596static void sram_set_size(struct adapter *adapter, u32 mask)
597{
598 write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
599}
600
601static void sram_init(struct adapter *adapter)
602{
603 u32 tmp;
604
605 tmp = read_reg_dw(adapter, 0x71c);
606
607 write_reg_dw(adapter, 0x71c, 1);
608
609 if (read_reg_dw(adapter, 0x71c) != 0) {
610 write_reg_dw(adapter, 0x71c, tmp);
611
612 adapter->dw_sram_type = tmp & 0x30000;
613
614 ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
615
616 } else {
617
618 adapter->dw_sram_type = 0x10000;
619
620 ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
621 }
622
623 /* return value is never used? */
624/* return adapter->dw_sram_type; */
625}
626
627static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
628{
629 u8 tmp1, tmp2;
630
631 dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
632
633 sram_set_size(adapter, mask);
634 sram_init(adapter);
635
636 tmp2 = 0xa5;
637 tmp1 = 0x4f;
638
639 sram_write(adapter, addr, &tmp2, 1);
640 sram_write(adapter, addr + 4, &tmp1, 1);
641
642 tmp2 = 0;
643
644 mdelay(20);
645
646 sram_read(adapter, addr, &tmp2, 1);
647 sram_read(adapter, addr, &tmp2, 1);
648
649 dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
650
651 if (tmp2 != 0xa5)
652 return 0;
653
654 tmp2 = 0x5a;
655 tmp1 = 0xf4;
656
657 sram_write(adapter, addr, &tmp2, 1);
658 sram_write(adapter, addr + 4, &tmp1, 1);
659
660 tmp2 = 0;
661
662 mdelay(20);
663
664 sram_read(adapter, addr, &tmp2, 1);
665 sram_read(adapter, addr, &tmp2, 1);
666
667 dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
668
669 if (tmp2 != 0x5a)
670 return 0;
671
672 return 1;
673}
674
675static u32 sram_length(struct adapter *adapter)
676{
677 if (adapter->dw_sram_type == 0x10000)
678 return 32768; // 32K
679 if (adapter->dw_sram_type == 0x00000)
680 return 65536; // 64K
681 if (adapter->dw_sram_type == 0x20000)
682 return 131072; // 128K
683
684 return 32768; // 32K
685}
686
687/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
688 - for 128K there are 4x32K chips at bank 0,1,2,3.
689 - for 64K there are 2x32K chips at bank 1,2.
690 - for 32K there is one 32K chip at bank 0.
691
692 FlexCop works only with one bank at a time. The bank is selected
693 by bits 28-29 of the 0x700 register.
694
695 bank 0 covers addresses 0x00000-0x07fff
696 bank 1 covers addresses 0x08000-0x0ffff
697 bank 2 covers addresses 0x10000-0x17fff
698 bank 3 covers addresses 0x18000-0x1ffff
699*/
700static int sram_detect_for_flex2(struct adapter *adapter)
701{
702 u32 tmp, tmp2, tmp3;
703
704 dprintk("%s:\n", __FUNCTION__);
705
706 tmp = read_reg_dw(adapter, 0x208);
707 write_reg_dw(adapter, 0x208, 0);
708
709 tmp2 = read_reg_dw(adapter, 0x71c);
710
711 dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
712
713 write_reg_dw(adapter, 0x71c, 1);
714
715 tmp3 = read_reg_dw(adapter, 0x71c);
716
717 dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
718
719 write_reg_dw(adapter, 0x71c, tmp2);
720
721 // check for internal SRAM ???
722 tmp3--;
723 if (tmp3 != 0) {
724 sram_set_size(adapter, 0x10000);
725 sram_init(adapter);
726 write_reg_dw(adapter, 0x208, tmp);
727
728 dprintk("%s: sram size = 32K\n", __FUNCTION__);
729
730 return 32;
731 }
732
733 if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
734 sram_set_size(adapter, 0x20000);
735 sram_init(adapter);
736 write_reg_dw(adapter, 0x208, tmp);
737
738 dprintk("%s: sram size = 128K\n", __FUNCTION__);
739
740 return 128;
741 }
742
743 if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
744 sram_set_size(adapter, 0x00000);
745 sram_init(adapter);
746 write_reg_dw(adapter, 0x208, tmp);
747
748 dprintk("%s: sram size = 64K\n", __FUNCTION__);
749
750 return 64;
751 }
752
753 if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
754 sram_set_size(adapter, 0x10000);
755 sram_init(adapter);
756 write_reg_dw(adapter, 0x208, tmp);
757
758 dprintk("%s: sram size = 32K\n", __FUNCTION__);
759
760 return 32;
761 }
762
763 sram_set_size(adapter, 0x10000);
764 sram_init(adapter);
765 write_reg_dw(adapter, 0x208, tmp);
766
767 dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
768
769 return 0;
770}
771
772static void sll_detect_sram_size(struct adapter *adapter)
773{
774 sram_detect_for_flex2(adapter);
775}
776
777/* EEPROM (Skystar2 has one "24LC08B" chip on board) */
778/*
779static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
780{
781 return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
782}
783*/
784
785static int eeprom_read(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
786{
787 return flex_i2c_read(adapter, 0x20000000, 0x50, addr, buf, len);
788}
789
790static u8 calc_lrc(u8 *buf, int len)
791{
792 int i;
793 u8 sum;
794
795 sum = 0;
796
797 for (i = 0; i < len; i++)
798 sum = sum ^ buf[i];
799
800 return sum;
801}
802
803static int eeprom_lrc_read(struct adapter *adapter, u32 addr, u32 len, u8 *buf, int retries)
804{
805 int i;
806
807 for (i = 0; i < retries; i++) {
808 if (eeprom_read(adapter, addr, buf, len) == len) {
809 if (calc_lrc(buf, len - 1) == buf[len - 1])
810 return 1;
811 }
812 }
813
814 return 0;
815}
816
817/*
818static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
819{
820 int i;
821
822 for (i = 0; i < retries; i++) {
823 if (eeprom_write(adapter, addr, wbuf, len) == len) {
824 if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
825 return 1;
826 }
827 }
828
829 return 0;
830}
831*/
832
833
834/* These functions could be used to unlock SkyStar2 cards. */
835
836/*
837static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
838{
839 u8 rbuf[20];
840 u8 wbuf[20];
841
842 if (len != 16)
843 return 0;
844
845 memcpy(wbuf, key, len);
846
847 wbuf[16] = 0;
848 wbuf[17] = 0;
849 wbuf[18] = 0;
850 wbuf[19] = calc_lrc(wbuf, 19);
851
852 return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
853}
854
855static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
856{
857 u8 buf[20];
858
859 if (len != 16)
860 return 0;
861
862 if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
863 return 0;
864
865 memcpy(key, buf, len);
866
867 return 1;
868}
869*/
870
871static int eeprom_get_mac_addr(struct adapter *adapter, char type, u8 *mac)
872{
873 u8 tmp[8];
874
875 if (eeprom_lrc_read(adapter, 0x3f8, 8, tmp, 4) != 0) {
876 if (type != 0) {
877 mac[0] = tmp[0];
878 mac[1] = tmp[1];
879 mac[2] = tmp[2];
880 mac[3] = 0xfe;
881 mac[4] = 0xff;
882 mac[5] = tmp[3];
883 mac[6] = tmp[4];
884 mac[7] = tmp[5];
885
886 } else {
887
888 mac[0] = tmp[0];
889 mac[1] = tmp[1];
890 mac[2] = tmp[2];
891 mac[3] = tmp[3];
892 mac[4] = tmp[4];
893 mac[5] = tmp[5];
894 }
895
896 return 1;
897
898 } else {
899
900 if (type == 0) {
901 memset(mac, 0, 6);
902
903 } else {
904
905 memset(mac, 0, 8);
906 }
907
908 return 0;
909 }
910}
911
912/*
913static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
914{
915 u8 tmp[8];
916
917 if (type != 0) {
918 tmp[0] = mac[0];
919 tmp[1] = mac[1];
920 tmp[2] = mac[2];
921 tmp[3] = mac[5];
922 tmp[4] = mac[6];
923 tmp[5] = mac[7];
924
925 } else {
926
927 tmp[0] = mac[0];
928 tmp[1] = mac[1];
929 tmp[2] = mac[2];
930 tmp[3] = mac[3];
931 tmp[4] = mac[4];
932 tmp[5] = mac[5];
933 }
934
935 tmp[6] = 0;
936 tmp[7] = calc_lrc(tmp, 7);
937
938 if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
939 return 1;
940
941 return 0;
942}
943*/
944
945/* PID filter */
946
947/* every flexcop has 6 "lower" hw PID filters */
948/* these are enabled by setting bits 0-5 of 0x208 */
949/* for the 32 additional filters we have to select one */
950/* of them through 0x310 and modify through 0x314 */
951/* op: 0=disable, 1=enable */
952static void filter_enable_hw_filter(struct adapter *adapter, int id, u8 op)
953{
954 dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
955 if (id <= 5) {
956 u32 mask = (0x00000001 << id);
957 write_reg_bitfield(adapter, 0x208, mask, op ? mask : 0);
958 } else {
959 /* select */
960 write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
961 /* modify */
962 write_reg_bitfield(adapter, 0x314, 0x00006000, op ? 0x00004000 : 0);
963 }
964}
965
966/* this sets the PID that should pass the specified filter */
967static void pid_set_hw_pid(struct adapter *adapter, int id, u16 pid)
968{
969 dprintk("%s: id=%d pid=%d\n", __FUNCTION__, id, pid);
970 if (id <= 5) {
971 u32 adr = 0x300 + ((id & 6) << 1);
972 int shift = (id & 1) ? 16 : 0;
973 dprintk("%s: id=%d addr=%x %c pid=%d\n", __FUNCTION__, id, adr, (id & 1) ? 'h' : 'l', pid);
974 write_reg_bitfield(adapter, adr, (0x7fff) << shift, (pid & 0x1fff) << shift);
975 } else {
976 /* select */
977 write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
978 /* modify */
979 write_reg_bitfield(adapter, 0x314, 0x1fff, pid & 0x1fff);
980 }
981}
982
983
984/*
985static void filter_enable_null_filter(struct adapter *adapter, u32 op)
986{
987 dprintk("%s: op=%x\n", __FUNCTION__, op);
988
989 write_reg_bitfield(adapter, 0x208, 0x00000040, op?0x00000040:0);
990}
991*/
992
993static void filter_enable_mask_filter(struct adapter *adapter, u32 op)
994{
995 dprintk("%s: op=%x\n", __FUNCTION__, op);
996
997 write_reg_bitfield(adapter, 0x208, 0x00000080, op ? 0x00000080 : 0);
998}
999
1000
1001static void ctrl_enable_mac(struct adapter *adapter, u32 op)
1002{
1003 write_reg_bitfield(adapter, 0x208, 0x00004000, op ? 0x00004000 : 0);
1004}
1005
1006static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 *mac)
1007{
1008 u32 tmp1, tmp2;
1009
1010 tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
1011 tmp2 = (mac[5] << 0x08) | mac[4];
1012
1013 write_reg_dw(adapter, 0x418, tmp1);
1014 write_reg_dw(adapter, 0x41c, tmp2);
1015
1016 return 0;
1017}
1018
1019/*
1020static void set_ignore_mac_filter(struct adapter *adapter, u8 op)
1021{
1022 if (op != 0) {
1023 write_reg_bitfield(adapter, 0x208, 0x00004000, 0);
1024 adapter->mac_filter = 1;
1025 } else {
1026 if (adapter->mac_filter != 0) {
1027 adapter->mac_filter = 0;
1028 write_reg_bitfield(adapter, 0x208, 0x00004000, 0x00004000);
1029 }
1030 }
1031}
1032*/
1033
1034/*
1035static void check_null_filter_enable(struct adapter *adapter)
1036{
1037 filter_enable_null_filter(adapter, 1);
1038 filter_enable_mask_filter(adapter, 1);
1039}
1040*/
1041
1042static void pid_set_group_pid(struct adapter *adapter, u16 pid)
1043{
1044 u32 value;
1045
1046 dprintk("%s: pid=%x\n", __FUNCTION__, pid);
1047 value = (pid & 0x3fff) | (read_reg_dw(adapter, 0x30c) & 0xffff0000);
1048 write_reg_dw(adapter, 0x30c, value);
1049}
1050
1051static void pid_set_group_mask(struct adapter *adapter, u16 pid)
1052{
1053 u32 value;
1054
1055 dprintk("%s: pid=%x\n", __FUNCTION__, pid);
1056 value = ((pid & 0x3fff) << 0x10) | (read_reg_dw(adapter, 0x30c) & 0xffff);
1057 write_reg_dw(adapter, 0x30c, value);
1058}
1059
1060/*
1061static int pid_get_group_pid(struct adapter *adapter)
1062{
1063 return read_reg_dw(adapter, 0x30c) & 0x00001fff;
1064}
1065
1066static int pid_get_group_mask(struct adapter *adapter)
1067{
1068 return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;
1069}
1070*/
1071
1072/*
1073static void reset_hardware_pid_filter(struct adapter *adapter)
1074{
1075 pid_set_stream1_pid(adapter, 0x1fff);
1076
1077 pid_set_stream2_pid(adapter, 0x1fff);
1078 filter_enable_stream2_filter(adapter, 0);
1079
1080 pid_set_pcr_pid(adapter, 0x1fff);
1081 filter_enable_pcr_filter(adapter, 0);
1082
1083 pid_set_pmt_pid(adapter, 0x1fff);
1084 filter_enable_pmt_filter(adapter, 0);
1085
1086 pid_set_ecm_pid(adapter, 0x1fff);
1087 filter_enable_ecm_filter(adapter, 0);
1088
1089 pid_set_emm_pid(adapter, 0x1fff);
1090 filter_enable_emm_filter(adapter, 0);
1091}
1092*/
1093
1094static void init_pids(struct adapter *adapter)
1095{
1096 int i;
1097
1098 adapter->pid_count = 0;
1099 adapter->whole_bandwidth_count = 0;
1100 for (i = 0; i < adapter->useable_hw_filters; i++) {
1101 dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i);
1102 adapter->hw_pids[i] = 0x1fff;
1103 pid_set_hw_pid(adapter, i, 0x1fff);
1104}
1105
1106 pid_set_group_pid(adapter, 0);
1107 pid_set_group_mask(adapter, 0x1fe0);
1108}
1109
1110static void open_whole_bandwidth(struct adapter *adapter)
1111{
1112 dprintk("%s:\n", __FUNCTION__);
1113 pid_set_group_pid(adapter, 0);
1114 pid_set_group_mask(adapter, 0);
1115/*
1116 filter_enable_mask_filter(adapter, 1);
1117*/
1118}
1119
1120static void close_whole_bandwidth(struct adapter *adapter)
1121{
1122 dprintk("%s:\n", __FUNCTION__);
1123 pid_set_group_pid(adapter, 0);
1124 pid_set_group_mask(adapter, 0x1fe0);
1125/*
1126 filter_enable_mask_filter(adapter, 1);
1127*/
1128}
1129
1130static void whole_bandwidth_inc(struct adapter *adapter)
1131{
1132 if (adapter->whole_bandwidth_count++ == 0)
1133 open_whole_bandwidth(adapter);
1134}
1135
1136static void whole_bandwidth_dec(struct adapter *adapter)
1137{
1138 if (--adapter->whole_bandwidth_count <= 0)
1139 close_whole_bandwidth(adapter);
1140}
1141
1142/* The specified PID has to be let through the
1143 hw filters.
1144 We try to allocate an hardware filter and open whole
1145 bandwidth when allocation is impossible.
1146 All pids<=0x1f pass through the group filter.
1147 Returns 1 on success, -1 on error */
1148static int add_hw_pid(struct adapter *adapter, u16 pid)
1149{
1150 int i;
1151
1152 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1153
1154 if (pid <= 0x1f)
1155 return 1;
1156
1157 /* we can't use a filter for 0x2000, so no search */
1158 if (pid != 0x2000) {
1159 /* find an unused hardware filter */
1160 for (i = 0; i < adapter->useable_hw_filters; i++) {
1161 dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
1162 if (adapter->hw_pids[i] == 0x1fff) {
1163 dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
1164 adapter->hw_pids[i] = pid;
1165 pid_set_hw_pid(adapter, i, pid);
1166 filter_enable_hw_filter(adapter, i, 1);
1167 return 1;
1168 }
1169 }
1170 }
1171 /* if we have not used a filter, this pid depends on whole bandwidth */
1172 dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
1173 whole_bandwidth_inc(adapter);
1174 return 1;
1175 }
1176
1177/* returns -1 if the pid was not present in the filters */
1178static int remove_hw_pid(struct adapter *adapter, u16 pid)
1179{
1180 int i;
1181
1182 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1183
1184 if (pid <= 0x1f)
1185 return 1;
1186
1187 /* we can't use a filter for 0x2000, so no search */
1188 if (pid != 0x2000) {
1189 for (i = 0; i < adapter->useable_hw_filters; i++) {
1190 dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
1191 if (adapter->hw_pids[i] == pid) { // find the pid slot
1192 dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
1193 adapter->hw_pids[i] = 0x1fff;
1194 pid_set_hw_pid(adapter, i, 0x1fff);
1195 filter_enable_hw_filter(adapter, i, 0);
1196 return 1;
1197 }
1198 }
1199 }
1200 /* if we have not used a filter, this pid depended on whole bandwith */
1201 dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
1202 whole_bandwidth_dec(adapter);
1203 return 1;
1204 }
1205
1206/* Adds a PID to the filters.
1207 Adding a pid more than once is possible, we keep reference counts.
1208 Whole stream available through pid==0x2000.
1209 Returns 1 on success, -1 on error */
1210static int add_pid(struct adapter *adapter, u16 pid)
1211{
1212 int i;
1213
1214 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1215
1216 if (pid > 0x1ffe && pid != 0x2000)
1217 return -1;
1218
1219 // check if the pid is already present
1220 for (i = 0; i < adapter->pid_count; i++)
1221 if (adapter->pid_list[i] == pid) {
1222 adapter->pid_rc[i]++; // increment ref counter
1223 return 1;
1224 }
1225
1226 if (adapter->pid_count == N_PID_SLOTS)
1227 return -1; // no more pids can be added
1228 adapter->pid_list[adapter->pid_count] = pid; // register pid
1229 adapter->pid_rc[adapter->pid_count] = 1;
1230 adapter->pid_count++;
1231 // hardware setting
1232 add_hw_pid(adapter, pid);
1233
1234 return 1;
1235 }
1236
1237/* Removes a PID from the filters. */
1238static int remove_pid(struct adapter *adapter, u16 pid)
1239{
1240 int i;
1241
1242 dprintk("%s: pid=%d\n", __FUNCTION__, pid);
1243
1244 if (pid > 0x1ffe && pid != 0x2000)
1245 return -1;
1246
1247 // check if the pid is present (it must be!)
1248 for (i = 0; i < adapter->pid_count; i++) {
1249 if (adapter->pid_list[i] == pid) {
1250 adapter->pid_rc[i]--;
1251 if (adapter->pid_rc[i] <= 0) {
1252 // remove from the list
1253 adapter->pid_count--;
1254 adapter->pid_list[i]=adapter->pid_list[adapter->pid_count];
1255 adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count];
1256 // hardware setting
1257 remove_hw_pid(adapter, pid);
1258 }
1259 return 1;
1260 }
1261 }
1262
1263 return -1;
1264}
1265
1266
1267/* dma & irq */
1268static void ctrl_enable_smc(struct adapter *adapter, u32 op)
1269{
1270 write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);
1271}
1272
1273static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
1274{
1275 adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000;
1276
1277 if (flag1 == 0) {
1278 if (flag2 == 0)
1279 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000;
1280 else
1281 adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000;
1282
1283 if (flag3 == 0)
1284 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000;
1285 else
1286 adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000;
1287
1288 } else {
1289
1290 if (flag2 == 0)
1291 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000;
1292 else
1293 adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000;
1294
1295 if (flag3 == 0)
1296 adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000;
1297 else
1298 adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000;
1299 }
1300}
1301
1302static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op)
1303{
1304 u32 value;
1305
1306 value = read_reg_dw(adapter, 0x208) & 0xfff0ffff;
1307
1308 if (op != 0)
1309 value = value | (adapter->dma_ctrl & 0x000f0000);
1310
1311 write_reg_dw(adapter, 0x208, value);
1312}
1313
1314/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
1315 system memory.
1316
1317 The DMA1 buffer is divided in 2 subbuffers of equal size.
1318 FlexCopII will transfer TS data to one subbuffer, signal an interrupt
1319 when the subbuffer is full and continue fillig the second subbuffer.
1320
1321 For DMA1:
1322 subbuffer size in 32-bit words is stored in the first 24 bits of
1323 register 0x004. The last 8 bits of register 0x004 contain the number
1324 of subbuffers.
1325
1326 the first 30 bits of register 0x000 contain the address of the first
1327 subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
1328 when dma1 is enabled.
1329
1330 the first 30 bits of register 0x00c contain the address of the second
1331 subbuffer. the last 2 bits contain 1.
1332
1333 register 0x008 will contain the address of the subbuffer that was filled
1334 with TS data, when FlexCopII will generate an interrupt.
1335
1336 For DMA2:
1337 subbuffer size in 32-bit words is stored in the first 24 bits of
1338 register 0x014. The last 8 bits of register 0x014 contain the number
1339 of subbuffers.
1340
1341 the first 30 bits of register 0x010 contain the address of the first
1342 subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
1343 when dma1 is enabled.
1344
1345 the first 30 bits of register 0x01c contain the address of the second
1346 subbuffer. the last 2 bits contain 1.
1347
1348 register 0x018 contains the address of the subbuffer that was filled
1349 with TS data, when FlexCopII generates an interrupt.
1350*/
1351static int dma_init_dma(struct adapter *adapter, u32 dma_channel)
1352{
1353 u32 subbuffers, subbufsize, subbuf0, subbuf1;
1354
1355 if (dma_channel == 0) {
1356 dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__);
1357
1358 subbuffers = 2;
1359
1360 subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
1361
1362 subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc;
1363
1364 subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1;
1365
1366 dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
1367 udelay(1000);
1368 write_reg_dw(adapter, 0x000, subbuf0);
1369
1370 dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
1371 udelay(1000);
1372 write_reg_dw(adapter, 0x004, subbufsize);
1373
1374 dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
1375 udelay(1000);
1376 write_reg_dw(adapter, 0x00c, subbuf1);
1377
1378 dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc);
1379 write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
1380 udelay(1000);
1381
1382 dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0);
1383
1384 irq_dma_enable_disable_irq(adapter, 1);
1385
1386 sram_set_media_dest(adapter, 1);
1387 sram_set_net_dest(adapter, 1);
1388 sram_set_cai_dest(adapter, 2);
1389 sram_set_cao_dest(adapter, 2);
1390 }
1391
1392 if (dma_channel == 1) {
1393 dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__);
1394
1395 subbuffers = 2;
1396
1397 subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
1398
1399 subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc;
1400
1401 subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1;
1402
1403 dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
1404 udelay(1000);
1405 write_reg_dw(adapter, 0x010, subbuf0);
1406
1407 dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
1408 udelay(1000);
1409 write_reg_dw(adapter, 0x014, subbufsize);
1410
1411 dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
1412 udelay(1000);
1413 write_reg_dw(adapter, 0x01c, subbuf1);
1414
1415 sram_set_cai_dest(adapter, 2);
1416 }
1417
1418 return 0;
1419}
1420
1421static void ctrl_enable_receive_data(struct adapter *adapter, u32 op)
1422{
1423 if (op == 0) {
1424 write_reg_bitfield(adapter, 0x208, 0x00008000, 0);
1425 adapter->dma_status = adapter->dma_status & ~0x00000004;
1426 } else {
1427 write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000);
1428 adapter->dma_status = adapter->dma_status | 0x00000004;
1429 }
1430}
1431
1432/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
1433 bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
1434*/
1435static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop)
1436{
1437 u32 dma_enable, dma1_enable, dma2_enable;
1438
1439 dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask);
1440
1441 if (start_stop == 1) {
1442 dprintk("%s: starting dma\n", __FUNCTION__);
1443
1444 dma1_enable = 0;
1445 dma2_enable = 0;
1446
1447 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) {
1448 adapter->dma_status = adapter->dma_status | 1;
1449 dma1_enable = 1;
1450 }
1451
1452 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) {
1453 adapter->dma_status = adapter->dma_status | 2;
1454 dma2_enable = 1;
1455 }
1456 // enable dma1 and dma2
1457 if ((dma1_enable == 1) && (dma2_enable == 1)) {
1458 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
1459 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1460 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
1461
1462 ctrl_enable_receive_data(adapter, 1);
1463
1464 return;
1465 }
1466 // enable dma1
1467 if ((dma1_enable == 1) && (dma2_enable == 0)) {
1468 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
1469 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1470
1471 ctrl_enable_receive_data(adapter, 1);
1472
1473 return;
1474 }
1475 // enable dma2
1476 if ((dma1_enable == 0) && (dma2_enable == 1)) {
1477 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
1478
1479 ctrl_enable_receive_data(adapter, 1);
1480
1481 return;
1482 }
1483 // start dma
1484 if ((dma1_enable == 0) && (dma2_enable == 0)) {
1485 ctrl_enable_receive_data(adapter, 1);
1486
1487 return;
1488 }
1489
1490 } else {
1491
1492 dprintk("%s: stopping dma\n", __FUNCTION__);
1493
1494 dma_enable = adapter->dma_status & 0x00000003;
1495
1496 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
1497 dma_enable = dma_enable & 0xfffffffe;
1498 }
1499
1500 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
1501 dma_enable = dma_enable & 0xfffffffd;
1502 }
1503 //stop dma
1504 if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
1505 ctrl_enable_receive_data(adapter, 0);
1506
1507 udelay(3000);
1508 }
1509 //disable dma1
1510 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
1511 write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr);
1512 write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
1513
1514 adapter->dma_status = adapter->dma_status & ~0x00000001;
1515 }
1516 //disable dma2
1517 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
1518 write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr);
1519
1520 adapter->dma_status = adapter->dma_status & ~0x00000002;
1521 }
1522 }
1523}
1524
1525static void open_stream(struct adapter *adapter, u16 pid)
1526{
1527 u32 dma_mask;
1528
1529 ++adapter->capturing;
1530
1531 filter_enable_mask_filter(adapter, 1);
1532
1533 add_pid(adapter, pid);
1534
1535 dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
1536
1537 if ((adapter->dma_status & 7) != 7) {
1538 dma_mask = 0;
1539
1540 if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) {
1541 dma_mask = dma_mask | 1;
1542
1543 adapter->dmaq1.head = 0;
1544 adapter->dmaq1.tail = 0;
1545
1546 memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size);
1547 }
1548
1549 if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) {
1550 dma_mask = dma_mask | 2;
1551
1552 adapter->dmaq2.head = 0;
1553 adapter->dmaq2.tail = 0;
1554 }
1555
1556 if (dma_mask != 0) {
1557 irq_dma_enable_disable_irq(adapter, 1);
1558
1559 dma_start_stop(adapter, dma_mask, 1);
1560 }
1561 }
1562}
1563
1564static void close_stream(struct adapter *adapter, u16 pid)
1565{
1566 if (adapter->capturing > 0)
1567 --adapter->capturing;
1568
1569 dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
1570
1571 if (adapter->capturing == 0) {
1572 u32 dma_mask = 0;
1573
1574 if ((adapter->dma_status & 1) != 0)
1575 dma_mask = dma_mask | 0x00000001;
1576 if ((adapter->dma_status & 2) != 0)
1577 dma_mask = dma_mask | 0x00000002;
1578
1579 if (dma_mask != 0) {
1580 dma_start_stop(adapter, dma_mask, 0);
1581 }
1582 }
1583 remove_pid(adapter, pid);
1584}
1585
1586static void interrupt_service_dma1(struct adapter *adapter)
1587{
1588 struct dvb_demux *dvbdmx = &adapter->demux;
1589
1590 int n_cur_dma_counter;
1591 u32 n_num_bytes_parsed;
1592 u32 n_num_new_bytes_transferred;
1593 u32 dw_default_packet_size = 188;
1594 u8 gb_tmp_buffer[188];
1595 u8 *pb_dma_buf_cur_pos;
1596
1597 n_cur_dma_counter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
1598 n_cur_dma_counter = (n_cur_dma_counter / dw_default_packet_size) * dw_default_packet_size;
1599
1600 if ((n_cur_dma_counter < 0) || (n_cur_dma_counter > adapter->dmaq1.buffer_size)) {
1601 dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
1602 return;
1603 }
1604
1605 adapter->dmaq1.head = n_cur_dma_counter;
1606
1607 if (adapter->dmaq1.tail <= n_cur_dma_counter) {
1608 n_num_new_bytes_transferred = n_cur_dma_counter - adapter->dmaq1.tail;
1609
1610 } else {
1611
1612 n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
1613 }
1614
1615 ddprintk("%s: n_cur_dma_counter = %d\n", __FUNCTION__, n_cur_dma_counter);
1616 ddprintk("%s: dmaq1.tail = %d\n", __FUNCTION__, adapter->dmaq1.tail);
1617 ddprintk("%s: bytes_transferred = %d\n", __FUNCTION__, n_num_new_bytes_transferred);
1618
1619 if (n_num_new_bytes_transferred < dw_default_packet_size)
1620 return;
1621
1622 n_num_bytes_parsed = 0;
1623
1624 while (n_num_bytes_parsed < n_num_new_bytes_transferred) {
1625 pb_dma_buf_cur_pos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
1626
1627 if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
1628 memcpy(gb_tmp_buffer, adapter->dmaq1.buffer + adapter->dmaq1.tail,
1629 adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
1630 memcpy(gb_tmp_buffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer,
1631 (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
1632
1633 pb_dma_buf_cur_pos = gb_tmp_buffer;
1634 }
1635
1636 if (adapter->capturing != 0) {
1637 dvb_dmx_swfilter_packets(dvbdmx, pb_dma_buf_cur_pos, dw_default_packet_size / 188);
1638 }
1639
1640 n_num_bytes_parsed = n_num_bytes_parsed + dw_default_packet_size;
1641
1642 adapter->dmaq1.tail = adapter->dmaq1.tail + dw_default_packet_size;
1643
1644 if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
1645 adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
1646 };
1647}
1648
1649static void interrupt_service_dma2(struct adapter *adapter)
1650{
1651 printk("%s:\n", __FUNCTION__);
1652}
1653
1654static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs)
1655{
1656 struct adapter *tmp = dev_id;
1657
1658 u32 value;
1659
1660 ddprintk("%s:\n", __FUNCTION__);
1661
1662 spin_lock_irq(&tmp->lock);
1663
1664 if (0 == ((value = read_reg_dw(tmp, 0x20c)) & 0x0f)) {
1665 spin_unlock_irq(&tmp->lock);
1666 return IRQ_NONE;
1667 }
1668
1669 while (value != 0) {
1670 if ((value & 0x03) != 0)
1671 interrupt_service_dma1(tmp);
1672 if ((value & 0x0c) != 0)
1673 interrupt_service_dma2(tmp);
1674 value = read_reg_dw(tmp, 0x20c) & 0x0f;
1675 }
1676
1677 spin_unlock_irq(&tmp->lock);
1678 return IRQ_HANDLED;
1679}
1680
1681static int init_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq,
1682 int size, int dmaq_offset)
1683{
1684 struct pci_dev *pdev = adapter->pdev;
1685 dma_addr_t dma_addr;
1686
1687 dmaq->head = 0;
1688 dmaq->tail = 0;
1689
1690 dmaq->buffer = pci_alloc_consistent(pdev, size + 0x80, &dma_addr);
1691 if (!dmaq->buffer)
1692 return -ENOMEM;
1693
1694 dmaq->bus_addr = dma_addr;
1695 dmaq->buffer_size = size;
1696
1697 dma_init_dma(adapter, dmaq_offset);
1698
1699 ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n",
1700 __FUNCTION__, dmaq->buffer, size);
1701
1702 return 0;
1703 }
1704
1705static int init_dma_queue(struct adapter *adapter)
1706{
1707 struct {
1708 struct dmaq *dmaq;
1709 u32 dma_status;
1710 int size;
1711 } dmaq_desc[] = {
1712 { &adapter->dmaq1, 0x10000000, SIZE_OF_BUF_DMA1 },
1713 { &adapter->dmaq2, 0x20000000, SIZE_OF_BUF_DMA2 }
1714 }, *p = dmaq_desc;
1715 int i;
1716
1717 for (i = 0; i < 2; i++, p++) {
1718 if (init_dma_queue_one(adapter, p->dmaq, p->size, i) < 0)
1719 adapter->dma_status &= ~p->dma_status;
1720 else
1721 adapter->dma_status |= p->dma_status;
1722 }
1723 return (adapter->dma_status & 0x30000000) ? 0 : -ENOMEM;
1724}
1725
1726static void free_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq)
1727{
1728 if (dmaq->buffer) {
1729 pci_free_consistent(adapter->pdev, dmaq->buffer_size + 0x80,
1730 dmaq->buffer, dmaq->bus_addr);
1731 memset(dmaq, 0, sizeof(*dmaq));
1732 }
1733}
1734
1735static void free_dma_queue(struct adapter *adapter)
1736{
1737 struct dmaq *dmaq[] = {
1738 &adapter->dmaq1,
1739 &adapter->dmaq2,
1740 NULL
1741 }, **p;
1742
1743 for (p = dmaq; *p; p++)
1744 free_dma_queue_one(adapter, *p);
1745 }
1746
1747static void release_adapter(struct adapter *adapter)
1748{
1749 struct pci_dev *pdev = adapter->pdev;
1750
1751 iounmap(adapter->io_mem);
1752 pci_disable_device(pdev);
1753 pci_release_region(pdev, 0);
1754 pci_release_region(pdev, 1);
1755}
1756
1757static void free_adapter_object(struct adapter *adapter)
1758{
1759 dprintk("%s:\n", __FUNCTION__);
1760
1761 close_stream(adapter, 0);
1762 free_irq(adapter->irq, adapter);
1763 free_dma_queue(adapter);
1764 release_adapter(adapter);
1765 kfree(adapter);
1766}
1767
1768static struct pci_driver skystar2_pci_driver;
1769
1770static int claim_adapter(struct adapter *adapter)
1771{
1772 struct pci_dev *pdev = adapter->pdev;
1773 u16 var;
1774 int ret;
1775
1776 ret = pci_request_region(pdev, 1, skystar2_pci_driver.name);
1777 if (ret < 0)
1778 goto out;
1779
1780 ret = pci_request_region(pdev, 0, skystar2_pci_driver.name);
1781 if (ret < 0)
1782 goto err_pci_release_1;
1783
1784 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &adapter->card_revision);
1785
1786 dprintk("%s: card revision %x \n", __FUNCTION__, adapter->card_revision);
1787
1788 ret = pci_enable_device(pdev);
1789 if (ret < 0)
1790 goto err_pci_release_0;
1791
1792 pci_read_config_word(pdev, 4, &var);
1793
1794 if ((var & 4) == 0)
1795 pci_set_master(pdev);
1796
1797 adapter->io_port = pdev->resource[1].start;
1798
1799 adapter->io_mem = ioremap(pdev->resource[0].start, 0x800);
1800
1801 if (!adapter->io_mem) {
1802 dprintk("%s: can not map io memory\n", __FUNCTION__);
1803 ret = -EIO;
1804 goto err_pci_disable;
1805 }
1806
1807 dprintk("%s: io memory maped at %p\n", __FUNCTION__, adapter->io_mem);
1808
1809 ret = 1;
1810out:
1811 return ret;
1812
1813err_pci_disable:
1814 pci_disable_device(pdev);
1815err_pci_release_0:
1816 pci_release_region(pdev, 0);
1817err_pci_release_1:
1818 pci_release_region(pdev, 1);
1819 goto out;
1820}
1821
1822/*
1823static int sll_reset_flexcop(struct adapter *adapter)
1824{
1825 write_reg_dw(adapter, 0x208, 0);
1826 write_reg_dw(adapter, 0x210, 0xb2ff);
1827
1828 return 0;
1829}
1830*/
1831
1832static void decide_how_many_hw_filters(struct adapter *adapter)
1833{
1834 int hw_filters;
1835 int mod_option_hw_filters;
1836
1837 // FlexCop IIb & III have 6+32 hw filters
1838 // FlexCop II has 6 hw filters, every other should have at least 6
1839 switch (adapter->b2c2_revision) {
1840 case 0x82: /* II */
1841 hw_filters = 6;
1842 break;
1843 case 0xc3: /* IIB */
1844 hw_filters = 6 + 32;
1845 break;
1846 case 0xc0: /* III */
1847 hw_filters = 6 + 32;
1848 break;
1849 default:
1850 hw_filters = 6;
1851 break;
1852 }
1853 printk("%s: the chip has %i hardware filters", __FILE__, hw_filters);
1854
1855 mod_option_hw_filters = 0;
1856 if (enable_hw_filters >= 1)
1857 mod_option_hw_filters += 6;
1858 if (enable_hw_filters >= 2)
1859 mod_option_hw_filters += 32;
1860
1861 if (mod_option_hw_filters >= hw_filters) {
1862 adapter->useable_hw_filters = hw_filters;
1863 } else {
1864 adapter->useable_hw_filters = mod_option_hw_filters;
1865 printk(", but only %d will be used because of module option", mod_option_hw_filters);
1866 }
1867 printk("\n");
1868 dprintk("%s: useable_hardware_filters set to %i\n", __FILE__, adapter->useable_hw_filters);
1869}
1870
1871static int driver_initialize(struct pci_dev *pdev)
1872{
1873 struct adapter *adapter;
1874 u32 tmp;
1875 int ret = -ENOMEM;
1876
1877 adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
1878 if (!adapter) {
1879 dprintk("%s: out of memory!\n", __FUNCTION__);
1880 goto out;
1881 }
1882
1883 memset(adapter, 0, sizeof(struct adapter));
1884
1885 pci_set_drvdata(pdev,adapter);
1886
1887 adapter->pdev = pdev;
1888 adapter->irq = pdev->irq;
1889
1890 ret = claim_adapter(adapter);
1891 if (ret < 0)
1892 goto err_kfree;
1893
1894 irq_dma_enable_disable_irq(adapter, 0);
1895
1896 ret = request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter);
1897 if (ret < 0) {
1898 dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
1899 goto err_release_adapter;
1900 }
1901
1902 read_reg_dw(adapter, 0x208);
1903 write_reg_dw(adapter, 0x208, 0);
1904 write_reg_dw(adapter, 0x210, 0xb2ff);
1905 write_reg_dw(adapter, 0x208, 0x40);
1906
1907 ret = init_dma_queue(adapter);
1908 if (ret < 0)
1909 goto err_free_irq;
1910
1911 adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
1912
1913 switch (adapter->b2c2_revision) {
1914 case 0x82:
1915 printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
1916 break;
1917 case 0xc3:
1918 printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
1919 break;
1920 case 0xc0:
1921 printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
1922 break;
1923 default:
1924 printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
1925 printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
1926 ret = -ENODEV;
1927 goto err_free_dma_queue;
1928 }
1929
1930 decide_how_many_hw_filters(adapter);
1931
1932 init_pids(adapter);
1933
1934 tmp = read_reg_dw(adapter, 0x204);
1935
1936 write_reg_dw(adapter, 0x204, 0);
1937 mdelay(20);
1938
1939 write_reg_dw(adapter, 0x204, tmp);
1940 mdelay(10);
1941
1942 tmp = read_reg_dw(adapter, 0x308);
1943 write_reg_dw(adapter, 0x308, 0x4000 | tmp);
1944
1945 adapter->dw_sram_type = 0x10000;
1946
1947 sll_detect_sram_size(adapter);
1948
1949 dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, sram_length(adapter), adapter->dw_sram_type);
1950
1951 sram_set_media_dest(adapter, 1);
1952 sram_set_net_dest(adapter, 1);
1953
1954 ctrl_enable_smc(adapter, 0);
1955
1956 sram_set_cai_dest(adapter, 2);
1957 sram_set_cao_dest(adapter, 2);
1958
1959 dma_enable_disable_irq(adapter, 1, 0, 0);
1960
1961 if (eeprom_get_mac_addr(adapter, 0, adapter->mac_addr) != 0) {
1962 printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0],
1963 adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5],
1964 adapter->mac_addr[6], adapter->mac_addr[7]
1965 );
1966
1967 ca_set_mac_dst_addr_filter(adapter, adapter->mac_addr);
1968 ctrl_enable_mac(adapter, 1);
1969 }
1970
1971 spin_lock_init(&adapter->lock);
1972
1973out:
1974 return ret;
1975
1976err_free_dma_queue:
1977 free_dma_queue(adapter);
1978err_free_irq:
1979 free_irq(pdev->irq, adapter);
1980err_release_adapter:
1981 release_adapter(adapter);
1982err_kfree:
1983 pci_set_drvdata(pdev, NULL);
1984 kfree(adapter);
1985 goto out;
1986}
1987
1988static void driver_halt(struct pci_dev *pdev)
1989{
1990 struct adapter *adapter = pci_get_drvdata(pdev);
1991
1992 irq_dma_enable_disable_irq(adapter, 0);
1993
1994 ctrl_enable_receive_data(adapter, 0);
1995
1996 free_adapter_object(adapter);
1997
1998 pci_set_drvdata(pdev, NULL);
1999}
2000
2001static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
2002{
2003 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
2004 struct adapter *adapter = (struct adapter *) dvbdmx->priv;
2005
2006 dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
2007
2008 open_stream(adapter, dvbdmxfeed->pid);
2009
2010 return 0;
2011}
2012
2013static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
2014{
2015 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
2016 struct adapter *adapter = (struct adapter *) dvbdmx->priv;
2017
2018 dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
2019
2020 close_stream(adapter, dvbdmxfeed->pid);
2021
2022 return 0;
2023}
2024
2025/* lnb control */
2026static void set_tuner_tone(struct adapter *adapter, u8 tone)
2027{
2028 u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc };
2029 u16 ax;
2030
2031 dprintk("%s: %u\n", __FUNCTION__, tone);
2032
2033 switch (tone) {
2034 case 1:
2035 ax = wz_half_period_for_45_mhz[0];
2036 break;
2037 case 2:
2038 ax = wz_half_period_for_45_mhz[1];
2039 break;
2040 case 3:
2041 ax = wz_half_period_for_45_mhz[2];
2042 break;
2043 case 4:
2044 ax = wz_half_period_for_45_mhz[3];
2045 break;
2046
2047 default:
2048 ax = 0;
2049 }
2050
2051 if (ax != 0) {
2052 write_reg_dw(adapter, 0x200, ((ax << 0x0f) + (ax & 0x7fff)) | 0x40000000);
2053
2054 } else {
2055
2056 write_reg_dw(adapter, 0x200, 0x40ff8000);
2057 }
2058}
2059
2060static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
2061{
2062 u32 var;
2063
2064 dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
2065
2066 var = read_reg_dw(adapter, 0x204);
2067
2068 if (polarity == 0) {
2069 dprintk("%s: LNB power off\n", __FUNCTION__);
2070 var = var | 1;
2071 };
2072
2073 if (polarity == 1) {
2074 var = var & ~1;
2075 var = var & ~4;
2076 };
2077
2078 if (polarity == 2) {
2079 var = var & ~1;
2080 var = var | 4;
2081 }
2082
2083 write_reg_dw(adapter, 0x204, var);
2084}
2085
2086static void diseqc_send_bit(struct adapter *adapter, int data)
2087{
2088 set_tuner_tone(adapter, 1);
2089 udelay(data ? 500 : 1000);
2090 set_tuner_tone(adapter, 0);
2091 udelay(data ? 1000 : 500);
2092}
2093
2094
2095static void diseqc_send_byte(struct adapter *adapter, int data)
2096 {
2097 int i, par = 1, d;
2098
2099 for (i = 7; i >= 0; i--) {
2100 d = (data >> i) & 1;
2101 par ^= d;
2102 diseqc_send_bit(adapter, d);
2103 }
2104
2105 diseqc_send_bit(adapter, par);
2106 }
2107
2108
2109static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned long burst)
2110{
2111 int i;
2112
2113 set_tuner_tone(adapter, 0);
2114 mdelay(16);
2115
2116 for (i = 0; i < len; i++)
2117 diseqc_send_byte(adapter, msg[i]);
2118
2119 mdelay(16);
2120
2121 if (burst != -1) {
2122 if (burst)
2123 diseqc_send_byte(adapter, 0xff);
2124 else {
2125 set_tuner_tone(adapter, 1);
2126 udelay(12500);
2127 set_tuner_tone(adapter, 0);
2128 }
2129 msleep(20);
2130 }
2131
2132 return 0;
2133}
2134
2135static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2136{
2137 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2138
2139 switch(tone) {
2140 case SEC_TONE_ON:
2141 set_tuner_tone(adapter, 1);
2142 break;
2143 case SEC_TONE_OFF:
2144 set_tuner_tone(adapter, 0);
2145 break;
2146 default:
2147 return -EINVAL;
2148 };
2149
2150 return 0;
2151}
2152
2153static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
2154 {
2155 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2156
2157 send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
2158
2159 return 0;
2160 }
2161
2162static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
2163{
2164 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2165
2166 send_diseqc_msg(adapter, 0, NULL, minicmd);
2167
2168 return 0;
2169}
2170
2171static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2172 {
2173 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2174
2175 dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
2176
2177 switch (voltage) {
2178 case SEC_VOLTAGE_13:
2179 dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
2180 set_tuner_polarity(adapter, 1);
2181 return 0;
2182
2183 case SEC_VOLTAGE_18:
2184 dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
2185 set_tuner_polarity(adapter, 2);
2186 return 0;
2187
2188 default:
2189 return -EINVAL;
2190 }
2191 }
2192
2193static int flexcop_sleep(struct dvb_frontend* fe)
2194 {
2195 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2196
2197 dprintk("%s: FE_SLEEP\n", __FUNCTION__);
2198 set_tuner_polarity(adapter, 0);
2199
2200 if (adapter->fe_sleep) return adapter->fe_sleep(fe);
2201 return 0;
2202 }
2203
2204static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
2205 {
2206 printk("flexcop_i2c_func\n");
2207
2208 return I2C_FUNC_I2C;
2209}
2210
2211static struct i2c_algorithm flexcop_algo = {
2212 .name = "flexcop i2c algorithm",
2213 .id = I2C_ALGO_BIT,
2214 .master_xfer = master_xfer,
2215 .functionality = flexcop_i2c_func,
2216};
2217
2218
2219
2220
2221static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
2222{
2223 u8 aclk = 0;
2224 u8 bclk = 0;
2225
2226 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
2227 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
2228 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
2229 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
2230 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
2231 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
2232
2233 stv0299_writereg (fe, 0x13, aclk);
2234 stv0299_writereg (fe, 0x14, bclk);
2235 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
2236 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
2237 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
2238
2239 return 0;
2240}
2241
2242static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2243{
2244 u8 buf[4];
2245 u32 div;
2246 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
2247 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2248
2249 div = params->frequency / 125;
2250
2251 buf[0] = (div >> 8) & 0x7f;
2252 buf[1] = div & 0xff;
2253 buf[2] = 0x84; // 0xC4
2254 buf[3] = 0x08;
2255
2256 if (params->frequency < 1500000) buf[3] |= 0x10;
2257
2258 if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
2259 return 0;
2260}
2261
2262static u8 samsung_tbmu24112_inittab[] = {
2263 0x01, 0x15,
2264 0x02, 0x30,
2265 0x03, 0x00,
2266 0x04, 0x7D,
2267 0x05, 0x35,
2268 0x06, 0x02,
2269 0x07, 0x00,
2270 0x08, 0xC3,
2271 0x0C, 0x00,
2272 0x0D, 0x81,
2273 0x0E, 0x23,
2274 0x0F, 0x12,
2275 0x10, 0x7E,
2276 0x11, 0x84,
2277 0x12, 0xB9,
2278 0x13, 0x88,
2279 0x14, 0x89,
2280 0x15, 0xC9,
2281 0x16, 0x00,
2282 0x17, 0x5C,
2283 0x18, 0x00,
2284 0x19, 0x00,
2285 0x1A, 0x00,
2286 0x1C, 0x00,
2287 0x1D, 0x00,
2288 0x1E, 0x00,
2289 0x1F, 0x3A,
2290 0x20, 0x2E,
2291 0x21, 0x80,
2292 0x22, 0xFF,
2293 0x23, 0xC1,
2294 0x28, 0x00,
2295 0x29, 0x1E,
2296 0x2A, 0x14,
2297 0x2B, 0x0F,
2298 0x2C, 0x09,
2299 0x2D, 0x05,
2300 0x31, 0x1F,
2301 0x32, 0x19,
2302 0x33, 0xFE,
2303 0x34, 0x93,
2304 0xff, 0xff,
2305 };
2306
2307static struct stv0299_config samsung_tbmu24112_config = {
2308 .demod_address = 0x68,
2309 .inittab = samsung_tbmu24112_inittab,
2310 .mclk = 88000000UL,
2311 .invert = 0,
2312 .enhanced_tuning = 0,
2313 .skip_reinit = 0,
2314 .lock_output = STV0229_LOCKOUTPUT_LK,
2315 .volt13_op0_op1 = STV0299_VOLT13_OP1,
2316 .min_delay_ms = 100,
2317 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
2318 .pll_set = samsung_tbmu24112_pll_set,
2319};
2320
2321
2322
2323static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
2324{
2325 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2326
2327 return request_firmware(fw, name, &adapter->pdev->dev);
2328}
2329
2330
2331static struct nxt2002_config samsung_tbmv_config = {
2332 .demod_address = 0x0A,
2333 .request_firmware = nxt2002_request_firmware,
2334};
2335
2336static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
2337{
2338 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
2339 static u8 mt352_reset [] = { 0x50, 0x80 };
2340 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
2341 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
2342 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
2343
2344 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
2345 udelay(2000);
2346 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
2347 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
2348
2349 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
2350 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
2351
2352 return 0;
2353}
2354
2355static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
2356{
2357 u32 div;
2358 unsigned char bs = 0;
2359
2360 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
2361 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
2362
2363 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
2364 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
2365 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
2366
2367 pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
2368 pllbuf[1] = div >> 8;
2369 pllbuf[2] = div & 0xff;
2370 pllbuf[3] = 0xcc;
2371 pllbuf[4] = bs;
2372
2373 return 0;
2374}
2375
2376static struct mt352_config samsung_tdtc9251dh0_config = {
2377
2378 .demod_address = 0x0f,
2379 .demod_init = samsung_tdtc9251dh0_demod_init,
2380 .pll_set = samsung_tdtc9251dh0_pll_set,
2381};
2382
2383static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2384{
2385 u8 buf[4];
2386 u32 div;
2387 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
2388 struct adapter* adapter = (struct adapter*) fe->dvb->priv;
2389
2390 div = (params->frequency + (125/2)) / 125;
2391
2392 buf[0] = (div >> 8) & 0x7f;
2393 buf[1] = (div >> 0) & 0xff;
2394 buf[2] = 0x84 | ((div >> 10) & 0x60);
2395 buf[3] = 0x80;
2396
2397 if (params->frequency < 1550000)
2398 buf[3] |= 0x02;
2399
2400 if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
2401 return 0;
2402}
2403
2404static struct mt312_config skystar23_samsung_tbdu18132_config = {
2405
2406 .demod_address = 0x0e,
2407 .pll_set = skystar23_samsung_tbdu18132_pll_set,
2408};
2409
2410
2411
2412
2413static void frontend_init(struct adapter *skystar2)
2414{
2415 switch(skystar2->pdev->device) {
2416 case 0x2103: // Technisat Skystar2 OR Technisat Airstar2 (DVB-T or ATSC)
2417
2418 // Attempt to load the Nextwave nxt2002 for ATSC support
2419 skystar2->fe = nxt2002_attach(&samsung_tbmv_config, &skystar2->i2c_adap);
2420 if (skystar2->fe != NULL) {
2421 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2422 skystar2->fe->ops->sleep = flexcop_sleep;
2423 break;
2424 }
2425
2426 // try the skystar2 v2.6 first (stv0299/Samsung tbmu24112(sl1935))
2427 skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap);
2428 if (skystar2->fe != NULL) {
2429 skystar2->fe->ops->set_voltage = flexcop_set_voltage;
2430 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2431 skystar2->fe->ops->sleep = flexcop_sleep;
2432 break;
2433}
2434
2435 // try the airstar2 (mt352/Samsung tdtc9251dh0(??))
2436 skystar2->fe = mt352_attach(&samsung_tdtc9251dh0_config, &skystar2->i2c_adap);
2437 if (skystar2->fe != NULL) {
2438 skystar2->fe->ops->info.frequency_min = 474000000;
2439 skystar2->fe->ops->info.frequency_max = 858000000;
2440 break;
2441 }
2442
2443 // try the skystar2 v2.3 (vp310/Samsung tbdu18132(tsa5059))
2444 skystar2->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &skystar2->i2c_adap);
2445 if (skystar2->fe != NULL) {
2446 skystar2->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
2447 skystar2->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst;
2448 skystar2->fe->ops->set_tone = flexcop_set_tone;
2449 skystar2->fe->ops->set_voltage = flexcop_set_voltage;
2450 skystar2->fe_sleep = skystar2->fe->ops->sleep;
2451 skystar2->fe->ops->sleep = flexcop_sleep;
2452 break;
2453 }
2454 break;
2455 }
2456
2457 if (skystar2->fe == NULL) {
2458 printk("skystar2: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
2459 skystar2->pdev->vendor,
2460 skystar2->pdev->device,
2461 skystar2->pdev->subsystem_vendor,
2462 skystar2->pdev->subsystem_device);
2463 } else {
2464 if (dvb_register_frontend(&skystar2->dvb_adapter, skystar2->fe)) {
2465 printk("skystar2: Frontend registration failed!\n");
2466 if (skystar2->fe->ops->release)
2467 skystar2->fe->ops->release(skystar2->fe);
2468 skystar2->fe = NULL;
2469 }
2470 }
2471}
2472
2473
2474static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2475{
2476 struct adapter *adapter;
2477 struct dvb_adapter *dvb_adapter;
2478 struct dvb_demux *dvbdemux;
2479 struct dmx_demux *dmx;
2480 int ret = -ENODEV;
2481
2482 if (!pdev)
2483 goto out;
2484
2485 ret = driver_initialize(pdev);
2486 if (ret < 0)
2487 goto out;
2488
2489 adapter = pci_get_drvdata(pdev);
2490 dvb_adapter = &adapter->dvb_adapter;
2491
2492 ret = dvb_register_adapter(dvb_adapter, skystar2_pci_driver.name,
2493 THIS_MODULE);
2494 if (ret < 0) {
2495 printk("%s: Error registering DVB adapter\n", __FUNCTION__);
2496 goto err_halt;
2497 }
2498
2499 dvb_adapter->priv = adapter;
2500
2501
2502 init_MUTEX(&adapter->i2c_sem);
2503
2504
2505 memset(&adapter->i2c_adap, 0, sizeof(struct i2c_adapter));
2506 strcpy(adapter->i2c_adap.name, "SkyStar2");
2507
2508 i2c_set_adapdata(&adapter->i2c_adap, adapter);
2509
2510#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2511 adapter->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2512#else
2513 adapter->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2514#endif
2515 adapter->i2c_adap.algo = &flexcop_algo;
2516 adapter->i2c_adap.algo_data = NULL;
2517 adapter->i2c_adap.id = I2C_ALGO_BIT;
2518
2519 ret = i2c_add_adapter(&adapter->i2c_adap);
2520 if (ret < 0)
2521 goto err_dvb_unregister;
2522
2523 dvbdemux = &adapter->demux;
2524
2525 dvbdemux->priv = adapter;
2526 dvbdemux->filternum = N_PID_SLOTS;
2527 dvbdemux->feednum = N_PID_SLOTS;
2528 dvbdemux->start_feed = dvb_start_feed;
2529 dvbdemux->stop_feed = dvb_stop_feed;
2530 dvbdemux->write_to_decoder = NULL;
2531 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
2532
2533 ret = dvb_dmx_init(&adapter->demux);
2534 if (ret < 0)
2535 goto err_i2c_del;
2536
2537 dmx = &dvbdemux->dmx;
2538
2539 adapter->hw_frontend.source = DMX_FRONTEND_0;
2540 adapter->dmxdev.filternum = N_PID_SLOTS;
2541 adapter->dmxdev.demux = dmx;
2542 adapter->dmxdev.capabilities = 0;
2543
2544 ret = dvb_dmxdev_init(&adapter->dmxdev, &adapter->dvb_adapter);
2545 if (ret < 0)
2546 goto err_dmx_release;
2547
2548 ret = dmx->add_frontend(dmx, &adapter->hw_frontend);
2549 if (ret < 0)
2550 goto err_dmxdev_release;
2551
2552 adapter->mem_frontend.source = DMX_MEMORY_FE;
2553
2554 ret = dmx->add_frontend(dmx, &adapter->mem_frontend);
2555 if (ret < 0)
2556 goto err_remove_hw_frontend;
2557
2558 ret = dmx->connect_frontend(dmx, &adapter->hw_frontend);
2559 if (ret < 0)
2560 goto err_remove_mem_frontend;
2561
2562 dvb_net_init(&adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
2563
2564 frontend_init(adapter);
2565out:
2566 return ret;
2567
2568err_remove_mem_frontend:
2569 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
2570err_remove_hw_frontend:
2571 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
2572err_dmxdev_release:
2573 dvb_dmxdev_release(&adapter->dmxdev);
2574err_dmx_release:
2575 dvb_dmx_release(&adapter->demux);
2576err_i2c_del:
2577 i2c_del_adapter(&adapter->i2c_adap);
2578err_dvb_unregister:
2579 dvb_unregister_adapter(&adapter->dvb_adapter);
2580err_halt:
2581 driver_halt(pdev);
2582 goto out;
2583}
2584
2585static void skystar2_remove(struct pci_dev *pdev)
2586{
2587 struct adapter *adapter = pci_get_drvdata(pdev);
2588 struct dvb_demux *dvbdemux;
2589 struct dmx_demux *dmx;
2590
2591 if (!adapter)
2592 return;
2593
2594 dvb_net_release(&adapter->dvbnet);
2595 dvbdemux = &adapter->demux;
2596 dmx = &dvbdemux->dmx;
2597
2598 dmx->close(dmx);
2599 dmx->remove_frontend(dmx, &adapter->hw_frontend);
2600 dmx->remove_frontend(dmx, &adapter->mem_frontend);
2601
2602 dvb_dmxdev_release(&adapter->dmxdev);
2603 dvb_dmx_release(dvbdemux);
2604
2605 if (adapter->fe != NULL)
2606 dvb_unregister_frontend(adapter->fe);
2607
2608 dvb_unregister_adapter(&adapter->dvb_adapter);
2609
2610 i2c_del_adapter(&adapter->i2c_adap);
2611
2612 driver_halt(pdev);
2613 }
2614
2615static struct pci_device_id skystar2_pci_tbl[] = {
2616 {0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
2617/* {0x000013d0, 0x00002200, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000}, UNDEFINED HARDWARE - mail linuxtv.org list */ //FCIII
2618 {0,},
2619};
2620
2621MODULE_DEVICE_TABLE(pci, skystar2_pci_tbl);
2622
2623static struct pci_driver skystar2_pci_driver = {
2624 .name = "SkyStar2",
2625 .id_table = skystar2_pci_tbl,
2626 .probe = skystar2_probe,
2627 .remove = skystar2_remove,
2628};
2629
2630static int skystar2_init(void)
2631{
2632 return pci_register_driver(&skystar2_pci_driver);
2633}
2634
2635static void skystar2_cleanup(void)
2636{
2637 pci_unregister_driver(&skystar2_pci_driver);
2638}
2639
2640module_init(skystar2_init);
2641module_exit(skystar2_cleanup);
2642
2643MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
2644MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 1339912c308b..9bd12832e3d9 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -258,10 +258,10 @@ int write_dst(struct dst_state *state, u8 *data, u8 len)
258 if (debug && (verbose > 4)) { 258 if (debug && (verbose > 4)) {
259 u8 i; 259 u8 i;
260 if (verbose > 4) { 260 if (verbose > 4) {
261 dprintk("%s writing", __FUNCTION__); 261 dprintk("%s writing [ ", __FUNCTION__);
262 for (i = 0; i < len; i++) 262 for (i = 0; i < len; i++)
263 dprintk(" %02x", data[i]); 263 dprintk("%02x ", data[i]);
264 dprintk("\n"); 264 dprintk("]\n");
265 } 265 }
266 } 266 }
267 for (cnt = 0; cnt < 2; cnt++) { 267 for (cnt = 0; cnt < 2; cnt++) {
@@ -320,10 +320,29 @@ int read_dst(struct dst_state *state, u8 * ret, u8 len)
320} 320}
321EXPORT_SYMBOL(read_dst); 321EXPORT_SYMBOL(read_dst);
322 322
323static int dst_set_freq(struct dst_state *state, u32 freq) 323static int dst_set_polarization(struct dst_state *state)
324{ 324{
325 u8 *val; 325 switch (state->voltage) {
326 case SEC_VOLTAGE_13: // vertical
327 printk("%s: Polarization=[Vertical]\n", __FUNCTION__);
328 state->tx_tuna[8] &= ~0x40; //1
329 break;
330
331 case SEC_VOLTAGE_18: // horizontal
332 printk("%s: Polarization=[Horizontal]\n", __FUNCTION__);
333 state->tx_tuna[8] |= 0x40; // 0
334 break;
335
336 case SEC_VOLTAGE_OFF:
337
338 break;
339 }
340
341 return 0;
342}
326 343
344static int dst_set_freq(struct dst_state *state, u32 freq)
345{
327 state->frequency = freq; 346 state->frequency = freq;
328 if (debug > 4) 347 if (debug > 4)
329 dprintk("%s: set Frequency %u\n", __FUNCTION__, freq); 348 dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
@@ -332,46 +351,30 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
332 freq = freq / 1000; 351 freq = freq / 1000;
333 if (freq < 950 || freq > 2150) 352 if (freq < 950 || freq > 2150)
334 return -EINVAL; 353 return -EINVAL;
335 val = &state->tx_tuna[0]; 354
336 val[2] = (freq >> 8) & 0x7f; 355 state->tx_tuna[2] = (freq >> 8);
337 val[3] = (u8) freq; 356 state->tx_tuna[3] = (u8) freq;
338 val[4] = 1; 357 state->tx_tuna[4] = 0x01;
339 val[8] &= ~4; 358 state->tx_tuna[8] &= ~0x04;
340 if (freq < 1531) 359 if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
341 val[8] |= 4; 360 if (freq < 1531)
361 state->tx_tuna[8] |= 0x04;
362 }
363
342 } else if (state->dst_type == DST_TYPE_IS_TERR) { 364 } else if (state->dst_type == DST_TYPE_IS_TERR) {
343 freq = freq / 1000; 365 freq = freq / 1000;
344 if (freq < 137000 || freq > 858000) 366 if (freq < 137000 || freq > 858000)
345 return -EINVAL; 367 return -EINVAL;
346 val = &state->tx_tuna[0];
347 val[2] = (freq >> 16) & 0xff;
348 val[3] = (freq >> 8) & 0xff;
349 val[4] = (u8) freq;
350 val[5] = 0;
351 switch (state->bandwidth) {
352 case BANDWIDTH_6_MHZ:
353 val[6] = 6;
354 break;
355 368
356 case BANDWIDTH_7_MHZ: 369 state->tx_tuna[2] = (freq >> 16) & 0xff;
357 case BANDWIDTH_AUTO: 370 state->tx_tuna[3] = (freq >> 8) & 0xff;
358 val[6] = 7; 371 state->tx_tuna[4] = (u8) freq;
359 break;
360 372
361 case BANDWIDTH_8_MHZ:
362 val[6] = 8;
363 break;
364 }
365
366 val[7] = 0;
367 val[8] = 0;
368 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 373 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
369 /* guess till will get one */ 374 state->tx_tuna[2] = (freq >> 16) & 0xff;
370 freq = freq / 1000; 375 state->tx_tuna[3] = (freq >> 8) & 0xff;
371 val = &state->tx_tuna[0]; 376 state->tx_tuna[4] = (u8) freq;
372 val[2] = (freq >> 16) & 0xff; 377
373 val[3] = (freq >> 8) & 0xff;
374 val[4] = (u8) freq;
375 } else 378 } else
376 return -EINVAL; 379 return -EINVAL;
377 return 0; 380 return 0;
@@ -379,51 +382,58 @@ static int dst_set_freq(struct dst_state *state, u32 freq)
379 382
380static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth) 383static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
381{ 384{
382 u8 *val;
383
384 state->bandwidth = bandwidth; 385 state->bandwidth = bandwidth;
385 386
386 if (state->dst_type != DST_TYPE_IS_TERR) 387 if (state->dst_type != DST_TYPE_IS_TERR)
387 return 0; 388 return 0;
388 389
389 val = &state->tx_tuna[0];
390 switch (bandwidth) { 390 switch (bandwidth) {
391 case BANDWIDTH_6_MHZ: 391 case BANDWIDTH_6_MHZ:
392 val[6] = 6; 392 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
393 break; 393 state->tx_tuna[7] = 0x06;
394 else {
395 state->tx_tuna[6] = 0x06;
396 state->tx_tuna[7] = 0x00;
397 }
398 break;
394 399
395 case BANDWIDTH_7_MHZ: 400 case BANDWIDTH_7_MHZ:
396 val[6] = 7; 401 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
397 break; 402 state->tx_tuna[7] = 0x07;
403 else {
404 state->tx_tuna[6] = 0x07;
405 state->tx_tuna[7] = 0x00;
406 }
407 break;
398 408
399 case BANDWIDTH_8_MHZ: 409 case BANDWIDTH_8_MHZ:
400 val[6] = 8; 410 if (state->dst_hw_cap & DST_TYPE_HAS_CA)
401 break; 411 state->tx_tuna[7] = 0x08;
412 else {
413 state->tx_tuna[6] = 0x08;
414 state->tx_tuna[7] = 0x00;
415 }
416 break;
402 417
403 default: 418 default:
404 return -EINVAL; 419 return -EINVAL;
405 } 420 }
406 return 0; 421 return 0;
407} 422}
408 423
409static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion) 424static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
410{ 425{
411 u8 *val;
412
413 state->inversion = inversion; 426 state->inversion = inversion;
414
415 val = &state->tx_tuna[0];
416
417 val[8] &= ~0x80;
418
419 switch (inversion) { 427 switch (inversion) {
420 case INVERSION_OFF: 428 case INVERSION_OFF: // Inversion = Normal
421 break; 429 state->tx_tuna[8] &= ~0x80;
422 case INVERSION_ON: 430 break;
423 val[8] |= 0x80; 431
424 break; 432 case INVERSION_ON:
425 default: 433 state->tx_tuna[8] |= 0x80;
426 return -EINVAL; 434 break;
435 default:
436 return -EINVAL;
427 } 437 }
428 return 0; 438 return 0;
429} 439}
@@ -478,6 +488,52 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate)
478 return 0; 488 return 0;
479} 489}
480 490
491
492static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
493{
494 if (state->dst_type != DST_TYPE_IS_CABLE)
495 return 0;
496
497 state->modulation = modulation;
498 switch (modulation) {
499 case QAM_16:
500 state->tx_tuna[8] = 0x10;
501 break;
502
503 case QAM_32:
504 state->tx_tuna[8] = 0x20;
505 break;
506
507 case QAM_64:
508 state->tx_tuna[8] = 0x40;
509 break;
510
511 case QAM_128:
512 state->tx_tuna[8] = 0x80;
513 break;
514
515 case QAM_256:
516 state->tx_tuna[8] = 0x00;
517 break;
518
519 case QPSK:
520 case QAM_AUTO:
521 case VSB_8:
522 case VSB_16:
523 default:
524 return -EINVAL;
525
526 }
527
528 return 0;
529}
530
531static fe_modulation_t dst_get_modulation(struct dst_state *state)
532{
533 return state->modulation;
534}
535
536
481u8 dst_check_sum(u8 * buf, u32 len) 537u8 dst_check_sum(u8 * buf, u32 len)
482{ 538{
483 u32 i; 539 u32 i;
@@ -577,7 +633,7 @@ struct dst_types dst_tlist[] = {
577 .device_id = "200103A", 633 .device_id = "200103A",
578 .offset = 0, 634 .offset = 0,
579 .dst_type = DST_TYPE_IS_SAT, 635 .dst_type = DST_TYPE_IS_SAT,
580 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, 636 .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
581 .dst_feature = 0 637 .dst_feature = 0
582 }, /* obsolete */ 638 }, /* obsolete */
583 639
@@ -626,7 +682,7 @@ struct dst_types dst_tlist[] = {
626 .device_id = "DSTMCI", 682 .device_id = "DSTMCI",
627 .offset = 1, 683 .offset = 1,
628 .dst_type = DST_TYPE_IS_SAT, 684 .dst_type = DST_TYPE_IS_SAT,
629 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, 685 .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT,
630 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 686 .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
631 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC 687 | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC
632 }, 688 },
@@ -872,7 +928,7 @@ static int dst_get_signal(struct dst_state* state)
872{ 928{
873 int retval; 929 int retval;
874 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; 930 u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
875 931 printk("%s: Getting Signal strength and other parameters !!!!!!!!\n", __FUNCTION__);
876 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { 932 if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
877 state->decode_lock = state->decode_strength = state->decode_snr = 0; 933 state->decode_lock = state->decode_strength = state->decode_snr = 0;
878 return 0; 934 return 0;
@@ -954,15 +1010,8 @@ static int dst_get_tuna(struct dst_state* state)
954 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; 1010 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
955 1011
956 state->decode_lock = 1; 1012 state->decode_lock = 1;
957 /*
958 dst->decode_n1 = (dst->rx_tuna[4] << 8) +
959 (dst->rx_tuna[5]);
960
961 dst->decode_n2 = (dst->rx_tuna[8] << 8) +
962 (dst->rx_tuna[7]);
963 */
964 state->diseq_flags |= HAS_LOCK; 1013 state->diseq_flags |= HAS_LOCK;
965 /* dst->cur_jiff = jiffies; */ 1014
966 return 1; 1015 return 1;
967} 1016}
968 1017
@@ -1098,7 +1147,11 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1098 1147
1099 switch (tone) { 1148 switch (tone) {
1100 case SEC_TONE_OFF: 1149 case SEC_TONE_OFF:
1101 state->tx_tuna[2] = 0xff; 1150 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1151 state->tx_tuna[2] = 0x00;
1152 else
1153 state->tx_tuna[2] = 0xff;
1154
1102 break; 1155 break;
1103 1156
1104 case SEC_TONE_ON: 1157 case SEC_TONE_ON:
@@ -1145,7 +1198,8 @@ static int dst_init(struct dvb_frontend* fe)
1145 static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; 1198 static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
1146 static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; 1199 static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
1147 static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; 1200 static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
1148 state->inversion = INVERSION_ON; 1201// state->inversion = INVERSION_ON;
1202 state->inversion = INVERSION_OFF;
1149 state->voltage = SEC_VOLTAGE_13; 1203 state->voltage = SEC_VOLTAGE_13;
1150 state->tone = SEC_TONE_OFF; 1204 state->tone = SEC_TONE_OFF;
1151 state->symbol_rate = 29473000; 1205 state->symbol_rate = 29473000;
@@ -1174,7 +1228,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status)
1174 1228
1175 *status = 0; 1229 *status = 0;
1176 if (state->diseq_flags & HAS_LOCK) { 1230 if (state->diseq_flags & HAS_LOCK) {
1177 dst_get_signal(state); 1231// dst_get_signal(state); // don't require(?) to ask MCU
1178 if (state->decode_lock) 1232 if (state->decode_lock)
1179 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; 1233 *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
1180 } 1234 }
@@ -1208,20 +1262,25 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
1208 1262
1209 dst_set_freq(state, p->frequency); 1263 dst_set_freq(state, p->frequency);
1210 if (verbose > 4) 1264 if (verbose > 4)
1211 dprintk("Set Frequency = [%d]\n", p->frequency); 1265 dprintk("Set Frequency=[%d]\n", p->frequency);
1212 1266
1213 dst_set_inversion(state, p->inversion); 1267// dst_set_inversion(state, p->inversion);
1214 if (state->dst_type == DST_TYPE_IS_SAT) { 1268 if (state->dst_type == DST_TYPE_IS_SAT) {
1269 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1270 dst_set_inversion(state, p->inversion);
1271
1215 dst_set_fec(state, p->u.qpsk.fec_inner); 1272 dst_set_fec(state, p->u.qpsk.fec_inner);
1216 dst_set_symbolrate(state, p->u.qpsk.symbol_rate); 1273 dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
1274 dst_set_polarization(state);
1217 if (verbose > 4) 1275 if (verbose > 4)
1218 dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate); 1276 dprintk("Set Symbolrate=[%d]\n", p->u.qpsk.symbol_rate);
1219 1277
1220 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1278 } else if (state->dst_type == DST_TYPE_IS_TERR) {
1221 dst_set_bandwidth(state, p->u.ofdm.bandwidth); 1279 dst_set_bandwidth(state, p->u.ofdm.bandwidth);
1222 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 1280 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1223 dst_set_fec(state, p->u.qam.fec_inner); 1281 dst_set_fec(state, p->u.qam.fec_inner);
1224 dst_set_symbolrate(state, p->u.qam.symbol_rate); 1282 dst_set_symbolrate(state, p->u.qam.symbol_rate);
1283 dst_set_modulation(state, p->u.qam.modulation);
1225 } 1284 }
1226 dst_write_tuna(fe); 1285 dst_write_tuna(fe);
1227 1286
@@ -1233,8 +1292,11 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
1233 struct dst_state* state = fe->demodulator_priv; 1292 struct dst_state* state = fe->demodulator_priv;
1234 1293
1235 p->frequency = state->decode_freq; 1294 p->frequency = state->decode_freq;
1236 p->inversion = state->inversion; 1295// p->inversion = state->inversion;
1237 if (state->dst_type == DST_TYPE_IS_SAT) { 1296 if (state->dst_type == DST_TYPE_IS_SAT) {
1297 if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
1298 p->inversion = state->inversion;
1299
1238 p->u.qpsk.symbol_rate = state->symbol_rate; 1300 p->u.qpsk.symbol_rate = state->symbol_rate;
1239 p->u.qpsk.fec_inner = dst_get_fec(state); 1301 p->u.qpsk.fec_inner = dst_get_fec(state);
1240 } else if (state->dst_type == DST_TYPE_IS_TERR) { 1302 } else if (state->dst_type == DST_TYPE_IS_TERR) {
@@ -1242,7 +1304,8 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet
1242 } else if (state->dst_type == DST_TYPE_IS_CABLE) { 1304 } else if (state->dst_type == DST_TYPE_IS_CABLE) {
1243 p->u.qam.symbol_rate = state->symbol_rate; 1305 p->u.qam.symbol_rate = state->symbol_rate;
1244 p->u.qam.fec_inner = dst_get_fec(state); 1306 p->u.qam.fec_inner = dst_get_fec(state);
1245 p->u.qam.modulation = QAM_AUTO; 1307// p->u.qam.modulation = QAM_AUTO;
1308 p->u.qam.modulation = dst_get_modulation(state);
1246 } 1309 }
1247 1310
1248 return 0; 1311 return 0;
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index d781504cc2fa..bfaacd5fc20f 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -32,7 +32,7 @@
32#include "dst_ca.h" 32#include "dst_ca.h"
33#include "dst_common.h" 33#include "dst_common.h"
34 34
35static unsigned int verbose = 1; 35static unsigned int verbose = 5;
36module_param(verbose, int, 0644); 36module_param(verbose, int, 0644);
37MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); 37MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
38 38
@@ -295,34 +295,28 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
295 return 0; 295 return 0;
296} 296}
297 297
298static int handle_en50221_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) 298static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
299{ 299{
300 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) { 300 if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
301 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */ 301 hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */
302 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */ 302 hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */
303 } 303 }
304 else { 304 else {
305 hw_buffer->msg[0] = (length & 0xff) + 7;
306 hw_buffer->msg[1] = 0x40;
305 hw_buffer->msg[2] = 0x03; 307 hw_buffer->msg[2] = 0x03;
306 hw_buffer->msg[3] = 0x00; 308 hw_buffer->msg[3] = 0x00;
309 hw_buffer->msg[4] = 0x03;
310 hw_buffer->msg[5] = length & 0xff;
311 hw_buffer->msg[6] = 0x00;
307 } 312 }
308 return 0; 313 return 0;
309} 314}
310 315
311static int debug_8820_buffer(struct ca_msg *hw_buffer)
312{
313 unsigned int i;
314
315 dprintk("%s:Debug=[", __FUNCTION__);
316 for (i = 0; i < (hw_buffer->msg[0] + 1); i++)
317 dprintk(" %02x", hw_buffer->msg[i]);
318 dprintk("]\n");
319
320 return 0;
321}
322 316
323static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply) 317static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
324{ 318{
325 if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) { 319 if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
326 dprintk("%s: DST-CI Command failed.\n", __FUNCTION__); 320 dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
327 dprintk("%s: Resetting DST.\n", __FUNCTION__); 321 dprintk("%s: Resetting DST.\n", __FUNCTION__);
328 rdc_reset_state(state); 322 rdc_reset_state(state);
@@ -334,234 +328,141 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 r
334 return 0; 328 return 0;
335} 329}
336 330
337 331u32 asn_1_decode(u8 *asn_1_array)
338static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
339{ 332{
340 u32 hw_offset, buf_offset, i, k; 333 u8 length_field = 0, word_count = 0, count = 0;
341 u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0; 334 u32 length = 0;
342 u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0; 335
343 336 length_field = asn_1_array[0];
344 if (verbose > 3) 337 dprintk("%s: Length field=[%02x]\n", __FUNCTION__, length_field);
345 dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length ); 338 if (length_field < 0x80) {
346 339 length = length_field & 0x7f;
347 handle_en50221_tag(state, p_ca_message, hw_buffer); /* EN50221 tag */ 340 dprintk("%s: Length=[%02x]\n", __FUNCTION__, length);
348 341 } else {
349 /* Handle the length field (variable) */ 342 word_count = length_field & 0x7f;
350 if (!(p_ca_message->msg[3] & 0x80)) { /* Length = 1 */ 343 for (count = 0; count < word_count; count++) {
351 length = p_ca_message->msg[3] & 0x7f; 344 length = (length | asn_1_array[count + 1]) << 8;
352 words = 0; /* domi's suggestion */ 345 dprintk("%s: Length=[%04x]\n", __FUNCTION__, length);
353 }
354 else { /* Length = words */
355 words = p_ca_message->msg[3] & 0x7f;
356 for (i = 0; i < words; i++) {
357 length = length << 8;
358 length = length | p_ca_message->msg[4 + i];
359 } 346 }
360 } 347 }
361 if (verbose > 4) { 348 return length;
362 dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words); 349}
363
364 /* Debug Input string */
365 for (i = 0; i < length; i++)
366 dprintk(" %02x", p_ca_message->msg[i]);
367 dprintk("]\n");
368 }
369
370 hw_offset = 7;
371 buf_offset = words + 4;
372
373 /* Program Header */
374 if (verbose > 4)
375 dprintk("\n%s:Program Header=[", __FUNCTION__);
376 for (i = 0; i < 6; i++) {
377 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
378 if (verbose > 4)
379 dprintk(" %02x", p_ca_message->msg[buf_offset]);
380 hw_offset++, buf_offset++, hw_buffer_length++;
381 }
382 if (verbose > 4)
383 dprintk("]\n");
384 350
385 program_info_length = 0; 351static int init_buffer(u8 *buffer, u32 length)
386 program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9]; 352{
387 if (verbose > 4) 353 u32 i;
388 dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n", 354 for (i = 0; i < length; i++)
389 __FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset); 355 buffer[i] = 0;
390 356
391 if (program_info_length && (program_info_length < 256)) { /* If program_info_length */ 357 return 0;
392 hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f; /* req only 4 bits */ 358}
393 hw_buffer->msg[12] = hw_buffer->msg[12] + 1; /* increment! ASIC bug! */
394 359
395 if (p_ca_message->msg[buf_offset + 1] == 0x09) { /* Check CA descriptor */ 360static int debug_string(u8 *msg, u32 length, u32 offset)
396 found_prog_ca_desc = 1; 361{
397 if (verbose > 4) 362 u32 i;
398 dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__);
399 }
400 363
401 if (found_prog_ca_desc) { /* Command only if CA descriptor */ 364 dprintk(" String=[ ");
402 hw_buffer->msg[13] = p_ca_message->msg[buf_offset]; /* CA PMT command ID */ 365 for (i = offset; i < length; i++)
403 hw_offset++, buf_offset++, hw_buffer_length++; 366 dprintk("%02x ", msg[i]);
404 } 367 dprintk("]\n");
405 368
406 /* Program descriptors */ 369 return 0;
407 if (verbose > 4) { 370}
408 dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
409 dprintk("%s:Program descriptors=[", __FUNCTION__);
410 }
411 while (program_info_length && !error_condition) { /* Copy prog descriptors */
412 if (program_info_length > p_ca_message->length) { /* Error situation */
413 dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n",
414 __FUNCTION__, __LINE__, program_info_length);
415 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
416 error_condition = 1;
417 break;
418 }
419 371
420 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; 372static int copy_string(u8 *destination, u8 *source, u32 dest_offset, u32 source_offset, u32 length)
421 dprintk(" %02x", p_ca_message->msg[buf_offset]); 373{
422 hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--; 374 u32 i;
423 } 375 dprintk("%s: Copying [", __FUNCTION__);
424 if (verbose > 4) { 376 for (i = 0; i < length; i++) {
425 dprintk("]\n"); 377 destination[i + dest_offset] = source[i + source_offset];
426 dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset); 378 dprintk(" %02x", source[i + source_offset]);
427 }
428 if (found_prog_ca_desc) {
429 if (!reply) {
430 hw_buffer->msg[13] = 0x01; /* OK descrambling */
431 if (verbose > 1)
432 dprintk("CA PMT Command = OK Descrambling\n");
433 }
434 else {
435 hw_buffer->msg[13] = 0x02; /* Ok MMI */
436 if (verbose > 1)
437 dprintk("CA PMT Command = Ok MMI\n");
438 }
439 if (query) {
440 hw_buffer->msg[13] = 0x03; /* Query */
441 if (verbose > 1)
442 dprintk("CA PMT Command = CA PMT query\n");
443 }
444 }
445 }
446 else {
447 hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0; /* Don't write to ASIC */
448 hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00;
449 } 379 }
450 if (verbose > 4) 380 dprintk("]\n");
451 dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n",
452 __FUNCTION__, p_ca_message->length, buf_offset, hw_offset);
453
454 while ((buf_offset < p_ca_message->length) && !error_condition) {
455 /* Bail out in case of an indefinite loop */
456 if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
457 dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n",
458 __FUNCTION__, __LINE__, program_info_length, buf_offset);
459
460 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
461 error_condition = 1;
462 break;
463 }
464
465 /* Stream Header */
466
467 for (k = 0; k < 5; k++) {
468 hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k];
469 }
470 381
471 es_info_length = 0; 382 return i;
472 es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4]; 383}
473 384
474 if (verbose > 4) { 385static int modify_4_bits(u8 *message, u32 pos)
475 dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__, 386{
476 p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1], 387 message[pos] &= 0x0f;
477 p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3],
478 p_ca_message->msg[buf_offset + 4]);
479 388
480 dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__, 389 return 0;
481 p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length, 390}
482 p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset);
483 }
484 391
485 hw_buffer->msg[hw_offset + 3] &= 0x0f; /* req only 4 bits */
486 392
487 if (found_prog_ca_desc) {
488 hw_buffer->msg[hw_offset + 3] = 0x00;
489 hw_buffer->msg[hw_offset + 4] = 0x00;
490 }
491 393
492 hw_offset += 5, buf_offset += 5, hw_buffer_length += 5; 394static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
395{
396 u32 length = 0, count = 0;
397 u8 asn_1_words, program_header_length;
398 u16 program_info_length = 0, es_info_length = 0;
399 u32 hw_offset = 0, buf_offset = 0, i;
400 u8 dst_tag_length;
493 401
494 /* Check for CA descriptor */ 402 length = asn_1_decode(&p_ca_message->msg[3]);
495 if (p_ca_message->msg[buf_offset + 1] == 0x09) { 403 dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length);
496 if (verbose > 4) 404 dprintk("%s: ASN.1 ", __FUNCTION__);
497 dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__); 405 debug_string(&p_ca_message->msg[4], length, 0); // length does not include tag and length
498 found_stream_ca_desc = 1;
499 }
500 406
501 /* ES descriptors */ 407 init_buffer(hw_buffer->msg, length);
502 408 handle_dst_tag(state, p_ca_message, hw_buffer, length);
503 if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) {
504// if (!ca_pmt_done) {
505 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; /* CA PMT cmd(es) */
506 if (verbose > 4)
507 printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]);
508// hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1;
509 hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
510// }
511 if (verbose > 4)
512 dprintk("%s:----->ES descriptors=[", __FUNCTION__);
513
514 while (es_info_length && !error_condition) { /* ES descriptors */
515 if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
516 if (verbose > 4) {
517 dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n",
518 __FUNCTION__, __LINE__, es_info_length, buf_offset);
519
520 dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
521 }
522 error_condition = 1;
523 break;
524 }
525 409
526 hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; 410 hw_offset = 7;
527 if (verbose > 3) 411 asn_1_words = 1; // just a hack to test, should compute this one
528 dprintk("%02x ", hw_buffer->msg[hw_offset]); 412 buf_offset = 3;
529 hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--; 413 program_header_length = 6;
530 } 414 dst_tag_length = 7;
531 found_stream_ca_desc = 0; /* unset for new streams */ 415
532 dprintk("]\n"); 416// debug_twinhan_ca_params(state, p_ca_message, hw_buffer, reply, query, length, hw_offset, buf_offset);
417// dprintk("%s: Program Header(BUF)", __FUNCTION__);
418// debug_string(&p_ca_message->msg[4], program_header_length, 0);
419// dprintk("%s: Copying Program header\n", __FUNCTION__);
420 copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + asn_1_words), program_header_length);
421 buf_offset += program_header_length, hw_offset += program_header_length;
422 modify_4_bits(hw_buffer->msg, (hw_offset - 2));
423 if (state->type_flags & DST_TYPE_HAS_INC_COUNT) { // workaround
424 dprintk("%s: Probably an ASIC bug !!!\n", __FUNCTION__);
425 debug_string(hw_buffer->msg, (hw_offset + program_header_length), 0);
426 hw_buffer->msg[hw_offset - 1] += 1;
427 }
428
429// dprintk("%s: Program Header(HW), Count=[%d]", __FUNCTION__, count);
430// debug_string(hw_buffer->msg, hw_offset, 0);
431
432 program_info_length = ((program_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
433 dprintk("%s: Program info length=[%02x]\n", __FUNCTION__, program_info_length);
434 if (program_info_length) {
435 count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + 1), (program_info_length + 1) ); // copy next elem, not current
436 buf_offset += count, hw_offset += count;
437// dprintk("%s: Program level ", __FUNCTION__);
438// debug_string(hw_buffer->msg, hw_offset, 0);
439 }
440
441 buf_offset += 1;// hw_offset += 1;
442 for (i = buf_offset; i < length; i++) {
443// dprintk("%s: Stream Header ", __FUNCTION__);
444 count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, buf_offset, 5);
445 modify_4_bits(hw_buffer->msg, (hw_offset + 3));
446
447 hw_offset += 5, buf_offset += 5, i += 4;
448// debug_string(hw_buffer->msg, hw_offset, (hw_offset - 5));
449 es_info_length = ((es_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
450 dprintk("%s: ES info length=[%02x]\n", __FUNCTION__, es_info_length);
451 if (es_info_length) {
452 // copy descriptors @ STREAM level
453 dprintk("%s: Descriptors @ STREAM level...!!! \n", __FUNCTION__);
533 } 454 }
534 }
535
536 /* MCU Magic words */
537
538 hw_buffer_length += 7;
539 hw_buffer->msg[0] = hw_buffer_length;
540 hw_buffer->msg[1] = 64;
541 hw_buffer->msg[4] = 3;
542 hw_buffer->msg[5] = hw_buffer->msg[0] - 7;
543 hw_buffer->msg[6] = 0;
544
545 455
546 /* Fix length */
547 hw_buffer->length = hw_buffer->msg[0];
548
549 put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]);
550 /* Do the actual write */
551 if (verbose > 4) {
552 dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__);
553 dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length);
554 } 456 }
555 /* Only for debugging! */ 457 hw_buffer->msg[length + dst_tag_length] = dst_check_sum(hw_buffer->msg, (length + dst_tag_length));
556 if (verbose > 2) 458// dprintk("%s: Total length=[%d], Checksum=[%02x]\n", __FUNCTION__, (length + dst_tag_length), hw_buffer->msg[length + dst_tag_length]);
557 debug_8820_buffer(hw_buffer); 459 debug_string(hw_buffer->msg, (length + dst_tag_length + 1), 0); // dst tags also
558 if (verbose > 3) 460 write_to_8820(state, hw_buffer, (length + dst_tag_length + 1), reply); // checksum
559 dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply);
560 write_to_8820(state, hw_buffer, reply);
561 461
562 return 0; 462 return 0;
563} 463}
564 464
465
565/* Board supports CA PMT reply ? */ 466/* Board supports CA PMT reply ? */
566static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) 467static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
567{ 468{
@@ -605,7 +506,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
605 struct ca_msg *hw_buffer; 506 struct ca_msg *hw_buffer;
606 507
607 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 508 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
608 printk("%s: Memory allocation failure\n", __FUNCTION__); 509 dprintk("%s: Memory allocation failure\n", __FUNCTION__);
609 return -ENOMEM; 510 return -ENOMEM;
610 } 511 }
611 if (verbose > 3) 512 if (verbose > 3)
@@ -630,8 +531,10 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
630 switch (command) { 531 switch (command) {
631 case CA_PMT: 532 case CA_PMT:
632 if (verbose > 3) 533 if (verbose > 3)
534// dprintk("Command = SEND_CA_PMT\n");
633 dprintk("Command = SEND_CA_PMT\n"); 535 dprintk("Command = SEND_CA_PMT\n");
634 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { 536// if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
537 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
635 dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__); 538 dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
636 return -1; 539 return -1;
637 } 540 }
@@ -664,7 +567,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
664 return -1; 567 return -1;
665 } 568 }
666 if (verbose > 3) 569 if (verbose > 3)
667 printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__); 570 dprintk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
668 571
669 break; 572 break;
670 } 573 }
@@ -681,17 +584,17 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
681 struct ca_msg *p_ca_message; 584 struct ca_msg *p_ca_message;
682 585
683 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 586 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
684 printk("%s: Memory allocation failure\n", __FUNCTION__); 587 dprintk("%s: Memory allocation failure\n", __FUNCTION__);
685 return -ENOMEM; 588 return -ENOMEM;
686 } 589 }
687 590
688 if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) { 591 if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
689 printk("%s: Memory allocation failure\n", __FUNCTION__); 592 dprintk("%s: Memory allocation failure\n", __FUNCTION__);
690 return -ENOMEM; 593 return -ENOMEM;
691 } 594 }
692 595
693 if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) { 596 if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
694 printk("%s: Memory allocation failure\n", __FUNCTION__); 597 dprintk("%s: Memory allocation failure\n", __FUNCTION__);
695 return -ENOMEM; 598 return -ENOMEM;
696 } 599 }
697 600
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 0b3da29245fb..ef532a6aceaa 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -47,6 +47,8 @@
47#define DST_TYPE_HAS_FW_2 16 47#define DST_TYPE_HAS_FW_2 16
48#define DST_TYPE_HAS_FW_3 32 48#define DST_TYPE_HAS_FW_3 32
49#define DST_TYPE_HAS_FW_BUILD 64 49#define DST_TYPE_HAS_FW_BUILD 64
50#define DST_TYPE_HAS_OBS_REGS 128
51#define DST_TYPE_HAS_INC_COUNT 256
50 52
51/* Card capability list */ 53/* Card capability list */
52 54
@@ -110,6 +112,7 @@ struct dst_state {
110 u32 dst_hw_cap; 112 u32 dst_hw_cap;
111 u8 dst_fw_version; 113 u8 dst_fw_version;
112 fe_sec_mini_cmd_t minicmd; 114 fe_sec_mini_cmd_t minicmd;
115 fe_modulation_t modulation;
113 u8 messages[256]; 116 u8 messages[256];
114}; 117};
115 118
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 96c57fde95a0..7d8b3cad350b 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -699,6 +699,8 @@ static void cinergyt2_query_rc (void *data)
699 for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) { 699 for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
700 int i; 700 int i;
701 701
702/* dprintk(1,"rc_events[%d].value = %x, type=%x\n",n,le32_to_cpu(rc_events[n].value),rc_events[n].type);*/
703
702 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && 704 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
703 rc_events[n].value == ~0) 705 rc_events[n].value == ~0)
704 { 706 {
@@ -714,7 +716,7 @@ static void cinergyt2_query_rc (void *data)
714 cinergyt2->rc_input_event = KEY_MAX; 716 cinergyt2->rc_input_event = KEY_MAX;
715 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) { 717 for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
716 if (rc_keys[i+0] == rc_events[n].type && 718 if (rc_keys[i+0] == rc_events[n].type &&
717 rc_keys[i+1] == rc_events[n].value) 719 rc_keys[i+1] == le32_to_cpu(rc_events[n].value))
718 { 720 {
719 cinergyt2->rc_input_event = rc_keys[i+2]; 721 cinergyt2->rc_input_event = rc_keys[i+2];
720 break; 722 break;
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index c225de7ffd82..68050cd527cb 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -42,12 +42,6 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
42 42
43#define dprintk if (debug) printk 43#define dprintk if (debug) printk
44 44
45static inline struct dmxdev_filter *
46dvb_dmxdev_file_to_filter(struct file *file)
47{
48 return (struct dmxdev_filter *) file->private_data;
49}
50
51static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer) 45static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer)
52{ 46{
53 buffer->data=NULL; 47 buffer->data=NULL;
@@ -669,8 +663,10 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
669 663
670 ret = filter->feed.ts->start_filtering(filter->feed.ts); 664 ret = filter->feed.ts->start_filtering(filter->feed.ts);
671 665
672 if (ret < 0) 666 if (ret < 0) {
667 dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
673 return ret; 668 return ret;
669 }
674 670
675 break; 671 break;
676 } 672 }
@@ -842,7 +838,7 @@ static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil,
842static ssize_t 838static ssize_t
843dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 839dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
844{ 840{
845 struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file); 841 struct dmxdev_filter *dmxdevfilter= file->private_data;
846 int ret=0; 842 int ret=0;
847 843
848 if (down_interruptible(&dmxdevfilter->mutex)) 844 if (down_interruptible(&dmxdevfilter->mutex))
@@ -863,7 +859,7 @@ dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
863static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, 859static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
864 unsigned int cmd, void *parg) 860 unsigned int cmd, void *parg)
865{ 861{
866 struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file); 862 struct dmxdev_filter *dmxdevfilter = file->private_data;
867 struct dmxdev *dmxdev=dmxdevfilter->dev; 863 struct dmxdev *dmxdev=dmxdevfilter->dev;
868 unsigned long arg=(unsigned long) parg; 864 unsigned long arg=(unsigned long) parg;
869 int ret=0; 865 int ret=0;
@@ -960,7 +956,7 @@ static int dvb_demux_ioctl(struct inode *inode, struct file *file,
960 956
961static unsigned int dvb_demux_poll (struct file *file, poll_table *wait) 957static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
962{ 958{
963 struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file); 959 struct dmxdev_filter *dmxdevfilter = file->private_data;
964 unsigned int mask = 0; 960 unsigned int mask = 0;
965 961
966 if (!dmxdevfilter) 962 if (!dmxdevfilter)
@@ -985,7 +981,7 @@ static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
985 981
986static int dvb_demux_release(struct inode *inode, struct file *file) 982static int dvb_demux_release(struct inode *inode, struct file *file)
987{ 983{
988 struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file); 984 struct dmxdev_filter *dmxdevfilter = file->private_data;
989 struct dmxdev *dmxdev = dmxdevfilter->dev; 985 struct dmxdev *dmxdev = dmxdevfilter->dev;
990 986
991 return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); 987 return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
@@ -1109,7 +1105,6 @@ dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
1109 dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE); 1105 dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
1110 dmxdev->dvr[i].dev=dmxdev; 1106 dmxdev->dvr[i].dev=dmxdev;
1111 dmxdev->dvr[i].buffer.data=NULL; 1107 dmxdev->dvr[i].buffer.data=NULL;
1112 dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
1113 dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE); 1108 dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
1114 } 1109 }
1115 1110
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index f11daae91cd4..a8bc84240b50 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -42,6 +42,8 @@
42#include "dvb_frontend.h" 42#include "dvb_frontend.h"
43#include "dvbdev.h" 43#include "dvbdev.h"
44 44
45// #define DEBUG_LOCKLOSS 1
46
45static int dvb_frontend_debug; 47static int dvb_frontend_debug;
46static int dvb_shutdown_timeout = 5; 48static int dvb_shutdown_timeout = 5;
47static int dvb_force_auto_inversion; 49static int dvb_force_auto_inversion;
@@ -113,6 +115,7 @@ struct dvb_frontend_private {
113 int exit; 115 int exit;
114 int wakeup; 116 int wakeup;
115 fe_status_t status; 117 fe_status_t status;
118 fe_sec_tone_mode_t tone;
116}; 119};
117 120
118 121
@@ -434,9 +437,26 @@ static int dvb_frontend_thread(void *data)
434 /* we're tuned, and the lock is still good... */ 437 /* we're tuned, and the lock is still good... */
435 if (s & FE_HAS_LOCK) 438 if (s & FE_HAS_LOCK)
436 continue; 439 continue;
437 else { 440 else { /* if we _WERE_ tuned, but now don't have a lock */
438 /* if we _WERE_ tuned, but now don't have a lock, 441#ifdef DEBUG_LOCKLOSS
439 * need to zigzag */ 442 /* first of all try setting the tone again if it was on - this
443 * sometimes works around problems with noisy power supplies */
444 if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) {
445 fe->ops->set_tone(fe, fepriv->tone);
446 mdelay(100);
447 s = 0;
448 fe->ops->read_status(fe, &s);
449 if (s & FE_HAS_LOCK) {
450 printk("DVB%i: Lock was lost, but regained by setting "
451 "the tone. This may indicate your power supply "
452 "is noisy/slightly incompatable with this DVB-S "
453 "adapter\n", fe->dvb->num);
454 fepriv->state = FESTATE_TUNED;
455 continue;
456 }
457 }
458#endif
459 /* some other reason for losing the lock - start zigzagging */
440 fepriv->state = FESTATE_ZIGZAG_FAST; 460 fepriv->state = FESTATE_ZIGZAG_FAST;
441 fepriv->started_auto_step = fepriv->auto_step; 461 fepriv->started_auto_step = fepriv->auto_step;
442 check_wrapped = 0; 462 check_wrapped = 0;
@@ -626,11 +646,21 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
626 break; 646 break;
627 } 647 }
628 648
629 case FE_READ_STATUS: 649 case FE_READ_STATUS: {
650 fe_status_t* status = parg;
651
652 /* if retune was requested but hasn't occured yet, prevent
653 * that user get signal state from previous tuning */
654 if(fepriv->state == FESTATE_RETUNE) {
655 err=0;
656 *status = 0;
657 break;
658 }
659
630 if (fe->ops->read_status) 660 if (fe->ops->read_status)
631 err = fe->ops->read_status(fe, (fe_status_t*) parg); 661 err = fe->ops->read_status(fe, status);
632 break; 662 break;
633 663 }
634 case FE_READ_BER: 664 case FE_READ_BER:
635 if (fe->ops->read_ber) 665 if (fe->ops->read_ber)
636 err = fe->ops->read_ber(fe, (__u32*) parg); 666 err = fe->ops->read_ber(fe, (__u32*) parg);
@@ -681,6 +711,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
681 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); 711 err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
682 fepriv->state = FESTATE_DISEQC; 712 fepriv->state = FESTATE_DISEQC;
683 fepriv->status = 0; 713 fepriv->status = 0;
714 fepriv->tone = (fe_sec_tone_mode_t) parg;
684 } 715 }
685 break; 716 break;
686 717
@@ -883,6 +914,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
883 init_MUTEX (&fepriv->events.sem); 914 init_MUTEX (&fepriv->events.sem);
884 fe->dvb = dvb; 915 fe->dvb = dvb;
885 fepriv->inversion = INVERSION_OFF; 916 fepriv->inversion = INVERSION_OFF;
917 fepriv->tone = SEC_TONE_OFF;
886 918
887 printk ("DVB: registering frontend %i (%s)...\n", 919 printk ("DVB: registering frontend %i (%s)...\n",
888 fe->dvb->num, 920 fe->dvb->num,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index d2b021792791..9c2c1d1136bd 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -40,28 +40,6 @@
40 40
41#include "dvbdev.h" 41#include "dvbdev.h"
42 42
43/* FIXME: Move to i2c-id.h */
44#define I2C_DRIVERID_DVBFE_SP8870 I2C_DRIVERID_EXP2
45#define I2C_DRIVERID_DVBFE_CX22700 I2C_DRIVERID_EXP2
46#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP2
47#define I2C_DRIVERID_DVBFE_CX24110 I2C_DRIVERID_EXP2
48#define I2C_DRIVERID_DVBFE_CX22702 I2C_DRIVERID_EXP2
49#define I2C_DRIVERID_DVBFE_DIB3000MB I2C_DRIVERID_EXP2
50#define I2C_DRIVERID_DVBFE_DST I2C_DRIVERID_EXP2
51#define I2C_DRIVERID_DVBFE_DUMMY I2C_DRIVERID_EXP2
52#define I2C_DRIVERID_DVBFE_L64781 I2C_DRIVERID_EXP2
53#define I2C_DRIVERID_DVBFE_MT312 I2C_DRIVERID_EXP2
54#define I2C_DRIVERID_DVBFE_MT352 I2C_DRIVERID_EXP2
55#define I2C_DRIVERID_DVBFE_NXT6000 I2C_DRIVERID_EXP2
56#define I2C_DRIVERID_DVBFE_SP887X I2C_DRIVERID_EXP2
57#define I2C_DRIVERID_DVBFE_STV0299 I2C_DRIVERID_EXP2
58#define I2C_DRIVERID_DVBFE_TDA1004X I2C_DRIVERID_EXP2
59#define I2C_DRIVERID_DVBFE_TDA8083 I2C_DRIVERID_EXP2
60#define I2C_DRIVERID_DVBFE_VES1820 I2C_DRIVERID_EXP2
61#define I2C_DRIVERID_DVBFE_VES1X93 I2C_DRIVERID_EXP2
62#define I2C_DRIVERID_DVBFE_TDA80XX I2C_DRIVERID_EXP2
63
64
65struct dvb_frontend_tune_settings { 43struct dvb_frontend_tune_settings {
66 int min_delay_ms; 44 int min_delay_ms;
67 int step_size; 45 int step_size;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 8aa32f6e447b..612e5b087b1c 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -3,30 +3,35 @@ config DVB_USB
3 depends on DVB_CORE && USB 3 depends on DVB_CORE && USB
4 select FW_LOADER 4 select FW_LOADER
5 help 5 help
6 By enabling this you will be able to choose the various USB 1.1 and 6 By enabling this you will be able to choose the various supported
7 USB2.0 DVB devices. 7 USB1.1 and USB2.0 DVB devices.
8 8
9 Almost every USB device needs a firmware, please look into 9 Almost every USB device needs a firmware, please look into
10 <file:Documentation/dvb/README.dvb-usb> 10 <file:Documentation/dvb/README.dvb-usb>.
11 11
12 Say Y if you own an USB DVB device. 12 For a complete list of supported USB devices see the LinuxTV DVB Wiki:
13 <http://www.linuxtv.org/wiki/index.php/DVB_USB>
14
15 Say Y if you own a USB DVB device.
13 16
14config DVB_USB_DEBUG 17config DVB_USB_DEBUG
15 bool "Enable extended debug support for all DVB-USB devices" 18 bool "Enable extended debug support for all DVB-USB devices"
16 depends on DVB_USB 19 depends on DVB_USB
17 help 20 help
18 Say Y if you want to enable debuging. See modinfo dvb-usb (and the 21 Say Y if you want to enable debugging. See modinfo dvb-usb (and the
19 appropriate drivers) for debug levels. 22 appropriate drivers) for debug levels.
20 23
21config DVB_USB_A800 24config DVB_USB_A800
22 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" 25 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
23 depends on DVB_USB 26 depends on DVB_USB
27 select DVB_DIB3000MC
24 help 28 help
25 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. 29 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
26 30
27config DVB_USB_DIBUSB_MB 31config DVB_USB_DIBUSB_MB
28 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" 32 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
29 depends on DVB_USB 33 depends on DVB_USB
34 select DVB_DIB3000MB
30 help 35 help
31 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by 36 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. 37 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -52,6 +57,7 @@ config DVB_USB_DIBUSB_MB
52config DVB_USB_DIBUSB_MC 57config DVB_USB_DIBUSB_MC
53 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" 58 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
54 depends on DVB_USB 59 depends on DVB_USB
60 select DVB_DIB3000MC
55 help 61 help
56 Support for 2.0 DVB-T receivers based on reference designs made by 62 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. 63 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -66,12 +72,23 @@ config DVB_USB_DIBUSB_MC
66config DVB_USB_UMT_010 72config DVB_USB_UMT_010
67 tristate "HanfTek UMT-010 DVB-T USB2.0 support" 73 tristate "HanfTek UMT-010 DVB-T USB2.0 support"
68 depends on DVB_USB 74 depends on DVB_USB
75 select DVB_DIB3000MC
69 help 76 help
70 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. 77 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
71 78
79config DVB_USB_CXUSB
80 tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
81 depends on DVB_USB
82 select DVB_CX22702
83 help
84 Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
85 only the DVB-T part is supported.
86
72config DVB_USB_DIGITV 87config DVB_USB_DIGITV
73 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" 88 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
74 depends on DVB_USB 89 depends on DVB_USB
90 select DVB_NXT6000
91 select DVB_MT352
75 help 92 help
76 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. 93 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
77 94
@@ -87,13 +104,16 @@ config DVB_USB_VP7045
87config DVB_USB_NOVA_T_USB2 104config DVB_USB_NOVA_T_USB2
88 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" 105 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
89 depends on DVB_USB 106 depends on DVB_USB
107 select DVB_DIB3000MC
90 help 108 help
91 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. 109 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
92 110
93config DVB_USB_DTT200U 111config DVB_USB_DTT200U
94 tristate "Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support" 112 tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
95 depends on DVB_USB 113 depends on DVB_USB
96 help 114 help
97 Say Y here to support the Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver. 115 Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
98 116
99 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). 117 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
118
119 The WT-220U and its clones are pen-sized.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index d65b50f9abb0..746d87ed6f32 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -27,4 +27,7 @@ obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
27dvb-usb-digitv-objs = digitv.o 27dvb-usb-digitv-objs = digitv.o
28obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o 28obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
29 29
30dvb-usb-cxusb-objs = cxusb.o
31obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
32
30EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 33EXTRA_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
index a3542935604f..f2fcc2f1f846 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -61,6 +61,12 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */ 61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
62 { 0x02, 0x04, KEY_EPG }, /* EPG */ 62 { 0x02, 0x04, KEY_EPG }, /* EPG */
63 { 0x02, 0x15, KEY_MENU }, /* MENU */ 63 { 0x02, 0x15, KEY_MENU }, /* MENU */
64
65 { 0x03, 0x03, KEY_CHANNELUP }, /* CH UP */
66 { 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
67 { 0x03, 0x01, KEY_FIRST }, /* |<< / GREEN */
68 { 0x03, 0x00, KEY_LAST }, /* >>| / BLUE */
69
64}; 70};
65 71
66int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 72int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -68,7 +74,7 @@ int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
68 u8 key[5]; 74 u8 key[5];
69 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0), 75 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
70 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5, 76 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
71 2*HZ) != 5) 77 2000) != 5)
72 return -ENODEV; 78 return -ENODEV;
73 79
74 /* call the universal NEC remote processor, to find out the key's state and event */ 80 /* call the universal NEC remote processor, to find out the key's state and event */
@@ -143,7 +149,7 @@ static struct dvb_usb_properties a800_properties = {
143 149
144static struct usb_driver a800_driver = { 150static struct usb_driver a800_driver = {
145 .owner = THIS_MODULE, 151 .owner = THIS_MODULE,
146 .name = "AVerMedia AverTV DVB-T USB 2.0 (A800)", 152 .name = "dvb_usb_a800",
147 .probe = a800_probe, 153 .probe = a800_probe,
148 .disconnect = dvb_usb_device_exit, 154 .disconnect = dvb_usb_device_exit,
149 .id_table = a800_table, 155 .id_table = a800_table,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
new file mode 100644
index 000000000000..c3e1b661aae6
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -0,0 +1,295 @@
1/* DVB USB compliant linux driver for Conexant USB reference design.
2 *
3 * The Conexant reference design I saw on their website was only for analogue
4 * capturing (using the cx25842). The box I took to write this driver (reverse
5 * engineered) is the one labeled Medion MD95700. In addition to the cx25842
6 * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
7 * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
8 *
9 * Maybe it is a little bit premature to call this driver cxusb, but I assume
10 * the USB protocol is identical or at least inherited from the reference
11 * design, so it can be reused for the "analogue-only" device (if it will
12 * appear at all).
13 *
14 * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue
15 * part
16 *
17 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
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, version 2.
22 *
23 * see Documentation/dvb/README.dvb-usb for more information
24 */
25#include "cxusb.h"
26
27#include "cx22702.h"
28
29/* debug */
30int dvb_usb_cxusb_debug;
31module_param_named(debug,dvb_usb_cxusb_debug, int, 0644);
32MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
33
34static int cxusb_ctrl_msg(struct dvb_usb_device *d,
35 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
36{
37 int wo = (rbuf == NULL || rlen == 0); /* write-only */
38 u8 sndbuf[1+wlen];
39 memset(sndbuf,0,1+wlen);
40
41 sndbuf[0] = cmd;
42 memcpy(&sndbuf[1],wbuf,wlen);
43 if (wo)
44 dvb_usb_generic_write(d,sndbuf,1+wlen);
45 else
46 dvb_usb_generic_rw(d,sndbuf,1+wlen,rbuf,rlen,0);
47
48 return 0;
49}
50
51/* I2C */
52static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path)
53{
54 struct cxusb_state *st = d->priv;
55 u8 o[2],i;
56
57 if (path == st->cur_i2c_path)
58 return;
59
60 o[0] = IOCTL_SET_I2C_PATH;
61 switch (path) {
62 case PATH_CX22702:
63 o[1] = 0;
64 break;
65 case PATH_TUNER_OTHER:
66 o[1] = 1;
67 break;
68 default:
69 err("unkown i2c path");
70 return;
71 }
72 cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1);
73
74 if (i != 0x01)
75 deb_info("i2c_path setting failed.\n");
76
77 st->cur_i2c_path = path;
78}
79
80static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
81{
82 struct dvb_usb_device *d = i2c_get_adapdata(adap);
83 int i;
84
85 if (down_interruptible(&d->i2c_sem) < 0)
86 return -EAGAIN;
87
88 if (num > 2)
89 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
90
91 for (i = 0; i < num; i++) {
92
93 switch (msg[i].addr) {
94 case 0x63:
95 cxusb_set_i2c_path(d,PATH_CX22702);
96 break;
97 default:
98 cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
99 break;
100 }
101
102 /* read request */
103 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
104 u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
105 obuf[0] = msg[i].len;
106 obuf[1] = msg[i+1].len;
107 obuf[2] = msg[i].addr;
108 memcpy(&obuf[3],msg[i].buf,msg[i].len);
109
110 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
111 obuf, 3+msg[i].len,
112 ibuf, 1+msg[i+1].len) < 0)
113 break;
114
115 if (ibuf[0] != 0x08)
116 deb_info("i2c read could have been failed\n");
117
118 memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len);
119
120 i++;
121 } else { /* write */
122 u8 obuf[2+msg[i].len], ibuf;
123 obuf[0] = msg[i].addr;
124 obuf[1] = msg[i].len;
125 memcpy(&obuf[2],msg[i].buf,msg[i].len);
126
127 if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0)
128 break;
129 if (ibuf != 0x08)
130 deb_info("i2c write could have been failed\n");
131 }
132 }
133
134 up(&d->i2c_sem);
135 return i;
136}
137
138static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
139{
140 return I2C_FUNC_I2C;
141}
142
143static struct i2c_algorithm cxusb_i2c_algo = {
144 .name = "Conexant USB I2C algorithm",
145 .id = I2C_ALGO_BIT,
146 .master_xfer = cxusb_i2c_xfer,
147 .functionality = cxusb_i2c_func,
148};
149
150static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
151{
152 return 0;
153}
154
155static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
156{
157 u8 buf[2] = { 0x03, 0x00 };
158 if (onoff)
159 cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
160 else
161 cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0);
162
163 return 0;
164}
165
166struct cx22702_config cxusb_cx22702_config = {
167 .demod_address = 0x63,
168
169 .output_mode = CX22702_PARALLEL_OUTPUT,
170
171 .pll_init = dvb_usb_pll_init_i2c,
172 .pll_set = dvb_usb_pll_set_i2c,
173};
174
175/* Callbacks for DVB USB */
176static int cxusb_tuner_attach(struct dvb_usb_device *d)
177{
178 u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
179 d->pll_addr = 0x61;
180 memcpy(d->pll_init,bpll,4);
181 d->pll_desc = &dvb_pll_fmd1216me;
182 return 0;
183}
184
185static int cxusb_frontend_attach(struct dvb_usb_device *d)
186{
187 u8 buf[2] = { 0x03, 0x00 };
188 u8 b = 0;
189
190 if (usb_set_interface(d->udev,0,0) < 0)
191 err("set interface to alts=0 failed");
192
193 cxusb_ctrl_msg(d,0xde,&b,0,NULL,0);
194 cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
195 cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1);
196
197 if (usb_set_interface(d->udev,0,6) < 0)
198 err("set interface failed");
199
200 cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
201 cxusb_set_i2c_path(d,PATH_CX22702);
202 cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1);
203
204 if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
205 return 0;
206
207 return -EIO;
208}
209
210/* DVB USB Driver stuff */
211static struct dvb_usb_properties cxusb_properties;
212
213static int cxusb_probe(struct usb_interface *intf,
214 const struct usb_device_id *id)
215{
216 return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE);
217}
218
219static struct usb_device_id cxusb_table [] = {
220 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
221 {} /* Terminating entry */
222};
223MODULE_DEVICE_TABLE (usb, cxusb_table);
224
225static struct dvb_usb_properties cxusb_properties = {
226 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
227
228 .usb_ctrl = CYPRESS_FX2,
229
230 .size_of_priv = sizeof(struct cxusb_state),
231
232 .streaming_ctrl = cxusb_streaming_ctrl,
233 .power_ctrl = cxusb_power_ctrl,
234 .frontend_attach = cxusb_frontend_attach,
235 .tuner_attach = cxusb_tuner_attach,
236
237 .i2c_algo = &cxusb_i2c_algo,
238
239 .generic_bulk_ctrl_endpoint = 0x01,
240 /* parameter for the MPEG2-data transfer */
241 .urb = {
242 .type = DVB_USB_ISOC,
243 .count = 5,
244 .endpoint = 0x02,
245 .u = {
246 .isoc = {
247 .framesperurb = 32,
248 .framesize = 940,
249 .interval = 5,
250 }
251 }
252 },
253
254 .num_device_descs = 1,
255 .devices = {
256 { "Medion MD95700 (MDUSBTV-HYBRID)",
257 { NULL },
258 { &cxusb_table[0], NULL },
259 },
260 }
261};
262
263static struct usb_driver cxusb_driver = {
264 .owner = THIS_MODULE,
265 .name = "dvb_usb_cxusb",
266 .probe = cxusb_probe,
267 .disconnect = dvb_usb_device_exit,
268 .id_table = cxusb_table,
269};
270
271/* module stuff */
272static int __init cxusb_module_init(void)
273{
274 int result;
275 if ((result = usb_register(&cxusb_driver))) {
276 err("usb_register failed. Error number %d",result);
277 return result;
278 }
279
280 return 0;
281}
282
283static void __exit cxusb_module_exit(void)
284{
285 /* deregister this driver from the USB subsystem */
286 usb_deregister(&cxusb_driver);
287}
288
289module_init (cxusb_module_init);
290module_exit (cxusb_module_exit);
291
292MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
293MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
294MODULE_VERSION("1.0-alpha");
295MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
new file mode 100644
index 000000000000..1d79016e3195
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -0,0 +1,30 @@
1#ifndef _DVB_USB_CXUSB_H_
2#define _DVB_USB_CXUSB_H_
3
4#define DVB_USB_LOG_PREFIX "digitv"
5#include "dvb-usb.h"
6
7extern int dvb_usb_cxusb_debug;
8#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
9
10/* usb commands - some of it are guesses, don't have a reference yet */
11#define CMD_I2C_WRITE 0x08
12#define CMD_I2C_READ 0x09
13
14#define CMD_IOCTL 0x0e
15#define IOCTL_SET_I2C_PATH 0x02
16
17#define CMD_POWER_OFF 0x50
18#define CMD_POWER_ON 0x51
19
20enum cxusb_i2c_pathes {
21 PATH_UNDEF = 0x00,
22 PATH_CX22702 = 0x01,
23 PATH_TUNER_OTHER = 0x02,
24};
25
26struct cxusb_state {
27 enum cxusb_i2c_pathes cur_i2c_path;
28};
29
30#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index a0ffbb59fa14..828b5182e16c 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -31,10 +31,17 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
31 return 0; 31 return 0;
32} 32}
33 33
34/* some of the dibusb 1.1 device aren't equipped with the default tuner 34static int dibusb_thomson_tuner_attach(struct dvb_usb_device *d)
35{
36 d->pll_addr = 0x61;
37 d->pll_desc = &dvb_pll_tua6010xs;
38 return 0;
39}
40
41/* Some of the Artec 1.1 device aren't equipped with the default tuner
35 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures 42 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
36 * this out. */ 43 * this out. */
37static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d) 44static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
38{ 45{
39 u8 b[2] = { 0,0 }, b2[1]; 46 u8 b[2] = { 0,0 }, b2[1];
40 int ret = 0; 47 int ret = 0;
@@ -59,8 +66,7 @@ static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d)
59 66
60 if (b2[0] == 0xfe) { 67 if (b2[0] == 0xfe) {
61 info("this device has the Thomson Cable onboard. Which is default."); 68 info("this device has the Thomson Cable onboard. Which is default.");
62 d->pll_addr = 0x61; 69 dibusb_thomson_tuner_attach(d);
63 d->pll_desc = &dvb_pll_tua6010xs;
64 } else { 70 } else {
65 u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; 71 u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
66 info("this device has the Panasonic ENV77H11D5 onboard."); 72 info("this device has the Panasonic ENV77H11D5 onboard.");
@@ -90,8 +96,8 @@ static int dibusb_probe(struct usb_interface *intf,
90 96
91/* do not change the order of the ID table */ 97/* do not change the order of the ID table */
92static struct usb_device_id dibusb_dib3000mb_table [] = { 98static struct usb_device_id dibusb_dib3000mb_table [] = {
93/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, 99/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
94/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, 100/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
95/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, 101/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
96/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, 102/* 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) }, 103/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
@@ -114,7 +120,17 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
114/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, 120/* 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) }, 121/* 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) }, 122/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
123
124/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
117/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, 125/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
126/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
127/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
128
129// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
130
131#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
132/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
133#endif
118 { } /* Terminating entry */ 134 { } /* Terminating entry */
119}; 135};
120MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); 136MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
@@ -134,7 +150,7 @@ static struct dvb_usb_properties dibusb1_1_properties = {
134 .pid_filter_ctrl = dibusb_pid_filter_ctrl, 150 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
135 .power_ctrl = dibusb_power_ctrl, 151 .power_ctrl = dibusb_power_ctrl,
136 .frontend_attach = dibusb_dib3000mb_frontend_attach, 152 .frontend_attach = dibusb_dib3000mb_frontend_attach,
137 .tuner_attach = dibusb_dib3000mb_tuner_attach, 153 .tuner_attach = dibusb_tuner_probe_and_attach,
138 154
139 .rc_interval = DEFAULT_RC_INTERVAL, 155 .rc_interval = DEFAULT_RC_INTERVAL,
140 .rc_key_map = dibusb_rc_keys, 156 .rc_key_map = dibusb_rc_keys,
@@ -156,7 +172,7 @@ static struct dvb_usb_properties dibusb1_1_properties = {
156 } 172 }
157 }, 173 },
158 174
159 .num_device_descs = 8, 175 .num_device_descs = 9,
160 .devices = { 176 .devices = {
161 { "AVerMedia AverTV DVBT USB1.1", 177 { "AVerMedia AverTV DVBT USB1.1",
162 { &dibusb_dib3000mb_table[0], NULL }, 178 { &dibusb_dib3000mb_table[0], NULL },
@@ -190,11 +206,17 @@ static struct dvb_usb_properties dibusb1_1_properties = {
190 { &dibusb_dib3000mb_table[19], NULL }, 206 { &dibusb_dib3000mb_table[19], NULL },
191 { &dibusb_dib3000mb_table[20], NULL }, 207 { &dibusb_dib3000mb_table[20], NULL },
192 }, 208 },
209 { "VideoWalker DVB-T USB",
210 { &dibusb_dib3000mb_table[25], NULL },
211 { &dibusb_dib3000mb_table[26], NULL },
212 },
193 } 213 }
194}; 214};
195 215
196static struct dvb_usb_properties dibusb1_1_an2235_properties = { 216static 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, 217 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
218 .pid_filter_count = 16,
219
198 .usb_ctrl = CYPRESS_AN2235, 220 .usb_ctrl = CYPRESS_AN2235,
199 221
200 .firmware = "dvb-usb-dibusb-an2235-01.fw", 222 .firmware = "dvb-usb-dibusb-an2235-01.fw",
@@ -206,7 +228,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
206 .pid_filter_ctrl = dibusb_pid_filter_ctrl, 228 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
207 .power_ctrl = dibusb_power_ctrl, 229 .power_ctrl = dibusb_power_ctrl,
208 .frontend_attach = dibusb_dib3000mb_frontend_attach, 230 .frontend_attach = dibusb_dib3000mb_frontend_attach,
209 .tuner_attach = dibusb_dib3000mb_tuner_attach, 231 .tuner_attach = dibusb_tuner_probe_and_attach,
210 232
211 .rc_interval = DEFAULT_RC_INTERVAL, 233 .rc_interval = DEFAULT_RC_INTERVAL,
212 .rc_key_map = dibusb_rc_keys, 234 .rc_key_map = dibusb_rc_keys,
@@ -228,20 +250,32 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
228 } 250 }
229 }, 251 },
230 252
253#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
254 .num_device_descs = 2,
255#else
231 .num_device_descs = 1, 256 .num_device_descs = 1,
257#endif
232 .devices = { 258 .devices = {
233 { "Artec T1 USB1.1 TVBOX with AN2235", 259 { "Artec T1 USB1.1 TVBOX with AN2235",
234 { &dibusb_dib3000mb_table[20], NULL }, 260 { &dibusb_dib3000mb_table[20], NULL },
235 { &dibusb_dib3000mb_table[21], NULL }, 261 { &dibusb_dib3000mb_table[21], NULL },
236 }, 262 },
263#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
264 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
265 { &dibusb_dib3000mb_table[27], NULL },
266 { NULL },
267 },
268#endif
237 } 269 }
238}; 270};
239 271
240static struct dvb_usb_properties dibusb2_0b_properties = { 272static 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, 273 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
274 .pid_filter_count = 32,
275
242 .usb_ctrl = CYPRESS_FX2, 276 .usb_ctrl = CYPRESS_FX2,
243 277
244 .firmware = "dvb-usb-adstech-usb2-01.fw", 278 .firmware = "dvb-usb-adstech-usb2-02.fw",
245 279
246 .size_of_priv = sizeof(struct dibusb_state), 280 .size_of_priv = sizeof(struct dibusb_state),
247 281
@@ -250,7 +284,7 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
250 .pid_filter_ctrl = dibusb_pid_filter_ctrl, 284 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
251 .power_ctrl = dibusb2_0_power_ctrl, 285 .power_ctrl = dibusb2_0_power_ctrl,
252 .frontend_attach = dibusb_dib3000mb_frontend_attach, 286 .frontend_attach = dibusb_dib3000mb_frontend_attach,
253 .tuner_attach = dibusb_dib3000mb_tuner_attach, 287 .tuner_attach = dibusb_thomson_tuner_attach,
254 288
255 .rc_interval = DEFAULT_RC_INTERVAL, 289 .rc_interval = DEFAULT_RC_INTERVAL,
256 .rc_key_map = dibusb_rc_keys, 290 .rc_key_map = dibusb_rc_keys,
@@ -272,18 +306,18 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
272 } 306 }
273 }, 307 },
274 308
275 .num_device_descs = 2, 309 .num_device_descs = 1,
276 .devices = { 310 .devices = {
277 { "KWorld/ADSTech Instant DVB-T USB 2.0", 311 { "KWorld/ADSTech Instant DVB-T USB 2.0",
278 { &dibusb_dib3000mb_table[23], NULL }, 312 { &dibusb_dib3000mb_table[23], NULL },
279 { &dibusb_dib3000mb_table[24], NULL }, /* device ID with default DIBUSB2_0-firmware */ 313 { &dibusb_dib3000mb_table[24], NULL },
280 }, 314 },
281 } 315 }
282}; 316};
283 317
284static struct usb_driver dibusb_driver = { 318static struct usb_driver dibusb_driver = {
285 .owner = THIS_MODULE, 319 .owner = THIS_MODULE,
286 .name = "DiBcom based USB DVB-T devices (DiB3000M-B based)", 320 .name = "dvb_usb_dibusb_mb",
287 .probe = dibusb_probe, 321 .probe = dibusb_probe,
288 .disconnect = dvb_usb_device_exit, 322 .disconnect = dvb_usb_device_exit,
289 .id_table = dibusb_dib3000mb_table, 323 .id_table = dibusb_dib3000mb_table,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index aad8ed3fe005..e9dac430f37d 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -83,7 +83,7 @@ static struct dvb_usb_properties dibusb_mc_properties = {
83 83
84static struct usb_driver dibusb_mc_driver = { 84static struct usb_driver dibusb_mc_driver = {
85 .owner = THIS_MODULE, 85 .owner = THIS_MODULE,
86 .name = "DiBcom based USB2.0 DVB-T (DiB3000M-C/P based) devices", 86 .name = "dvb_usb_dibusb_mc",
87 .probe = dibusb_mc_probe, 87 .probe = dibusb_mc_probe,
88 .disconnect = dvb_usb_device_exit, 88 .disconnect = dvb_usb_device_exit,
89 .id_table = dibusb_dib3000mc_table, 89 .id_table = dibusb_dib3000mc_table,
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 5acf3fde9522..9a676afc1d6e 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -1,10 +1,9 @@
1/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0 1/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
2 * receiver 2 * receiver
3 * 3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) and 4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 * Allan Third (allan.third@cs.man.ac.uk)
6 * 5 *
7 * partly based on the SDK published by Nebula Electronics (TODO do we want this line ?) 6 * partly based on the SDK published by Nebula Electronics
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify it 8 * 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 9 * under the terms of the GNU General Public License as published by the Free
@@ -38,7 +37,7 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d,
38 dvb_usb_generic_write(d,sndbuf,7); 37 dvb_usb_generic_write(d,sndbuf,7);
39 } else { 38 } else {
40 dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10); 39 dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
41 memcpy(&rbuf,&rcvbuf[3],rlen); 40 memcpy(rbuf,&rcvbuf[3],rlen);
42 } 41 }
43 return 0; 42 return 0;
44} 43}
@@ -95,41 +94,20 @@ static int digitv_identify_state (struct usb_device *udev, struct
95 94
96static int digitv_mt352_demod_init(struct dvb_frontend *fe) 95static int digitv_mt352_demod_init(struct dvb_frontend *fe)
97{ 96{
98 static u8 mt352_clock_config[] = { 0x89, 0x38, 0x2d }; 97 static u8 reset_buf[] = { 0x89, 0x38, 0x8a, 0x2d, 0x50, 0x80 };
99 static u8 mt352_reset[] = { 0x50, 0x80 }; 98 static u8 init_buf[] = { 0x68, 0xa0, 0x8e, 0x40, 0x53, 0x50,
100 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; 99 0x67, 0x20, 0x7d, 0x01, 0x7c, 0x00, 0x7a, 0x00,
101 100 0x79, 0x20, 0x57, 0x05, 0x56, 0x31, 0x88, 0x0f,
102 static u8 mt352_agc_cfg[] = { 0x68, 0xa0 }; 101 0x75, 0x32 };
103 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0xa0 }; 102 int i;
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 103
112 static u8 mt352_scan_ctl[] = { 0x88, 0x0f }; 104 for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
113 static u8 mt352_capt_range[] = { 0x75, 0x32 }; 105 mt352_write(fe, &reset_buf[i], 2);
114 106
115 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
116 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
117 msleep(1); 107 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 108
129 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); 109 for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
130 110 mt352_write(fe, &init_buf[i], 2);
131 mt352_write(fe, mt352_scan_ctl, sizeof(mt352_scan_ctl));
132 mt352_write(fe, mt352_capt_range, sizeof(mt352_capt_range));
133 111
134 return 0; 112 return 0;
135} 113}
@@ -137,7 +115,7 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe)
137static struct mt352_config digitv_mt352_config = { 115static struct mt352_config digitv_mt352_config = {
138 .demod_address = 0x0, /* ignored by the digitv anyway */ 116 .demod_address = 0x0, /* ignored by the digitv anyway */
139 .demod_init = digitv_mt352_demod_init, 117 .demod_init = digitv_mt352_demod_init,
140 .pll_set = NULL, /* TODO */ 118 .pll_set = dvb_usb_pll_set,
141}; 119};
142 120
143static struct nxt6000_config digitv_nxt6000_config = { 121static struct nxt6000_config digitv_nxt6000_config = {
@@ -150,9 +128,9 @@ static struct nxt6000_config digitv_nxt6000_config = {
150 128
151static int digitv_frontend_attach(struct dvb_usb_device *d) 129static int digitv_frontend_attach(struct dvb_usb_device *d)
152{ 130{
153 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) == NULL) 131 if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL)
154 return 0; 132 return 0;
155 if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) == NULL) { 133 if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
156 134
157 warn("nxt6000 support is not done yet, in fact you are one of the first " 135 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 " 136 "person who wants to use this device in Linux. Please report to "
@@ -163,6 +141,13 @@ static int digitv_frontend_attach(struct dvb_usb_device *d)
163 return -EIO; 141 return -EIO;
164} 142}
165 143
144static int digitv_tuner_attach(struct dvb_usb_device *d)
145{
146 d->pll_addr = 0x60;
147 d->pll_desc = &dvb_pll_tded4;
148 return 0;
149}
150
166static struct dvb_usb_rc_key digitv_rc_keys[] = { 151static struct dvb_usb_rc_key digitv_rc_keys[] = {
167 { 0x00, 0x16, KEY_POWER }, /* dummy key */ 152 { 0x00, 0x16, KEY_POWER }, /* dummy key */
168}; 153};
@@ -184,7 +169,6 @@ int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
184 return 0; 169 return 0;
185} 170}
186 171
187
188/* DVB USB Driver stuff */ 172/* DVB USB Driver stuff */
189static struct dvb_usb_properties digitv_properties; 173static struct dvb_usb_properties digitv_properties;
190 174
@@ -208,13 +192,8 @@ static struct dvb_usb_properties digitv_properties = {
208 192
209 .size_of_priv = 0, 193 .size_of_priv = 0,
210 194
211 .streaming_ctrl = NULL,
212 .pid_filter = NULL,
213 .pid_filter_ctrl = NULL,
214 .power_ctrl = NULL,
215 .frontend_attach = digitv_frontend_attach, 195 .frontend_attach = digitv_frontend_attach,
216 .tuner_attach = NULL, // digitv_tuner_attach, 196 .tuner_attach = digitv_tuner_attach,
217 .read_mac_address = NULL,
218 197
219 .rc_interval = 1000, 198 .rc_interval = 1000,
220 .rc_key_map = digitv_rc_keys, 199 .rc_key_map = digitv_rc_keys,
@@ -238,7 +217,7 @@ static struct dvb_usb_properties digitv_properties = {
238 } 217 }
239 }, 218 },
240 219
241 .num_device_descs = 2, 220 .num_device_descs = 1,
242 .devices = { 221 .devices = {
243 { "Nebula Electronics uDigiTV DVB-T USB2.0)", 222 { "Nebula Electronics uDigiTV DVB-T USB2.0)",
244 { &digitv_table[0], NULL }, 223 { &digitv_table[0], NULL },
@@ -249,7 +228,7 @@ static struct dvb_usb_properties digitv_properties = {
249 228
250static struct usb_driver digitv_driver = { 229static struct usb_driver digitv_driver = {
251 .owner = THIS_MODULE, 230 .owner = THIS_MODULE,
252 .name = "Nebula Electronics uDigiTV DVB-T USB2.0 device", 231 .name = "dvb_usb_digitv",
253 .probe = digitv_probe, 232 .probe = digitv_probe,
254 .disconnect = dvb_usb_device_exit, 233 .disconnect = dvb_usb_device_exit,
255 .id_table = digitv_table, 234 .id_table = digitv_table,
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index d17d768038c6..b032523b07bc 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -1,5 +1,5 @@
1/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T 1/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
2 * USB2.0 receiver. 2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 * 3 *
4 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de> 4 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
5 * 5 *
@@ -14,61 +14,58 @@
14struct dtt200u_fe_state { 14struct dtt200u_fe_state {
15 struct dvb_usb_device *d; 15 struct dvb_usb_device *d;
16 16
17 fe_status_t stat;
18
17 struct dvb_frontend_parameters fep; 19 struct dvb_frontend_parameters fep;
18 struct dvb_frontend frontend; 20 struct dvb_frontend frontend;
19}; 21};
20 22
21#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)
22
23static 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)
24{ 24{
25 struct dtt200u_fe_state *state = fe->demodulator_priv; 25 struct dtt200u_fe_state *state = fe->demodulator_priv;
26 u8 bw = GET_TUNE_STAT; 26 u8 st = GET_TUNE_STATUS, b[3];
27 u8 br[3] = { 0 }; 27
28// u8 bdeb[5] = { 0 }; 28 dvb_usb_generic_rw(state->d,&st,1,b,3,0);
29 29
30 dvb_usb_generic_rw(state->d,&bw,1,br,3,0); 30 switch (b[0]) {
31 switch (br[0]) {
32 case 0x01: 31 case 0x01:
33 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 32 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
33 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
34 break; 34 break;
35 case 0x00: 35 case 0x00: /* pending */
36 *stat = 0; 36 *stat = FE_TIMEDOUT; /* during set_frontend */
37 break; 37 break;
38 default: 38 default:
39 moan("br[0]",GET_TUNE_STAT); 39 case 0x02: /* failed */
40 *stat = 0;
40 break; 41 break;
41 } 42 }
42
43// bw[0] = 0x88;
44// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0);
45
46// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
47
48 return 0; 43 return 0;
49} 44}
45
50static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber) 46static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
51{ 47{
52 struct dtt200u_fe_state *state = fe->demodulator_priv; 48 struct dtt200u_fe_state *state = fe->demodulator_priv;
53 u8 bw = GET_BER; 49 u8 bw = GET_VIT_ERR_CNT,b[3];
54 *ber = 0; 50 dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
55 dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0); 51 *ber = (b[0] << 16) | (b[1] << 8) | b[2];
56 return 0; 52 return 0;
57} 53}
58 54
59static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) 55static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
60{ 56{
61 struct dtt200u_fe_state *state = fe->demodulator_priv; 57 struct dtt200u_fe_state *state = fe->demodulator_priv;
62 u8 bw = GET_UNK; 58 u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
63 *unc = 0; 59
64 dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0); 60 dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
61 *unc = (b[0] << 8) | b[1];
65 return 0; 62 return 0;
66} 63}
67 64
68static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) 65static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
69{ 66{
70 struct dtt200u_fe_state *state = fe->demodulator_priv; 67 struct dtt200u_fe_state *state = fe->demodulator_priv;
71 u8 bw = GET_SIG_STRENGTH, b; 68 u8 bw = GET_AGC, b;
72 dvb_usb_generic_rw(state->d,&bw,1,&b,1,0); 69 dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
73 *strength = (b << 8) | b; 70 *strength = (b << 8) | b;
74 return 0; 71 return 0;
@@ -86,7 +83,7 @@ static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
86static int dtt200u_fe_init(struct dvb_frontend* fe) 83static int dtt200u_fe_init(struct dvb_frontend* fe)
87{ 84{
88 struct dtt200u_fe_state *state = fe->demodulator_priv; 85 struct dtt200u_fe_state *state = fe->demodulator_priv;
89 u8 b = RESET_DEMOD; 86 u8 b = SET_INIT;
90 return dvb_usb_generic_write(state->d,&b,1); 87 return dvb_usb_generic_write(state->d,&b,1);
91} 88}
92 89
@@ -98,8 +95,8 @@ static int dtt200u_fe_sleep(struct dvb_frontend* fe)
98static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 95static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
99{ 96{
100 tune->min_delay_ms = 1500; 97 tune->min_delay_ms = 1500;
101 tune->step_size = 166667; 98 tune->step_size = 0;
102 tune->max_drift = 166667 * 2; 99 tune->max_drift = 0;
103 return 0; 100 return 0;
104} 101}
105 102
@@ -107,27 +104,32 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
107 struct dvb_frontend_parameters *fep) 104 struct dvb_frontend_parameters *fep)
108{ 105{
109 struct dtt200u_fe_state *state = fe->demodulator_priv; 106 struct dtt200u_fe_state *state = fe->demodulator_priv;
107 int i;
108 fe_status_t st;
110 u16 freq = fep->frequency / 250000; 109 u16 freq = fep->frequency / 250000;
111 u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 }; 110 u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
112 111
113 switch (fep->u.ofdm.bandwidth) { 112 switch (fep->u.ofdm.bandwidth) {
114 case BANDWIDTH_8_MHZ: bw = 8; break; 113 case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break;
115 case BANDWIDTH_7_MHZ: bw = 7; break; 114 case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break;
116 case BANDWIDTH_6_MHZ: bw = 6; break; 115 case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break;
117 case BANDWIDTH_AUTO: return -EOPNOTSUPP; 116 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
118 default: 117 default:
119 return -EINVAL; 118 return -EINVAL;
120 } 119 }
121 deb_info("set_frontend\n");
122 120
123 bwbuf[1] = bw;
124 dvb_usb_generic_write(state->d,bwbuf,2); 121 dvb_usb_generic_write(state->d,bwbuf,2);
125 122
126 freqbuf[1] = freq & 0xff; 123 freqbuf[1] = freq & 0xff;
127 freqbuf[2] = (freq >> 8) & 0xff; 124 freqbuf[2] = (freq >> 8) & 0xff;
128 dvb_usb_generic_write(state->d,freqbuf,3); 125 dvb_usb_generic_write(state->d,freqbuf,3);
129 126
130 memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters)); 127 for (i = 0; i < 30; i++) {
128 msleep(20);
129 dtt200u_fe_read_status(fe, &st);
130 if (st & FE_TIMEDOUT)
131 continue;
132 }
131 133
132 return 0; 134 return 0;
133} 135}
@@ -174,7 +176,7 @@ success:
174 176
175static struct dvb_frontend_ops dtt200u_fe_ops = { 177static struct dvb_frontend_ops dtt200u_fe_ops = {
176 .info = { 178 .info = {
177 .name = "DTT200U (Yakumo/Typhoon/Hama) DVB-T", 179 .name = "WideView USB DVB-T",
178 .type = FE_OFDM, 180 .type = FE_OFDM,
179 .frequency_min = 44250000, 181 .frequency_min = 44250000,
180 .frequency_max = 867250000, 182 .frequency_max = 867250000,
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index fb2b5a2da137..47dba6e45968 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -1,8 +1,10 @@
1/* DVB USB library compliant Linux driver for the Yakumo/Hama/Typhoon DVB-T 1/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
2 * USB2.0 receiver. 2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 * 3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 * 5 *
6 * Thanks to Steve Chang from WideView for providing support for the WT-220U.
7 *
6 * This program is free software; you can redistribute it and/or modify it 8 * 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 9 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2. 10 * Software Foundation, version 2.
@@ -16,14 +18,24 @@ int dvb_usb_dtt200u_debug;
16module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); 18module_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); 19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
18 20
21static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
22{
23 u8 b = SET_INIT;
24
25 if (onoff)
26 dvb_usb_generic_write(d,&b,2);
27
28 return 0;
29}
30
19static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff) 31static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
20{ 32{
21 u8 b_streaming[2] = { SET_TS_CTRL, onoff }; 33 u8 b_streaming[2] = { SET_STREAMING, onoff };
22 u8 b_rst_pid = RESET_PID_FILTER; 34 u8 b_rst_pid = RESET_PID_FILTER;
23 35
24 dvb_usb_generic_write(d,b_streaming,2); 36 dvb_usb_generic_write(d,b_streaming,2);
25 37
26 if (!onoff) 38 if (onoff == 0)
27 dvb_usb_generic_write(d,&b_rst_pid,1); 39 dvb_usb_generic_write(d,&b_rst_pid,1);
28 return 0; 40 return 0;
29} 41}
@@ -36,7 +48,7 @@ static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int
36 b_pid[0] = SET_PID_FILTER; 48 b_pid[0] = SET_PID_FILTER;
37 b_pid[1] = index; 49 b_pid[1] = index;
38 b_pid[2] = pid & 0xff; 50 b_pid[2] = pid & 0xff;
39 b_pid[3] = (pid >> 8) & 0xff; 51 b_pid[3] = (pid >> 8) & 0x1f;
40 52
41 return dvb_usb_generic_write(d,b_pid,4); 53 return dvb_usb_generic_write(d,b_pid,4);
42} 54}
@@ -54,9 +66,9 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
54 { 0x80, 0x08, KEY_5 }, 66 { 0x80, 0x08, KEY_5 },
55 { 0x80, 0x09, KEY_6 }, 67 { 0x80, 0x09, KEY_6 },
56 { 0x80, 0x0a, KEY_7 }, 68 { 0x80, 0x0a, KEY_7 },
57 { 0x00, 0x0c, KEY_ZOOM }, 69 { 0x80, 0x0c, KEY_ZOOM },
58 { 0x80, 0x0d, KEY_0 }, 70 { 0x80, 0x0d, KEY_0 },
59 { 0x00, 0x0e, KEY_SELECT }, 71 { 0x80, 0x0e, KEY_SELECT },
60 { 0x80, 0x12, KEY_POWER }, 72 { 0x80, 0x12, KEY_POWER },
61 { 0x80, 0x1a, KEY_CHANNELUP }, 73 { 0x80, 0x1a, KEY_CHANNELUP },
62 { 0x80, 0x1b, KEY_8 }, 74 { 0x80, 0x1b, KEY_8 },
@@ -66,7 +78,7 @@ static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
66 78
67static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 79static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
68{ 80{
69 u8 key[5],cmd = GET_RC_KEY; 81 u8 key[5],cmd = GET_RC_CODE;
70 dvb_usb_generic_rw(d,&cmd,1,key,5,0); 82 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
71 dvb_usb_nec_rc_key_to_event(d,key,event,state); 83 dvb_usb_nec_rc_key_to_event(d,key,event,state);
72 if (key[0] != 0) 84 if (key[0] != 0)
@@ -81,32 +93,41 @@ static int dtt200u_frontend_attach(struct dvb_usb_device *d)
81} 93}
82 94
83static struct dvb_usb_properties dtt200u_properties; 95static struct dvb_usb_properties dtt200u_properties;
96static struct dvb_usb_properties wt220u_properties;
84 97
85static int dtt200u_usb_probe(struct usb_interface *intf, 98static int dtt200u_usb_probe(struct usb_interface *intf,
86 const struct usb_device_id *id) 99 const struct usb_device_id *id)
87{ 100{
88 return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE); 101 if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 ||
102 dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0)
103 return 0;
104
105 return -ENODEV;
89} 106}
90 107
91static struct usb_device_id dtt200u_usb_table [] = { 108static struct usb_device_id dtt200u_usb_table [] = {
92 { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_COLD) }, 109// { USB_DEVICE(0x04b4,0x8613) },
93 { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_WARM) }, 110 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
111 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
112 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
113 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
94 { 0 }, 114 { 0 },
95}; 115};
96MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); 116MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
97 117
98static struct dvb_usb_properties dtt200u_properties = { 118static struct dvb_usb_properties dtt200u_properties = {
99 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, 119 .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 */ 120 .pid_filter_count = 15,
101 121
102 .usb_ctrl = CYPRESS_FX2, 122 .usb_ctrl = CYPRESS_FX2,
103 .firmware = "dvb-usb-dtt200u-01.fw", 123 .firmware = "dvb-usb-dtt200u-01.fw",
104 124
125 .power_ctrl = dtt200u_power_ctrl,
105 .streaming_ctrl = dtt200u_streaming_ctrl, 126 .streaming_ctrl = dtt200u_streaming_ctrl,
106 .pid_filter = dtt200u_pid_filter, 127 .pid_filter = dtt200u_pid_filter,
107 .frontend_attach = dtt200u_frontend_attach, 128 .frontend_attach = dtt200u_frontend_attach,
108 129
109 .rc_interval = 200, 130 .rc_interval = 300,
110 .rc_key_map = dtt200u_rc_keys, 131 .rc_key_map = dtt200u_rc_keys,
111 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 132 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
112 .rc_query = dtt200u_rc_query, 133 .rc_query = dtt200u_rc_query,
@@ -127,18 +148,59 @@ static struct dvb_usb_properties dtt200u_properties = {
127 148
128 .num_device_descs = 1, 149 .num_device_descs = 1,
129 .devices = { 150 .devices = {
130 { .name = "Yakumo/Hama/Typhoon DVB-T USB2.0)", 151 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
131 .cold_ids = { &dtt200u_usb_table[0], &dtt200u_usb_table[2] }, 152 .cold_ids = { &dtt200u_usb_table[0], NULL },
132 .warm_ids = { &dtt200u_usb_table[1], NULL }, 153 .warm_ids = { &dtt200u_usb_table[1], NULL },
133 }, 154 },
134 { 0 }, 155 { 0 },
135 } 156 }
136}; 157};
137 158
159static struct dvb_usb_properties wt220u_properties = {
160 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
161 .pid_filter_count = 15,
162
163 .usb_ctrl = CYPRESS_FX2,
164 .firmware = "dvb-usb-wt220u-01.fw",
165
166 .power_ctrl = dtt200u_power_ctrl,
167 .streaming_ctrl = dtt200u_streaming_ctrl,
168 .pid_filter = dtt200u_pid_filter,
169 .frontend_attach = dtt200u_frontend_attach,
170
171 .rc_interval = 300,
172 .rc_key_map = dtt200u_rc_keys,
173 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
174 .rc_query = dtt200u_rc_query,
175
176 .generic_bulk_ctrl_endpoint = 0x01,
177
178 /* parameter for the MPEG2-data transfer */
179 .urb = {
180 .type = DVB_USB_BULK,
181 .count = 7,
182 .endpoint = 0x02,
183 .u = {
184 .bulk = {
185 .buffersize = 4096,
186 }
187 }
188 },
189
190 .num_device_descs = 1,
191 .devices = {
192 { .name = "WideView WT-220U PenType Receiver (and clones)",
193 .cold_ids = { &dtt200u_usb_table[2], NULL },
194 .warm_ids = { &dtt200u_usb_table[3], NULL },
195 },
196 { 0 },
197 }
198};
199
138/* usb specific object needed to register this driver with the usb subsystem */ 200/* usb specific object needed to register this driver with the usb subsystem */
139static struct usb_driver dtt200u_usb_driver = { 201static struct usb_driver dtt200u_usb_driver = {
140 .owner = THIS_MODULE, 202 .owner = THIS_MODULE,
141 .name = "Yakumo/Hama/Typhoon DVB-T USB2.0", 203 .name = "dvb_usb_dtt200u",
142 .probe = dtt200u_usb_probe, 204 .probe = dtt200u_usb_probe,
143 .disconnect = dvb_usb_device_exit, 205 .disconnect = dvb_usb_device_exit,
144 .id_table = dtt200u_usb_table, 206 .id_table = dtt200u_usb_table,
@@ -166,6 +228,6 @@ module_init(dtt200u_usb_module_init);
166module_exit(dtt200u_usb_module_exit); 228module_exit(dtt200u_usb_module_exit);
167 229
168MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); 230MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
169MODULE_DESCRIPTION("Driver for the Yakumo/Hama/Typhoon DVB-T USB2.0 device"); 231MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices");
170MODULE_VERSION("1.0"); 232MODULE_VERSION("1.0");
171MODULE_LICENSE("GPL"); 233MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
index ed4142071518..6f1f3042e21a 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.h
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -1,5 +1,5 @@
1/* Common header file of Linux driver for the Yakumo/Hama/Typhoon DVB-T 1/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
2 * USB2.0 receiver. 2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 * 3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 * 5 *
@@ -22,44 +22,34 @@ extern int dvb_usb_dtt200u_debug;
22/* guessed protocol description (reverse engineered): 22/* guessed protocol description (reverse engineered):
23 * read 23 * read
24 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1 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) 25 * 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 */ 26 */
37 27
38#define GET_SPEED 0x00 28#define GET_SPEED 0x00
39#define GET_TUNE_STAT 0x81 29#define GET_TUNE_STATUS 0x81
40#define GET_RC_KEY 0x84 30#define GET_RC_CODE 0x84
41#define GET_STATUS 0x88 31#define GET_CONFIGURATION 0x88
42#define GET_SNR 0x89 32#define GET_AGC 0x89
43#define GET_SIG_STRENGTH 0x8a 33#define GET_SNR 0x8a
44#define GET_UNK 0x8c 34#define GET_VIT_ERR_CNT 0x8c
45#define GET_BER 0x8d 35#define GET_RS_ERR_CNT 0x8d
46#define GET_UNC 0x8e 36#define GET_RS_UNCOR_BLK_CNT 0x8e
47 37
48/* write 38/* write
49 * 01 - reset the demod 39 * 01 - init
50 * 02 - frequency (divided by 250000) 40 * 02 - frequency (divided by 250000)
51 * 03 - bandwidth 41 * 03 - bandwidth
52 * 04 - pid table (index pid(7:0) pid(12:8)) 42 * 04 - pid table (index pid(7:0) pid(12:8))
53 * 05 - reset the pid table 43 * 05 - reset the pid table
54 * 08 - demod transfer enabled or not (FX2 transfer is enabled by default) 44 * 08 - transfer switch
55 */ 45 */
56 46
57#define RESET_DEMOD 0x01 47#define SET_INIT 0x01
58#define SET_FREQUENCY 0x02 48#define SET_RF_FREQ 0x02
59#define SET_BANDWIDTH 0x03 49#define SET_BANDWIDTH 0x03
60#define SET_PID_FILTER 0x04 50#define SET_PID_FILTER 0x04
61#define RESET_PID_FILTER 0x05 51#define RESET_PID_FILTER 0x05
62#define SET_TS_CTRL 0x08 52#define SET_STREAMING 0x08
63 53
64extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); 54extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
65 55
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
index 67e0d73fbceb..7300489d3e24 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -12,14 +12,16 @@
12#include "dvb-usb.h" 12#include "dvb-usb.h"
13 13
14extern int dvb_usb_debug; 14extern int dvb_usb_debug;
15extern int dvb_usb_disable_rc_polling;
15 16
16#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args) 17#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
17#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args) 18#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
18#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args) 19#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
19#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args) 20#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args)
20#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args) 21#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args)
21#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args) 22#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args)
22#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args) 23#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args)
24#define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args)
23 25
24/* commonly used methods */ 26/* commonly used methods */
25extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); 27extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index bcb34191868b..794d513a8480 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -12,7 +12,7 @@
12/* Vendor IDs */ 12/* Vendor IDs */
13#define USB_VID_ADSTECH 0x06e1 13#define USB_VID_ADSTECH 0x06e1
14#define USB_VID_ANCHOR 0x0547 14#define USB_VID_ANCHOR 0x0547
15#define USB_VID_AVERMEDIA_UNK 0x14aa 15#define USB_VID_WIDEVIEW 0x14aa
16#define USB_VID_AVERMEDIA 0x07ca 16#define USB_VID_AVERMEDIA 0x07ca
17#define USB_VID_COMPRO 0x185b 17#define USB_VID_COMPRO 0x185b
18#define USB_VID_COMPRO_UNK 0x145f 18#define USB_VID_COMPRO_UNK 0x145f
@@ -24,6 +24,8 @@
24#define USB_VID_HANFTEK 0x15f4 24#define USB_VID_HANFTEK 0x15f4
25#define USB_VID_HAUPPAUGE 0x2040 25#define USB_VID_HAUPPAUGE 0x2040
26#define USB_VID_HYPER_PALTEK 0x1025 26#define USB_VID_HYPER_PALTEK 0x1025
27#define USB_VID_KYE 0x0458
28#define USB_VID_MEDION 0x1660
27#define USB_VID_VISIONPLUS 0x13d3 29#define USB_VID_VISIONPLUS 0x13d3
28#define USB_VID_TWINHAN 0x1822 30#define USB_VID_TWINHAN 0x1822
29#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 31#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
@@ -70,6 +72,8 @@
70#define USB_PID_HANFTEK_UMT_010_WARM 0x0015 72#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
71#define USB_PID_DTT200U_COLD 0x0201 73#define USB_PID_DTT200U_COLD 0x0201
72#define USB_PID_DTT200U_WARM 0x0301 74#define USB_PID_DTT200U_WARM 0x0301
75#define USB_PID_WT220U_COLD 0x0222
76#define USB_PID_WT220U_WARM 0x0221
73#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 77#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
74#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 78#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
75#define USB_PID_NEBULA_DIGITV 0x0201 79#define USB_PID_NEBULA_DIGITV 0x0201
@@ -78,6 +82,8 @@
78#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 82#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
79#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 83#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01
80#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 84#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11
81 85#define USB_PID_MEDION_MD95700 0x0932
86#define USB_PID_KYE_DVB_T_COLD 0x701e
87#define USB_PID_KYE_DVB_T_WARM 0x701f
82 88
83#endif 89#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 3aadec974cf1..c3b3ae4f3ec7 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -18,6 +18,10 @@ int dvb_usb_debug;
18module_param_named(debug,dvb_usb_debug, int, 0644); 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); 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 20
21int dvb_usb_disable_rc_polling;
22module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
23MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
24
21/* general initialization functions */ 25/* general initialization functions */
22int dvb_usb_exit(struct dvb_usb_device *d) 26int dvb_usb_exit(struct dvb_usb_device *d)
23{ 27{
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 9f1e23f82bae..fc7800f1743e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -21,6 +21,10 @@ static void dvb_usb_read_remote_control(void *data)
21 /* TODO: need a lock here. We can simply skip checking for the remote control 21 /* TODO: need a lock here. We can simply skip checking for the remote control
22 if we're busy. */ 22 if we're busy. */
23 23
24 /* when the parameter has been set to 1 via sysfs while the driver was running */
25 if (dvb_usb_disable_rc_polling)
26 return;
27
24 if (d->props.rc_query(d,&event,&state)) { 28 if (d->props.rc_query(d,&event,&state)) {
25 err("error while querying for an remote control event."); 29 err("error while querying for an remote control event.");
26 goto schedule; 30 goto schedule;
@@ -35,7 +39,7 @@ static void dvb_usb_read_remote_control(void *data)
35 d->last_event = event; 39 d->last_event = event;
36 case REMOTE_KEY_REPEAT: 40 case REMOTE_KEY_REPEAT:
37 deb_rc("key repeated\n"); 41 deb_rc("key repeated\n");
38 input_event(&d->rc_input_dev, EV_KEY, event, 1); 42 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
39 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0); 43 input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
40 input_sync(&d->rc_input_dev); 44 input_sync(&d->rc_input_dev);
41 break; 45 break;
@@ -85,7 +89,9 @@ schedule:
85int dvb_usb_remote_init(struct dvb_usb_device *d) 89int dvb_usb_remote_init(struct dvb_usb_device *d)
86{ 90{
87 int i; 91 int i;
88 if (d->props.rc_key_map == NULL) 92 if (d->props.rc_key_map == NULL ||
93 d->props.rc_query == NULL ||
94 dvb_usb_disable_rc_polling)
89 return 0; 95 return 0;
90 96
91 /* Initialise the remote-control structures.*/ 97 /* Initialise the remote-control structures.*/
@@ -154,12 +160,12 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
154 break; 160 break;
155 } 161 }
156 /* See if we can match the raw key code. */ 162 /* See if we can match the raw key code. */
157 for (i = 0; i < sizeof(keymap)/sizeof(struct dvb_usb_rc_key); i++) 163 for (i = 0; i < d->props.rc_key_map_size; i++)
158 if (keymap[i].custom == keybuf[1] && 164 if (keymap[i].custom == keybuf[1] &&
159 keymap[i].data == keybuf[3]) { 165 keymap[i].data == keybuf[3]) {
160 *event = keymap[i].event; 166 *event = keymap[i].event;
161 *state = REMOTE_KEY_PRESSED; 167 *state = REMOTE_KEY_PRESSED;
162 break; 168 return 0;
163 } 169 }
164 deb_err("key mapping failed - no appropriate key found in keymapping\n"); 170 deb_err("key mapping failed - no appropriate key found in keymapping\n");
165 break; 171 break;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index 83d476fb410a..f5799a4c228e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -24,11 +24,12 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
24 if ((ret = down_interruptible(&d->usb_sem))) 24 if ((ret = down_interruptible(&d->usb_sem)))
25 return ret; 25 return ret;
26 26
27 deb_xfer(">>> ");
27 debug_dump(wbuf,wlen,deb_xfer); 28 debug_dump(wbuf,wlen,deb_xfer);
28 29
29 ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev, 30 ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
30 d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen, 31 d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
31 2*HZ); 32 2000);
32 33
33 if (ret) 34 if (ret)
34 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen); 35 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
@@ -42,12 +43,14 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
42 43
43 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev, 44 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
44 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen, 45 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
45 2*HZ); 46 2000);
46 47
47 if (ret) 48 if (ret)
48 err("recv bulk message failed: %d",ret); 49 err("recv bulk message failed: %d",ret);
49 else 50 else {
51 deb_xfer("<<< ");
50 debug_dump(rbuf,actlen,deb_xfer); 52 debug_dump(rbuf,actlen,deb_xfer);
53 }
51 } 54 }
52 55
53 up(&d->usb_sem); 56 up(&d->usb_sem);
@@ -61,12 +64,19 @@ int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
61} 64}
62EXPORT_SYMBOL(dvb_usb_generic_write); 65EXPORT_SYMBOL(dvb_usb_generic_write);
63 66
64static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs) 67
68/* URB stuff for streaming */
69static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
65{ 70{
66 struct dvb_usb_device *d = urb->context; 71 struct dvb_usb_device *d = urb->context;
72 int ptype = usb_pipetype(urb->pipe);
73 int i;
74 u8 *b;
67 75
68 deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status, 76 deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
69 urb->actual_length); 77 ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
78 urb->status,urb->actual_length,urb->transfer_buffer_length,
79 urb->number_of_packets,urb->error_count);
70 80
71 switch (urb->status) { 81 switch (urb->status) {
72 case 0: /* success */ 82 case 0: /* success */
@@ -81,11 +91,33 @@ static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs)
81 break; 91 break;
82 } 92 }
83 93
84 if (d->feedcount > 0 && urb->actual_length > 0) { 94 if (d->feedcount > 0) {
85 if (d->state & DVB_USB_STATE_DVB) 95 if (d->state & DVB_USB_STATE_DVB) {
86 dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length); 96 switch (ptype) {
87 } else 97 case PIPE_ISOCHRONOUS:
88 deb_ts("URB dropped because of feedcount.\n"); 98 b = (u8 *) urb->transfer_buffer;
99 for (i = 0; i < urb->number_of_packets; i++) {
100 if (urb->iso_frame_desc[i].status != 0)
101 deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
102 else if (urb->iso_frame_desc[i].actual_length > 0) {
103 dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
104 urb->iso_frame_desc[i].actual_length);
105 }
106 urb->iso_frame_desc[i].status = 0;
107 urb->iso_frame_desc[i].actual_length = 0;
108 }
109 debug_dump(b,20,deb_ts);
110 break;
111 case PIPE_BULK:
112 if (urb->actual_length > 0)
113 dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
114 break;
115 default:
116 err("unkown endpoint type in completition handler.");
117 return;
118 }
119 }
120 }
89 121
90 usb_submit_urb(urb,GFP_ATOMIC); 122 usb_submit_urb(urb,GFP_ATOMIC);
91} 123}
@@ -94,7 +126,7 @@ int dvb_usb_urb_kill(struct dvb_usb_device *d)
94{ 126{
95 int i; 127 int i;
96 for (i = 0; i < d->urbs_submitted; i++) { 128 for (i = 0; i < d->urbs_submitted; i++) {
97 deb_info("killing URB no. %d.\n",i); 129 deb_ts("killing URB no. %d.\n",i);
98 130
99 /* stop the URB */ 131 /* stop the URB */
100 usb_kill_urb(d->urb_list[i]); 132 usb_kill_urb(d->urb_list[i]);
@@ -107,9 +139,9 @@ int dvb_usb_urb_submit(struct dvb_usb_device *d)
107{ 139{
108 int i,ret; 140 int i,ret;
109 for (i = 0; i < d->urbs_initialized; i++) { 141 for (i = 0; i < d->urbs_initialized; i++) {
110 deb_info("submitting URB no. %d\n",i); 142 deb_ts("submitting URB no. %d\n",i);
111 if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) { 143 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); 144 err("could not submit URB no. %d - get them all back",i);
113 dvb_usb_urb_kill(d); 145 dvb_usb_urb_kill(d);
114 return ret; 146 return ret;
115 } 147 }
@@ -118,32 +150,78 @@ int dvb_usb_urb_submit(struct dvb_usb_device *d)
118 return 0; 150 return 0;
119} 151}
120 152
121static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d) 153static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
122{ 154{
123 int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize; 155 if (d->state & DVB_USB_STATE_URB_BUF) {
156 while (d->buf_num) {
157 d->buf_num--;
158 deb_mem("freeing buffer %d\n",d->buf_num);
159 usb_buffer_free(d->udev, d->buf_size,
160 d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
161 }
162 kfree(d->buf_list);
163 kfree(d->dma_addr);
164 }
165
166 d->state &= ~DVB_USB_STATE_URB_BUF;
124 167
125 deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize); 168 return 0;
126 /* allocate the actual buffer for the URBs */ 169}
127 if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) { 170
128 deb_info("not enough memory for urb-buffer allocation.\n"); 171static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
172{
173 d->buf_num = 0;
174 d->buf_size = size;
175
176 deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
177
178 if ((d->buf_list = kmalloc(num*sizeof(u8 *), GFP_ATOMIC)) == NULL)
179 return -ENOMEM;
180
181 if ((d->dma_addr = kmalloc(num*sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
182 kfree(d->buf_list);
129 return -ENOMEM; 183 return -ENOMEM;
130 } 184 }
131 deb_info("allocation successful\n"); 185 memset(d->buf_list,0,num*sizeof(u8 *));
132 memset(d->buffer,0,bufsize); 186 memset(d->dma_addr,0,num*sizeof(dma_addr_t));
133 187
134 d->state |= DVB_USB_STATE_URB_BUF; 188 d->state |= DVB_USB_STATE_URB_BUF;
135 189
190 for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
191 deb_mem("allocating buffer %d\n",d->buf_num);
192 if (( d->buf_list[d->buf_num] =
193 usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
194 &d->dma_addr[d->buf_num]) ) == NULL) {
195 deb_mem("not enough memory for urb-buffer allocation.\n");
196 dvb_usb_free_stream_buffers(d);
197 return -ENOMEM;
198 }
199 deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]);
200 memset(d->buf_list[d->buf_num],0,size);
201 }
202 deb_mem("allocation successful\n");
203
204 return 0;
205}
206
207static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
208{
209 int i;
210
211 if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
212 d->props.urb.u.bulk.buffersize)) < 0)
213 return i;
214
136 /* allocate the URBs */ 215 /* allocate the URBs */
137 for (i = 0; i < d->props.urb.count; i++) { 216 for (i = 0; i < d->props.urb.count; i++) {
138 if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) { 217 if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
139 return -ENOMEM; 218 return -ENOMEM;
140 }
141 219
142 usb_fill_bulk_urb( d->urb_list[i], d->udev, 220 usb_fill_bulk_urb( d->urb_list[i], d->udev,
143 usb_rcvbulkpipe(d->udev,d->props.urb.endpoint), 221 usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
144 &d->buffer[i*d->props.urb.u.bulk.buffersize], 222 d->buf_list[i],
145 d->props.urb.u.bulk.buffersize, 223 d->props.urb.u.bulk.buffersize,
146 dvb_usb_bulk_urb_complete, d); 224 dvb_usb_urb_complete, d);
147 225
148 d->urb_list[i]->transfer_flags = 0; 226 d->urb_list[i]->transfer_flags = 0;
149 d->urbs_initialized++; 227 d->urbs_initialized++;
@@ -151,6 +229,47 @@ static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
151 return 0; 229 return 0;
152} 230}
153 231
232static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
233{
234 int i,j;
235
236 if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
237 d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
238 return i;
239
240 /* allocate the URBs */
241 for (i = 0; i < d->props.urb.count; i++) {
242 struct urb *urb;
243 int frame_offset = 0;
244 if ((d->urb_list[i] =
245 usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
246 return -ENOMEM;
247
248 urb = d->urb_list[i];
249
250 urb->dev = d->udev;
251 urb->context = d;
252 urb->complete = dvb_usb_urb_complete;
253 urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
254 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
255 urb->interval = d->props.urb.u.isoc.interval;
256 urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
257 urb->transfer_buffer_length = d->buf_size;
258 urb->transfer_buffer = d->buf_list[i];
259 urb->transfer_dma = d->dma_addr[i];
260
261 for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
262 urb->iso_frame_desc[j].offset = frame_offset;
263 urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
264 frame_offset += d->props.urb.u.isoc.framesize;
265 }
266
267 d->urbs_initialized++;
268 }
269 return 0;
270
271}
272
154int dvb_usb_urb_init(struct dvb_usb_device *d) 273int dvb_usb_urb_init(struct dvb_usb_device *d)
155{ 274{
156 /* 275 /*
@@ -174,8 +293,7 @@ int dvb_usb_urb_init(struct dvb_usb_device *d)
174 case DVB_USB_BULK: 293 case DVB_USB_BULK:
175 return dvb_usb_bulk_urb_init(d); 294 return dvb_usb_bulk_urb_init(d);
176 case DVB_USB_ISOC: 295 case DVB_USB_ISOC:
177 err("isochronous transfer not yet implemented in dvb-usb."); 296 return dvb_usb_isoc_urb_init(d);
178 return -EINVAL;
179 default: 297 default:
180 err("unkown URB-type for data transfer."); 298 err("unkown URB-type for data transfer.");
181 return -EINVAL; 299 return -EINVAL;
@@ -191,7 +309,7 @@ int dvb_usb_urb_exit(struct dvb_usb_device *d)
191 if (d->state & DVB_USB_STATE_URB_LIST) { 309 if (d->state & DVB_USB_STATE_URB_LIST) {
192 for (i = 0; i < d->urbs_initialized; i++) { 310 for (i = 0; i < d->urbs_initialized; i++) {
193 if (d->urb_list[i] != NULL) { 311 if (d->urb_list[i] != NULL) {
194 deb_info("freeing URB no. %d.\n",i); 312 deb_mem("freeing URB no. %d.\n",i);
195 /* free the URBs */ 313 /* free the URBs */
196 usb_free_urb(d->urb_list[i]); 314 usb_free_urb(d->urb_list[i]);
197 } 315 }
@@ -202,10 +320,6 @@ int dvb_usb_urb_exit(struct dvb_usb_device *d)
202 d->state &= ~DVB_USB_STATE_URB_LIST; 320 d->state &= ~DVB_USB_STATE_URB_LIST;
203 } 321 }
204 322
205 if (d->state & DVB_USB_STATE_URB_BUF) 323 dvb_usb_free_stream_buffers(d);
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; 324 return 0;
211} 325}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index abcee1943f64..a80567caf508 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -189,12 +189,13 @@ struct dvb_usb_properties {
189 struct { 189 struct {
190 int framesperurb; 190 int framesperurb;
191 int framesize; 191 int framesize;
192 int interval;
192 } isoc; 193 } isoc;
193 } u; 194 } u;
194 } urb; 195 } urb;
195 196
196 int num_device_descs; 197 int num_device_descs;
197 struct dvb_usb_device_description devices[8]; 198 struct dvb_usb_device_description devices[9];
198}; 199};
199 200
200 201
@@ -207,19 +208,28 @@ struct dvb_usb_properties {
207 * @udev: pointer to the device's struct usb_device. 208 * @udev: pointer to the device's struct usb_device.
208 * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS- 209 * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
209 * streaming. 210 * streaming.
210 * @buffer: buffer used to streaming. 211 *
211 * @dma_handle: dma_addr_t for buffer. 212 * @buf_num: number of buffer allocated.
213 * @buf_size: size of each buffer in buf_list.
214 * @buf_list: array containing all allocate buffers for streaming.
215 * @dma_addr: list of dma_addr_t for each buffer in buf_list.
216 *
212 * @urbs_initialized: number of URBs initialized. 217 * @urbs_initialized: number of URBs initialized.
213 * @urbs_submitted: number of URBs submitted. 218 * @urbs_submitted: number of URBs submitted.
219 *
214 * @feedcount: number of reqested feeds (used for streaming-activation) 220 * @feedcount: number of reqested feeds (used for streaming-activation)
215 * @pid_filtering: is hardware pid_filtering used or not. 221 * @pid_filtering: is hardware pid_filtering used or not.
222 *
216 * @usb_sem: semaphore of USB control messages (reading needs two messages) 223 * @usb_sem: semaphore of USB control messages (reading needs two messages)
217 * @i2c_sem: semaphore for i2c-transfers 224 * @i2c_sem: semaphore for i2c-transfers
225 *
218 * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB 226 * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
219 * @pll_addr: I2C address of the tuner for programming 227 * @pll_addr: I2C address of the tuner for programming
220 * @pll_init: array containing the initialization buffer 228 * @pll_init: array containing the initialization buffer
221 * @pll_desc: pointer to the appropriate struct dvb_pll_desc 229 * @pll_desc: pointer to the appropriate struct dvb_pll_desc
222 * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod 230 *
231 * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
232 *
223 * @dvb_adap: device's dvb_adapter. 233 * @dvb_adap: device's dvb_adapter.
224 * @dmxdev: device's dmxdev. 234 * @dmxdev: device's dmxdev.
225 * @demux: device's software demuxer. 235 * @demux: device's software demuxer.
@@ -253,8 +263,12 @@ struct dvb_usb_device {
253 /* usb */ 263 /* usb */
254 struct usb_device *udev; 264 struct usb_device *udev;
255 struct urb **urb_list; 265 struct urb **urb_list;
256 u8 *buffer; 266
257 dma_addr_t dma_handle; 267 int buf_num;
268 unsigned long buf_size;
269 u8 **buf_list;
270 dma_addr_t *dma_addr;
271
258 int urbs_initialized; 272 int urbs_initialized;
259 int urbs_submitted; 273 int urbs_submitted;
260 274
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 9d83781aef95..258a92bfbcc7 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -203,7 +203,7 @@ static struct dvb_usb_properties nova_t_properties = {
203 203
204static struct usb_driver nova_t_driver = { 204static struct usb_driver nova_t_driver = {
205 .owner = THIS_MODULE, 205 .owner = THIS_MODULE,
206 .name = "Hauppauge WinTV-NOVA-T usb2", 206 .name = "dvb_usb_nova_t_usb2",
207 .probe = nova_t_probe, 207 .probe = nova_t_probe,
208 .disconnect = dvb_usb_device_exit, 208 .disconnect = dvb_usb_device_exit,
209 .id_table = nova_t_table, 209 .id_table = nova_t_table,
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index aa560422ce7c..2112ac3cf5e2 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -129,7 +129,7 @@ static struct dvb_usb_properties umt_properties = {
129 129
130static struct usb_driver umt_driver = { 130static struct usb_driver umt_driver = {
131 .owner = THIS_MODULE, 131 .owner = THIS_MODULE,
132 .name = "HanfTek UMT-010 USB2.0 DVB-T devices", 132 .name = "dvb_usb_umt_010",
133 .probe = umt_probe, 133 .probe = umt_probe,
134 .disconnect = dvb_usb_device_exit, 134 .disconnect = dvb_usb_device_exit,
135 .id_table = umt_table, 135 .id_table = umt_table,
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 02ecc9a8e3b6..5adc5d69ec84 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -44,7 +44,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
44 if (usb_control_msg(d->udev, 44 if (usb_control_msg(d->udev,
45 usb_sndctrlpipe(d->udev,0), 45 usb_sndctrlpipe(d->udev,0),
46 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, 46 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
47 outbuf, 20, 2*HZ) != 20) { 47 outbuf, 20, 2000) != 20) {
48 err("USB control message 'out' went wrong."); 48 err("USB control message 'out' went wrong.");
49 ret = -EIO; 49 ret = -EIO;
50 goto unlock; 50 goto unlock;
@@ -55,7 +55,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in,
55 if (usb_control_msg(d->udev, 55 if (usb_control_msg(d->udev,
56 usb_rcvctrlpipe(d->udev,0), 56 usb_rcvctrlpipe(d->udev,0),
57 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, 57 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
58 inbuf, 12, 2*HZ) != 12) { 58 inbuf, 12, 2000) != 12) {
59 err("USB control message 'in' went wrong."); 59 err("USB control message 'in' went wrong.");
60 ret = -EIO; 60 ret = -EIO;
61 goto unlock; 61 goto unlock;
@@ -94,13 +94,38 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
94/* The keymapping struct. Somehow this should be loaded to the driver, but 94/* The keymapping struct. Somehow this should be loaded to the driver, but
95 * currently it is hardcoded. */ 95 * currently it is hardcoded. */
96static struct dvb_usb_rc_key vp7045_rc_keys[] = { 96static struct dvb_usb_rc_key vp7045_rc_keys[] = {
97 /* insert the keys like this. to make the raw keys visible, enable 97 { 0x00, 0x16, KEY_POWER },
98 * debug=0x04 when loading dvb-usb-vp7045. */ 98 { 0x00, 0x10, KEY_MUTE },
99 99 { 0x00, 0x03, KEY_1 },
100 /* these keys are probably wrong. I don't have a working IR-receiver on my 100 { 0x00, 0x01, KEY_2 },
101 * vp7045, so I can't test it. Patches are welcome. */ 101 { 0x00, 0x06, KEY_3 },
102 { 0x00, 0x01, KEY_1 }, 102 { 0x00, 0x09, KEY_4 },
103 { 0x00, 0x02, KEY_2 }, 103 { 0x00, 0x1d, KEY_5 },
104 { 0x00, 0x1f, KEY_6 },
105 { 0x00, 0x0d, KEY_7 },
106 { 0x00, 0x19, KEY_8 },
107 { 0x00, 0x1b, KEY_9 },
108 { 0x00, 0x15, KEY_0 },
109 { 0x00, 0x05, KEY_CHANNELUP },
110 { 0x00, 0x02, KEY_CHANNELDOWN },
111 { 0x00, 0x1e, KEY_VOLUMEUP },
112 { 0x00, 0x0a, KEY_VOLUMEDOWN },
113 { 0x00, 0x11, KEY_RECORD },
114 { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
115 { 0x00, 0x14, KEY_PLAY },
116 { 0x00, 0x1a, KEY_STOP },
117 { 0x00, 0x40, KEY_REWIND },
118 { 0x00, 0x12, KEY_FASTFORWARD },
119 { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
120 { 0x00, 0x4c, KEY_PAUSE },
121 { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
122 { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
123 { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
124 { 0x00, 0x1c, KEY_EPG }, /* EPG */
125 { 0x00, 0x00, KEY_TAB }, /* Tab */
126 { 0x00, 0x48, KEY_INFO }, /* Preview */
127 { 0x00, 0x04, KEY_LIST }, /* RecordList */
128 { 0x00, 0x0f, KEY_TEXT } /* Teletext */
104}; 129};
105 130
106static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state) 131static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state)
@@ -230,7 +255,7 @@ static struct dvb_usb_properties vp7045_properties = {
230/* usb specific object needed to register this driver with the usb subsystem */ 255/* usb specific object needed to register this driver with the usb subsystem */
231static struct usb_driver vp7045_usb_driver = { 256static struct usb_driver vp7045_usb_driver = {
232 .owner = THIS_MODULE, 257 .owner = THIS_MODULE,
233 .name = "dvb-usb-vp7045", 258 .name = "dvb_usb_vp7045",
234 .probe = vp7045_usb_probe, 259 .probe = vp7045_usb_probe,
235 .disconnect = dvb_usb_device_exit, 260 .disconnect = dvb_usb_device_exit,
236 .id_table = vp7045_usb_table, 261 .id_table = vp7045_usb_table,
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b4fddf513ebe..d847c62bd837 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -40,6 +40,12 @@ config DVB_VES1X93
40 help 40 help
41 A DVB-S tuner module. Say Y when you want to support this frontend. 41 A DVB-S tuner module. Say Y when you want to support this frontend.
42 42
43config DVB_S5H1420
44 tristate "Samsung S5H1420 based"
45 depends on DVB_CORE
46 help
47 A DVB-S tuner module. Say Y when you want to support this frontend.
48
43comment "DVB-T (terrestrial) frontends" 49comment "DVB-T (terrestrial) frontends"
44 depends on DVB_CORE 50 depends on DVB_CORE
45 51
@@ -181,4 +187,11 @@ config DVB_BCM3510
181 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to 187 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
182 support this frontend. 188 support this frontend.
183 189
190config DVB_LGDT3302
191 tristate "LGDT3302 based (DViCO FusionHDTV3 Gold)"
192 depends on DVB_CORE
193 help
194 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
195 to support this frontend.
196
184endmenu 197endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 91d6d3576d3d..de5e240cba7f 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -29,3 +29,5 @@ obj-$(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 31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
32obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
33obj-$(CONFIG_DVB_LGDT3302) += lgdt3302.o
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index f4aa44136c7c..9f639297a9f2 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -76,7 +76,6 @@ static u8 init_tab [] = {
76 0x49, 0x56, 76 0x49, 0x56,
77 0x6b, 0x1e, 77 0x6b, 0x1e,
78 0xc8, 0x02, 78 0xc8, 0x02,
79 0xf8, 0x02,
80 0xf9, 0x00, 79 0xf9, 0x00,
81 0xfa, 0x00, 80 0xfa, 0x00,
82 0xfb, 0x00, 81 0xfb, 0x00,
@@ -203,7 +202,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
203 struct cx22702_state* state = fe->demodulator_priv; 202 struct cx22702_state* state = fe->demodulator_priv;
204 203
205 /* set PLL */ 204 /* set PLL */
206 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); 205 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
207 if (state->config->pll_set) { 206 if (state->config->pll_set) {
208 state->config->pll_set(fe, p); 207 state->config->pll_set(fe, p);
209 } else if (state->config->pll_desc) { 208 } else if (state->config->pll_desc) {
@@ -217,7 +216,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
217 } else { 216 } else {
218 BUG(); 217 BUG();
219 } 218 }
220 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); 219 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
221 220
222 /* set inversion */ 221 /* set inversion */
223 cx22702_set_inversion (state, p->inversion); 222 cx22702_set_inversion (state, p->inversion);
@@ -256,7 +255,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
256 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc ); 255 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
257 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); 256 cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
258 cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ 257 cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
259 printk("%s: Autodetecting\n",__FUNCTION__); 258 dprintk("%s: Autodetecting\n",__FUNCTION__);
260 return 0; 259 return 0;
261 } 260 }
262 261
@@ -347,10 +346,11 @@ static int cx22702_init (struct dvb_frontend* fe)
347 for (i=0; i<sizeof(init_tab); i+=2) 346 for (i=0; i<sizeof(init_tab); i+=2)
348 cx22702_writereg (state, init_tab[i], init_tab[i+1]); 347 cx22702_writereg (state, init_tab[i], init_tab[i+1]);
349 348
349 cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
350 350
351 /* init PLL */ 351 /* init PLL */
352 if (state->config->pll_init) { 352 if (state->config->pll_init) {
353 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); 353 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
354 state->config->pll_init(fe); 354 state->config->pll_init(fe);
355 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); 355 cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
356 } 356 }
@@ -440,8 +440,10 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
440 440
441 /* RS Uncorrectable Packet Count then reset */ 441 /* RS Uncorrectable Packet Count then reset */
442 _ucblocks = cx22702_readreg (state, 0xE3); 442 _ucblocks = cx22702_readreg (state, 0xE3);
443 if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks); 443 if (state->prevUCBlocks < _ucblocks)
444 else *ucblocks = state->prevUCBlocks - _ucblocks; 444 *ucblocks = (_ucblocks - state->prevUCBlocks);
445 else
446 *ucblocks = state->prevUCBlocks - _ucblocks;
445 state->prevUCBlocks = _ucblocks; 447 state->prevUCBlocks = _ucblocks;
446 448
447 return 0; 449 return 0;
@@ -457,6 +459,12 @@ static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
457 return cx22702_get_tps (state, &p->u.ofdm); 459 return cx22702_get_tps (state, &p->u.ofdm);
458} 460}
459 461
462static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
463{
464 tune->min_delay_ms = 1000;
465 return 0;
466}
467
460static void cx22702_release(struct dvb_frontend* fe) 468static void cx22702_release(struct dvb_frontend* fe)
461{ 469{
462 struct cx22702_state* state = fe->demodulator_priv; 470 struct cx22702_state* state = fe->demodulator_priv;
@@ -472,7 +480,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
472 480
473 /* allocate memory for the internal state */ 481 /* allocate memory for the internal state */
474 state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); 482 state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
475 if (state == NULL) goto error; 483 if (state == NULL)
484 goto error;
476 485
477 /* setup the state */ 486 /* setup the state */
478 state->config = config; 487 state->config = config;
@@ -481,7 +490,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
481 state->prevUCBlocks = 0; 490 state->prevUCBlocks = 0;
482 491
483 /* check if the demod is there */ 492 /* check if the demod is there */
484 if (cx22702_readreg(state, 0x1f) != 0x3) goto error; 493 if (cx22702_readreg(state, 0x1f) != 0x3)
494 goto error;
485 495
486 /* create dvb_frontend */ 496 /* create dvb_frontend */
487 state->frontend.ops = &state->ops; 497 state->frontend.ops = &state->ops;
@@ -514,6 +524,7 @@ static struct dvb_frontend_ops cx22702_ops = {
514 524
515 .set_frontend = cx22702_set_tps, 525 .set_frontend = cx22702_set_tps,
516 .get_frontend = cx22702_get_frontend, 526 .get_frontend = cx22702_get_frontend,
527 .get_tune_settings = cx22702_get_tune_settings,
517 528
518 .read_status = cx22702_read_status, 529 .read_status = cx22702_read_status,
519 .read_ber = cx22702_read_ber, 530 .read_ber = cx22702_read_ber,
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 559fdb906669..11f86806756e 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -35,6 +35,11 @@ struct cx22702_config
35 /* the demodulator's i2c address */ 35 /* the demodulator's i2c address */
36 u8 demod_address; 36 u8 demod_address;
37 37
38 /* serial/parallel output */
39#define CX22702_PARALLEL_OUTPUT 0
40#define CX22702_SERIAL_OUTPUT 1
41 u8 output_mode;
42
38 /* PLL maintenance */ 43 /* PLL maintenance */
39 u8 pll_address; 44 u8 pll_address;
40 struct dvb_pll_desc *pll_desc; 45 struct dvb_pll_desc *pll_desc;
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index f73b5f48e235..5afeaa9b43b4 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -55,7 +55,7 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
55}; 55};
56EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); 56EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
57 57
58static void thomson_dtt759x_bw(u8 *buf, int bandwidth) 58static void thomson_dtt759x_bw(u8 *buf, u32 freq, int bandwidth)
59{ 59{
60 if (BANDWIDTH_7_MHZ == bandwidth) 60 if (BANDWIDTH_7_MHZ == bandwidth)
61 buf[3] |= 0x10; 61 buf[3] |= 0x10;
@@ -93,6 +93,32 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
93}; 93};
94EXPORT_SYMBOL(dvb_pll_lg_z201); 94EXPORT_SYMBOL(dvb_pll_lg_z201);
95 95
96struct dvb_pll_desc dvb_pll_microtune_4042 = {
97 .name = "Microtune 4042 FI5",
98 .min = 57000000,
99 .max = 858000000,
100 .count = 3,
101 .entries = {
102 { 162000000, 44000000, 62500, 0x8e, 0xa1 },
103 { 457000000, 44000000, 62500, 0x8e, 0x91 },
104 { 999999999, 44000000, 62500, 0x8e, 0x31 },
105 },
106};
107EXPORT_SYMBOL(dvb_pll_microtune_4042);
108
109struct dvb_pll_desc dvb_pll_thomson_dtt7611 = {
110 .name = "Thomson dtt7611",
111 .min = 44000000,
112 .max = 958000000,
113 .count = 3,
114 .entries = {
115 { 157250000, 44000000, 62500, 0x8e, 0x39 },
116 { 454000000, 44000000, 62500, 0x8e, 0x3a },
117 { 999999999, 44000000, 62500, 0x8e, 0x3c },
118 },
119};
120EXPORT_SYMBOL(dvb_pll_thomson_dtt7611);
121
96struct dvb_pll_desc dvb_pll_unknown_1 = { 122struct dvb_pll_desc dvb_pll_unknown_1 = {
97 .name = "unknown 1", /* used by dntv live dvb-t */ 123 .name = "unknown 1", /* used by dntv live dvb-t */
98 .min = 174000000, 124 .min = 174000000,
@@ -146,7 +172,7 @@ EXPORT_SYMBOL(dvb_pll_env57h1xd5);
146/* Philips TDA6650/TDA6651 172/* Philips TDA6650/TDA6651
147 * used in Panasonic ENV77H11D5 173 * used in Panasonic ENV77H11D5
148 */ 174 */
149static void tda665x_bw(u8 *buf, int bandwidth) 175static void tda665x_bw(u8 *buf, u32 freq, int bandwidth)
150{ 176{
151 if (bandwidth == BANDWIDTH_8_MHZ) 177 if (bandwidth == BANDWIDTH_8_MHZ)
152 buf[3] |= 0x08; 178 buf[3] |= 0x08;
@@ -178,7 +204,7 @@ EXPORT_SYMBOL(dvb_pll_tda665x);
178/* Infineon TUA6034 204/* Infineon TUA6034
179 * used in LG TDTP E102P 205 * used in LG TDTP E102P
180 */ 206 */
181static void tua6034_bw(u8 *buf, int bandwidth) 207static void tua6034_bw(u8 *buf, u32 freq, int bandwidth)
182{ 208{
183 if (BANDWIDTH_7_MHZ != bandwidth) 209 if (BANDWIDTH_7_MHZ != bandwidth)
184 buf[3] |= 0x08; 210 buf[3] |= 0x08;
@@ -198,6 +224,57 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
198}; 224};
199EXPORT_SYMBOL(dvb_pll_tua6034); 225EXPORT_SYMBOL(dvb_pll_tua6034);
200 226
227/* Philips FMD1216ME
228 * used in Medion Hybrid PCMCIA card and USB Box
229 */
230static void fmd1216me_bw(u8 *buf, u32 freq, int bandwidth)
231{
232 if (bandwidth == BANDWIDTH_8_MHZ && freq >= 158870000)
233 buf[3] |= 0x08;
234}
235
236struct dvb_pll_desc dvb_pll_fmd1216me = {
237 .name = "Philips FMD1216ME",
238 .min = 50870000,
239 .max = 858000000,
240 .setbw = fmd1216me_bw,
241 .count = 7,
242 .entries = {
243 { 143870000, 36213333, 166667, 0xbc, 0x41 },
244 { 158870000, 36213333, 166667, 0xf4, 0x41 },
245 { 329870000, 36213333, 166667, 0xbc, 0x42 },
246 { 441870000, 36213333, 166667, 0xf4, 0x42 },
247 { 625870000, 36213333, 166667, 0xbc, 0x44 },
248 { 803870000, 36213333, 166667, 0xf4, 0x44 },
249 { 999999999, 36213333, 166667, 0xfc, 0x44 },
250 }
251};
252EXPORT_SYMBOL(dvb_pll_fmd1216me);
253
254/* ALPS TDED4
255 * used in Nebula-Cards and USB boxes
256 */
257static void tded4_bw(u8 *buf, u32 freq, int bandwidth)
258{
259 if (bandwidth == BANDWIDTH_8_MHZ)
260 buf[3] |= 0x04;
261}
262
263struct dvb_pll_desc dvb_pll_tded4 = {
264 .name = "ALPS TDED4",
265 .min = 47000000,
266 .max = 863000000,
267 .setbw = tded4_bw,
268 .count = 4,
269 .entries = {
270 { 153000000, 36166667, 166667, 0x85, 0x01 },
271 { 470000000, 36166667, 166667, 0x85, 0x02 },
272 { 823000000, 36166667, 166667, 0x85, 0x08 },
273 { 999999999, 36166667, 166667, 0x85, 0x88 },
274 }
275};
276EXPORT_SYMBOL(dvb_pll_tded4);
277
201/* ----------------------------------------------------------- */ 278/* ----------------------------------------------------------- */
202/* code */ 279/* code */
203 280
@@ -231,7 +308,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
231 buf[3] = desc->entries[i].cb2; 308 buf[3] = desc->entries[i].cb2;
232 309
233 if (desc->setbw) 310 if (desc->setbw)
234 desc->setbw(buf, bandwidth); 311 desc->setbw(buf, freq, bandwidth);
235 312
236 if (debug) 313 if (debug)
237 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", 314 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index b796778624b6..cb794759d89e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -9,7 +9,7 @@ struct dvb_pll_desc {
9 char *name; 9 char *name;
10 u32 min; 10 u32 min;
11 u32 max; 11 u32 max;
12 void (*setbw)(u8 *buf, int bandwidth); 12 void (*setbw)(u8 *buf, u32 freq, int bandwidth);
13 int count; 13 int count;
14 struct { 14 struct {
15 u32 limit; 15 u32 limit;
@@ -24,12 +24,16 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
24extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; 24extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
25extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; 25extern 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_microtune_4042;
28extern struct dvb_pll_desc dvb_pll_thomson_dtt7611;
27extern struct dvb_pll_desc dvb_pll_unknown_1; 29extern struct dvb_pll_desc dvb_pll_unknown_1;
28 30
29extern struct dvb_pll_desc dvb_pll_tua6010xs; 31extern struct dvb_pll_desc dvb_pll_tua6010xs;
30extern struct dvb_pll_desc dvb_pll_env57h1xd5; 32extern struct dvb_pll_desc dvb_pll_env57h1xd5;
31extern struct dvb_pll_desc dvb_pll_tua6034; 33extern struct dvb_pll_desc dvb_pll_tua6034;
32extern struct dvb_pll_desc dvb_pll_tda665x; 34extern struct dvb_pll_desc dvb_pll_tda665x;
35extern struct dvb_pll_desc dvb_pll_fmd1216me;
36extern struct dvb_pll_desc dvb_pll_tded4;
33 37
34int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 38int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
35 u32 freq, int bandwidth); 39 u32 freq, int bandwidth);
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index 031a1ddc7d11..faaad1ae8559 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -474,11 +474,12 @@ static int l64781_init(struct dvb_frontend* fe)
474 return 0; 474 return 0;
475} 475}
476 476
477static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 477static int l64781_get_tune_settings(struct dvb_frontend* fe,
478 struct dvb_frontend_tune_settings* fesettings)
478{ 479{
479 fesettings->min_delay_ms = 200; 480 fesettings->min_delay_ms = 4000;
480 fesettings->step_size = 166667; 481 fesettings->step_size = 0;
481 fesettings->max_drift = 166667*2; 482 fesettings->max_drift = 0;
482 return 0; 483 return 0;
483} 484}
484 485
diff --git a/drivers/media/dvb/frontends/lgdt3302.c b/drivers/media/dvb/frontends/lgdt3302.c
new file mode 100644
index 000000000000..09c914256e49
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302.c
@@ -0,0 +1,611 @@
1/*
2 * $Id: lgdt3302.c,v 1.5 2005/07/07 03:47:15 mkrufky Exp $
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
7 *
8 * Based on code from Kirk Lapray <kirk_lapray@bigfoot.com>
9 * Copyright (C) 2005
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., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 */
26
27/*
28 * NOTES ABOUT THIS DRIVER
29 *
30 * This driver supports DViCO FusionHDTV 3 Gold under Linux.
31 *
32 * TODO:
33 * BER and signal strength always return 0.
34 *
35 */
36
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/moduleparam.h>
40#include <linux/init.h>
41#include <linux/delay.h>
42#include <asm/byteorder.h>
43
44#include "dvb_frontend.h"
45#include "dvb-pll.h"
46#include "lgdt3302_priv.h"
47#include "lgdt3302.h"
48
49static int debug = 0;
50module_param(debug, int, 0644);
51MODULE_PARM_DESC(debug,"Turn on/off lgdt3302 frontend debugging (default:off).");
52#define dprintk(args...) \
53do { \
54if (debug) printk(KERN_DEBUG "lgdt3302: " args); \
55} while (0)
56
57struct lgdt3302_state
58{
59 struct i2c_adapter* i2c;
60 struct dvb_frontend_ops ops;
61
62 /* Configuration settings */
63 const struct lgdt3302_config* config;
64
65 struct dvb_frontend frontend;
66
67 /* Demodulator private data */
68 fe_modulation_t current_modulation;
69
70 /* Tuner private data */
71 u32 current_frequency;
72};
73
74static int i2c_writebytes (struct lgdt3302_state* state,
75 u8 addr, /* demod_address or pll_address */
76 u8 *buf, /* data bytes to send */
77 int len /* number of bytes to send */ )
78{
79 if (addr == state->config->pll_address) {
80 struct i2c_msg msg =
81 { .addr = addr, .flags = 0, .buf = buf, .len = len };
82 int err;
83
84 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
85 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
86 return -EREMOTEIO;
87 }
88 } else {
89 u8 tmp[] = { buf[0], buf[1] };
90 struct i2c_msg msg =
91 { .addr = addr, .flags = 0, .buf = tmp, .len = 2 };
92 int err;
93 int i;
94
95 for (i=1; i<len; i++) {
96 tmp[1] = buf[i];
97 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
98 printk(KERN_WARNING "lgdt3302: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err);
99 return -EREMOTEIO;
100 }
101 tmp[0]++;
102 }
103 }
104 return 0;
105}
106static int i2c_readbytes (struct lgdt3302_state* state,
107 u8 addr, /* demod_address or pll_address */
108 u8 *buf, /* holds data bytes read */
109 int len /* number of bytes to read */ )
110{
111 struct i2c_msg msg =
112 { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
113 int err;
114
115 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
116 printk(KERN_WARNING "lgdt3302: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err);
117 return -EREMOTEIO;
118 }
119 return 0;
120}
121
122/*
123 * This routine writes the register (reg) to the demod bus
124 * then reads the data returned for (len) bytes.
125 */
126
127static u8 i2c_selectreadbytes (struct lgdt3302_state* state,
128 enum I2C_REG reg, u8* buf, int len)
129{
130 u8 wr [] = { reg };
131 struct i2c_msg msg [] = {
132 { .addr = state->config->demod_address,
133 .flags = 0, .buf = wr, .len = 1 },
134 { .addr = state->config->demod_address,
135 .flags = I2C_M_RD, .buf = buf, .len = len },
136 };
137 int ret;
138 ret = i2c_transfer(state->i2c, msg, 2);
139 if (ret != 2) {
140 printk(KERN_WARNING "lgdt3302: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
141 } else {
142 ret = 0;
143 }
144 return ret;
145}
146
147/* Software reset */
148int lgdt3302_SwReset(struct lgdt3302_state* state)
149{
150 u8 ret;
151 u8 reset[] = {
152 IRQ_MASK,
153 0x00 /* bit 6 is active low software reset
154 * bits 5-0 are 1 to mask interrupts */
155 };
156
157 ret = i2c_writebytes(state,
158 state->config->demod_address,
159 reset, sizeof(reset));
160 if (ret == 0) {
161 /* spec says reset takes 100 ns why wait */
162 /* mdelay(100); */ /* keep low for 100mS */
163 reset[1] = 0x7f; /* force reset high (inactive)
164 * and unmask interrupts */
165 ret = i2c_writebytes(state,
166 state->config->demod_address,
167 reset, sizeof(reset));
168 }
169 /* Spec does not indicate a need for this either */
170 /*mdelay(5); */ /* wait 5 msec before doing more */
171 return ret;
172}
173
174static int lgdt3302_init(struct dvb_frontend* fe)
175{
176 /* Hardware reset is done using gpio[0] of cx23880x chip.
177 * I'd like to do it here, but don't know how to find chip address.
178 * cx88-cards.c arranges for the reset bit to be inactive (high).
179 * Maybe there needs to be a callable function in cx88-core or
180 * the caller of this function needs to do it. */
181
182 dprintk("%s entered\n", __FUNCTION__);
183 return lgdt3302_SwReset((struct lgdt3302_state*) fe->demodulator_priv);
184}
185
186static int lgdt3302_read_ber(struct dvb_frontend* fe, u32* ber)
187{
188 *ber = 0; /* Dummy out for now */
189 return 0;
190}
191
192static int lgdt3302_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
193{
194 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
195 u8 buf[2];
196
197 i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf));
198
199 *ucblocks = (buf[0] << 8) | buf[1];
200 return 0;
201}
202
203static int lgdt3302_set_parameters(struct dvb_frontend* fe,
204 struct dvb_frontend_parameters *param)
205{
206 u8 buf[4];
207 struct lgdt3302_state* state =
208 (struct lgdt3302_state*) fe->demodulator_priv;
209
210 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
211 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
212 static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 };
213 static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
214 static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
215 static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
216 static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x00, 0x00, 0x00 };
217 static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
218
219 /* Change only if we are actually changing the modulation */
220 if (state->current_modulation != param->u.vsb.modulation) {
221 switch(param->u.vsb.modulation) {
222 case VSB_8:
223 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
224
225 /* Select VSB mode and serial MPEG interface */
226 top_ctrl_cfg[1] = 0x07;
227 break;
228
229 case QAM_64:
230 dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
231
232 /* Select QAM_64 mode and serial MPEG interface */
233 top_ctrl_cfg[1] = 0x04;
234 break;
235
236 case QAM_256:
237 dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
238
239 /* Select QAM_256 mode and serial MPEG interface */
240 top_ctrl_cfg[1] = 0x05;
241 break;
242 default:
243 printk(KERN_WARNING "lgdt3302: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
244 return -1;
245 }
246 /* Initializations common to all modes */
247
248 /* Select the requested mode */
249 i2c_writebytes(state, state->config->demod_address,
250 top_ctrl_cfg, sizeof(top_ctrl_cfg));
251
252 /* Change the value of IFBW[11:0]
253 of AGC IF/RF loop filter bandwidth register */
254 i2c_writebytes(state, state->config->demod_address,
255 agc_rf_cfg, sizeof(agc_rf_cfg));
256
257 /* Change the value of bit 6, 'nINAGCBY' and
258 'NSSEL[1:0] of ACG function control register 2 */
259 /* Change the value of bit 6 'RFFIX'
260 of AGC function control register 3 */
261 i2c_writebytes(state, state->config->demod_address,
262 agc_ctrl_cfg, sizeof(agc_ctrl_cfg));
263
264 /* Change the TPCLK pin polarity
265 data is valid on falling clock */
266 i2c_writebytes(state, state->config->demod_address,
267 demux_ctrl_cfg, sizeof(demux_ctrl_cfg));
268
269 if (param->u.vsb.modulation == VSB_8) {
270 /* Initialization for VSB modes only */
271 /* Change the value of NCOCTFV[25:0]of carrier
272 recovery center frequency register for VSB */
273 i2c_writebytes(state, state->config->demod_address,
274 vsb_freq_cfg, sizeof(vsb_freq_cfg));
275 } else {
276 /* Initialization for QAM modes only */
277 /* Set the value of 'INLVTHD' register 0x2a/0x2c
278 to value from 'IFACC' register 0x39/0x3b -1 */
279 int value;
280 i2c_selectreadbytes(state, AGC_RFIF_ACC0,
281 &agc_delay_cfg[1], 3);
282 value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];
283 value = value -1;
284 dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);
285 agc_delay_cfg[1] = (value >> 8) & 0x0f;
286 agc_delay_cfg[2] = 0x00;
287 agc_delay_cfg[3] = value & 0xff;
288 i2c_writebytes(state, state->config->demod_address,
289 agc_delay_cfg, sizeof(agc_delay_cfg));
290
291 /* Change the value of IAGCBW[15:8]
292 of inner AGC loop filter bandwith */
293 i2c_writebytes(state, state->config->demod_address,
294 agc_loop_cfg, sizeof(agc_loop_cfg));
295 }
296
297 state->config->set_ts_params(fe, 0);
298 lgdt3302_SwReset(state);
299 state->current_modulation = param->u.vsb.modulation;
300 }
301
302 /* Change only if we are actually changing the channel */
303 if (state->current_frequency != param->frequency) {
304 dvb_pll_configure(state->config->pll_desc, buf,
305 param->frequency, 0);
306 dprintk("%s: tuner bytes: 0x%02x 0x%02x "
307 "0x%02x 0x%02x\n", __FUNCTION__, buf[0],buf[1],buf[2],buf[3]);
308 i2c_writebytes(state, state->config->pll_address ,buf, 4);
309
310 /* Check the status of the tuner pll */
311 i2c_readbytes(state, state->config->pll_address, buf, 1);
312 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
313
314 lgdt3302_SwReset(state);
315
316 /* Update current frequency */
317 state->current_frequency = param->frequency;
318 }
319 return 0;
320}
321
322static int lgdt3302_get_frontend(struct dvb_frontend* fe,
323 struct dvb_frontend_parameters* param)
324{
325 struct lgdt3302_state *state = fe->demodulator_priv;
326 param->frequency = state->current_frequency;
327 return 0;
328}
329
330static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
331{
332 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
333 u8 buf[3];
334
335 *status = 0; /* Reset status result */
336
337 /* Check the status of the tuner pll */
338 i2c_readbytes(state, state->config->pll_address, buf, 1);
339 dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[0]);
340 if ((buf[0] & 0xc0) != 0x40)
341 return 0; /* Tuner PLL not locked or not powered on */
342
343 /*
344 * You must set the Mask bits to 1 in the IRQ_MASK in order
345 * to see that status bit in the IRQ_STATUS register.
346 * This is done in SwReset();
347 */
348
349 /* AGC status register */
350 i2c_selectreadbytes(state, AGC_STATUS, buf, 1);
351 dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
352 if ((buf[0] & 0x0c) == 0x8){
353 /* Test signal does not exist flag */
354 /* as well as the AGC lock flag. */
355 *status |= FE_HAS_SIGNAL;
356 } else {
357 /* Without a signal all other status bits are meaningless */
358 return 0;
359 }
360
361 /* signal status */
362 i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf));
363 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
364
365#if 0
366 /* Alternative method to check for a signal */
367 /* using the SNR good/bad interrupts. */
368 if ((buf[2] & 0x30) == 0x10)
369 *status |= FE_HAS_SIGNAL;
370#endif
371
372 /* sync status */
373 if ((buf[2] & 0x03) == 0x01) {
374 *status |= FE_HAS_SYNC;
375 }
376
377 /* FEC error status */
378 if ((buf[2] & 0x0c) == 0x08) {
379 *status |= FE_HAS_LOCK;
380 *status |= FE_HAS_VITERBI;
381 }
382
383 /* Carrier Recovery Lock Status Register */
384 i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1);
385 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
386 switch (state->current_modulation) {
387 case QAM_256:
388 case QAM_64:
389 /* Need to undestand why there are 3 lock levels here */
390 if ((buf[0] & 0x07) == 0x07)
391 *status |= FE_HAS_CARRIER;
392 break;
393 case VSB_8:
394 if ((buf[0] & 0x80) == 0x80)
395 *status |= FE_HAS_CARRIER;
396 break;
397 default:
398 printk("KERN_WARNING lgdt3302: %s: Modulation set to unsupported value\n", __FUNCTION__);
399 }
400
401 return 0;
402}
403
404static int lgdt3302_read_signal_strength(struct dvb_frontend* fe, u16* strength)
405{
406 /* not directly available. */
407 return 0;
408}
409
410static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
411{
412#ifdef SNR_IN_DB
413 /*
414 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
415 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
416 * respectively. The following tables are built on these formulas.
417 * The usual definition is SNR = 20 log10(signal/noise)
418 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
419 *
420 * This table is a an ordered list of noise values computed by the
421 * formula from the spec sheet such that the index into the table
422 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
423 * value entries at the beginning because the SNR varies more than
424 * 1 db for a change of 1 digit in noise at very small values of noise.
425 *
426 * Examples from SNR_EQ table:
427 * noise SNR
428 * 0 43
429 * 1 42
430 * 2 39
431 * 3 37
432 * 4 36
433 * 5 35
434 * 6 34
435 * 7 33
436 * 8 33
437 * 9 32
438 * 10 32
439 * 11 31
440 * 12 31
441 * 13 30
442 */
443
444 static const u32 SNR_EQ[] =
445 { 1, 2, 2, 2, 3, 3, 4, 4, 5, 7,
446 9, 11, 13, 17, 21, 26, 33, 41, 52, 65,
447 81, 102, 129, 162, 204, 257, 323, 406, 511, 644,
448 810, 1020, 1284, 1616, 2035, 2561, 3224, 4059, 5110, 6433,
449 8098, 10195, 12835, 16158, 20341, 25608, 32238, 40585, 51094, 64323,
450 80978, 101945, 128341, 161571, 203406, 256073, 0x40000
451 };
452
453 static const u32 SNR_PH[] =
454 { 1, 2, 2, 2, 3, 3, 4, 5, 6, 8,
455 10, 12, 15, 19, 23, 29, 37, 46, 58, 73,
456 91, 115, 144, 182, 229, 288, 362, 456, 574, 722,
457 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216,
458 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151,
459 90833, 114351, 143960, 181235, 228161, 0x040000
460 };
461
462 static u8 buf[5];/* read data buffer */
463 static u32 noise; /* noise value */
464 static u32 snr_db; /* index into SNR_EQ[] */
465 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
466
467 /* read both equalizer and pase tracker noise data */
468 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
469
470 if (state->current_modulation == VSB_8) {
471 /* Equalizer Mean-Square Error Register for VSB */
472 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
473
474 /*
475 * Look up noise value in table.
476 * A better search algorithm could be used...
477 * watch out there are duplicate entries.
478 */
479 for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
480 if (noise < SNR_EQ[snr_db]) {
481 *snr = 43 - snr_db;
482 break;
483 }
484 }
485 } else {
486 /* Phase Tracker Mean-Square Error Register for QAM */
487 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
488
489 /* Look up noise value in table. */
490 for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
491 if (noise < SNR_PH[snr_db]) {
492 *snr = 45 - snr_db;
493 break;
494 }
495 }
496 }
497#else
498 /* Return the raw noise value */
499 static u8 buf[5];/* read data buffer */
500 static u32 noise; /* noise value */
501 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
502
503 /* read both equalizer and pase tracker noise data */
504 i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf));
505
506 if (state->current_modulation == VSB_8) {
507 /* Equalizer Mean-Square Error Register for VSB */
508 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
509 } else {
510 /* Phase Tracker Mean-Square Error Register for QAM */
511 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
512 }
513
514 /* Small values for noise mean signal is better so invert noise */
515 /* Noise is 19 bit value so discard 3 LSB*/
516 *snr = ~noise>>3;
517#endif
518
519 dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
520
521 return 0;
522}
523
524static int lgdt3302_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
525{
526 /* I have no idea about this - it may not be needed */
527 fe_tune_settings->min_delay_ms = 500;
528 fe_tune_settings->step_size = 0;
529 fe_tune_settings->max_drift = 0;
530 return 0;
531}
532
533static void lgdt3302_release(struct dvb_frontend* fe)
534{
535 struct lgdt3302_state* state = (struct lgdt3302_state*) fe->demodulator_priv;
536 kfree(state);
537}
538
539static struct dvb_frontend_ops lgdt3302_ops;
540
541struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
542 struct i2c_adapter* i2c)
543{
544 struct lgdt3302_state* state = NULL;
545 u8 buf[1];
546
547 /* Allocate memory for the internal state */
548 state = (struct lgdt3302_state*) kmalloc(sizeof(struct lgdt3302_state), GFP_KERNEL);
549 if (state == NULL)
550 goto error;
551 memset(state,0,sizeof(*state));
552
553 /* Setup the state */
554 state->config = config;
555 state->i2c = i2c;
556 memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
557 /* Verify communication with demod chip */
558 if (i2c_selectreadbytes(state, 2, buf, 1))
559 goto error;
560
561 state->current_frequency = -1;
562 state->current_modulation = -1;
563
564 /* Create dvb_frontend */
565 state->frontend.ops = &state->ops;
566 state->frontend.demodulator_priv = state;
567 return &state->frontend;
568
569error:
570 if (state)
571 kfree(state);
572 dprintk("%s: ERROR\n",__FUNCTION__);
573 return NULL;
574}
575
576static struct dvb_frontend_ops lgdt3302_ops = {
577 .info = {
578 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
579 .type = FE_ATSC,
580 .frequency_min= 54000000,
581 .frequency_max= 858000000,
582 .frequency_stepsize= 62500,
583 /* Symbol rate is for all VSB modes need to check QAM */
584 .symbol_rate_min = 10762000,
585 .symbol_rate_max = 10762000,
586 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
587 },
588 .init = lgdt3302_init,
589 .set_frontend = lgdt3302_set_parameters,
590 .get_frontend = lgdt3302_get_frontend,
591 .get_tune_settings = lgdt3302_get_tune_settings,
592 .read_status = lgdt3302_read_status,
593 .read_ber = lgdt3302_read_ber,
594 .read_signal_strength = lgdt3302_read_signal_strength,
595 .read_snr = lgdt3302_read_snr,
596 .read_ucblocks = lgdt3302_read_ucblocks,
597 .release = lgdt3302_release,
598};
599
600MODULE_DESCRIPTION("LGDT3302 [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
601MODULE_AUTHOR("Wilson Michaels");
602MODULE_LICENSE("GPL");
603
604EXPORT_SYMBOL(lgdt3302_attach);
605
606/*
607 * Local variables:
608 * c-basic-offset: 8
609 * compile-command: "make DVB=1"
610 * End:
611 */
diff --git a/drivers/media/dvb/frontends/lgdt3302.h b/drivers/media/dvb/frontends/lgdt3302.h
new file mode 100644
index 000000000000..81587a40032b
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302.h
@@ -0,0 +1,49 @@
1/*
2 * $Id: lgdt3302.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
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 */
23
24#ifndef LGDT3302_H
25#define LGDT3302_H
26
27#include <linux/dvb/frontend.h>
28
29struct lgdt3302_config
30{
31 /* The demodulator's i2c address */
32 u8 demod_address;
33 u8 pll_address;
34 struct dvb_pll_desc *pll_desc;
35
36 /* Need to set device param for start_dma */
37 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
38};
39
40extern struct dvb_frontend* lgdt3302_attach(const struct lgdt3302_config* config,
41 struct i2c_adapter* i2c);
42
43#endif /* LGDT3302_H */
44
45/*
46 * Local variables:
47 * c-basic-offset: 8
48 * End:
49 */
diff --git a/drivers/media/dvb/frontends/lgdt3302_priv.h b/drivers/media/dvb/frontends/lgdt3302_priv.h
new file mode 100644
index 000000000000..6193fa7a569d
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3302_priv.h
@@ -0,0 +1,72 @@
1/*
2 * $Id: lgdt3302_priv.h,v 1.2 2005/06/28 23:50:48 mkrufky Exp $
3 *
4 * Support for LGDT3302 (DViCO FustionHDTV 3 Gold) - VSB/QAM
5 *
6 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
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 */
23
24#ifndef _LGDT3302_PRIV_
25#define _LGDT3302_PRIV_
26
27/* i2c control register addresses */
28enum I2C_REG {
29 TOP_CONTROL= 0x00,
30 IRQ_MASK= 0x01,
31 IRQ_STATUS= 0x02,
32 VSB_CARRIER_FREQ0= 0x16,
33 VSB_CARRIER_FREQ1= 0x17,
34 VSB_CARRIER_FREQ2= 0x18,
35 VSB_CARRIER_FREQ3= 0x19,
36 CARRIER_MSEQAM1= 0x1a,
37 CARRIER_MSEQAM2= 0x1b,
38 CARRIER_LOCK= 0x1c,
39 TIMING_RECOVERY= 0x1d,
40 AGC_DELAY0= 0x2a,
41 AGC_DELAY1= 0x2b,
42 AGC_DELAY2= 0x2c,
43 AGC_RF_BANDWIDTH0= 0x2d,
44 AGC_RF_BANDWIDTH1= 0x2e,
45 AGC_RF_BANDWIDTH2= 0x2f,
46 AGC_LOOP_BANDWIDTH0= 0x30,
47 AGC_LOOP_BANDWIDTH1= 0x31,
48 AGC_FUNC_CTRL1= 0x32,
49 AGC_FUNC_CTRL2= 0x33,
50 AGC_FUNC_CTRL3= 0x34,
51 AGC_RFIF_ACC0= 0x39,
52 AGC_RFIF_ACC1= 0x3a,
53 AGC_RFIF_ACC2= 0x3b,
54 AGC_STATUS= 0x3f,
55 SYNC_STATUS_VSB= 0x43,
56 EQPH_ERR0= 0x47,
57 EQ_ERR1= 0x48,
58 EQ_ERR2= 0x49,
59 PH_ERR1= 0x4a,
60 PH_ERR2= 0x4b,
61 DEMUX_CONTROL= 0x66,
62 PACKET_ERR_COUNTER1= 0x6a,
63 PACKET_ERR_COUNTER2= 0x6b,
64};
65
66#endif /* _LGDT3302_PRIV_ */
67
68/*
69 * Local variables:
70 * c-basic-offset: 8
71 * End:
72 */
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
new file mode 100644
index 000000000000..4f396ac8de77
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -0,0 +1,800 @@
1/*
2Driver for Samsung S5H1420 QPSK Demodulator
3
4Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <linux/delay.h>
29
30#include "dvb_frontend.h"
31#include "s5h1420.h"
32
33
34
35#define TONE_FREQ 22000
36
37struct s5h1420_state {
38 struct i2c_adapter* i2c;
39 struct dvb_frontend_ops ops;
40 const struct s5h1420_config* config;
41 struct dvb_frontend frontend;
42
43 u8 postlocked:1;
44 u32 fclk;
45 u32 tunedfreq;
46 fe_code_rate_t fec_inner;
47 u32 symbol_rate;
48};
49
50static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
51static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings);
52
53
54static int debug = 0;
55#define dprintk if (debug) printk
56
57static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
58{
59 u8 buf [] = { reg, data };
60 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
61 int err;
62
63 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
64 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
65 return -EREMOTEIO;
66 }
67
68 return 0;
69}
70
71static u8 s5h1420_readreg (struct s5h1420_state* state, u8 reg)
72{
73 int ret;
74 u8 b0 [] = { reg };
75 u8 b1 [] = { 0 };
76 struct i2c_msg msg1 = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 };
77 struct i2c_msg msg2 = { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 };
78
79 if ((ret = i2c_transfer (state->i2c, &msg1, 1)) != 1)
80 return ret;
81
82 if ((ret = i2c_transfer (state->i2c, &msg2, 1)) != 1)
83 return ret;
84
85 return b1[0];
86}
87
88static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
89{
90 struct s5h1420_state* state = fe->demodulator_priv;
91
92 switch(voltage) {
93 case SEC_VOLTAGE_13:
94 s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
95 break;
96
97 case SEC_VOLTAGE_18:
98 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
99 break;
100
101 case SEC_VOLTAGE_OFF:
102 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
103 break;
104 }
105
106 return 0;
107}
108
109static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
110{
111 struct s5h1420_state* state = fe->demodulator_priv;
112
113 switch(tone) {
114 case SEC_TONE_ON:
115 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
116 break;
117
118 case SEC_TONE_OFF:
119 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
120 break;
121 }
122
123 return 0;
124}
125
126static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
127{
128 struct s5h1420_state* state = fe->demodulator_priv;
129 u8 val;
130 int i;
131 unsigned long timeout;
132 int result = 0;
133
134 /* setup for DISEQC */
135 val = s5h1420_readreg(state, 0x3b);
136 s5h1420_writereg(state, 0x3b, 0x02);
137 msleep(15);
138
139 /* write the DISEQC command bytes */
140 for(i=0; i< cmd->msg_len; i++) {
141 s5h1420_writereg(state, 0x3c + i, cmd->msg[i]);
142 }
143
144 /* kick off transmission */
145 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08);
146
147 /* wait for transmission to complete */
148 timeout = jiffies + ((100*HZ) / 1000);
149 while(time_before(jiffies, timeout)) {
150 if (s5h1420_readreg(state, 0x3b) & 0x08)
151 break;
152
153 msleep(5);
154 }
155 if (time_after(jiffies, timeout))
156 result = -ETIMEDOUT;
157
158 /* restore original settings */
159 s5h1420_writereg(state, 0x3b, val);
160 msleep(15);
161 return result;
162}
163
164static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply)
165{
166 struct s5h1420_state* state = fe->demodulator_priv;
167 u8 val;
168 int i;
169 int length;
170 unsigned long timeout;
171 int result = 0;
172
173 /* setup for DISEQC recieve */
174 val = s5h1420_readreg(state, 0x3b);
175 s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */
176 msleep(15);
177
178 /* wait for reception to complete */
179 timeout = jiffies + ((reply->timeout*HZ) / 1000);
180 while(time_before(jiffies, timeout)) {
181 if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */
182 break;
183
184 msleep(5);
185 }
186 if (time_after(jiffies, timeout)) {
187 result = -ETIMEDOUT;
188 goto exit;
189 }
190
191 /* check error flag - FIXME: not sure what this does - docs do not describe
192 * beyond "error flag for diseqc receive data :( */
193 if (s5h1420_readreg(state, 0x49)) {
194 result = -EIO;
195 goto exit;
196 }
197
198 /* check length */
199 length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
200 if (length > sizeof(reply->msg)) {
201 result = -EOVERFLOW;
202 goto exit;
203 }
204 reply->msg_len = length;
205
206 /* extract data */
207 for(i=0; i< length; i++) {
208 reply->msg[i] = s5h1420_readreg(state, 0x3c + i);
209 }
210
211exit:
212 /* restore original settings */
213 s5h1420_writereg(state, 0x3b, val);
214 msleep(15);
215 return result;
216}
217
218static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
219{
220 struct s5h1420_state* state = fe->demodulator_priv;
221 u8 val;
222 int result = 0;
223 unsigned long timeout;
224
225 /* setup for tone burst */
226 val = s5h1420_readreg(state, 0x3b);
227 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
228
229 /* set value for B position if requested */
230 if (minicmd == SEC_MINI_B) {
231 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
232 }
233 msleep(15);
234
235 /* start transmission */
236 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
237
238 /* wait for transmission to complete */
239 timeout = jiffies + ((20*HZ) / 1000);
240 while(time_before(jiffies, timeout)) {
241 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
242 break;
243
244 msleep(5);
245 }
246 if (time_after(jiffies, timeout))
247 result = -ETIMEDOUT;
248
249 /* restore original settings */
250 s5h1420_writereg(state, 0x3b, val);
251 msleep(15);
252 return result;
253}
254
255static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
256{
257 u8 val;
258 fe_status_t status = 0;
259
260 val = s5h1420_readreg(state, 0x14);
261 if (val & 0x02)
262 status |= FE_HAS_SIGNAL; // FIXME: not sure if this is right
263 if (val & 0x01)
264 status |= FE_HAS_CARRIER; // FIXME: not sure if this is right
265 val = s5h1420_readreg(state, 0x36);
266 if (val & 0x01)
267 status |= FE_HAS_VITERBI;
268 if (val & 0x20)
269 status |= FE_HAS_SYNC;
270 if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC))
271 status |= FE_HAS_LOCK;
272
273 return status;
274}
275
276static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
277{
278 struct s5h1420_state* state = fe->demodulator_priv;
279 u8 val;
280
281 if (status == NULL)
282 return -EINVAL;
283
284 /* determine lock state */
285 *status = s5h1420_get_status_bits(state);
286
287 /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion,
288 wait a bit and check again */
289 if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
290 val = s5h1420_readreg(state, 0x32);
291 if ((val & 0x07) == 0x03) {
292 if (val & 0x08)
293 s5h1420_writereg(state, 0x31, 0x13);
294 else
295 s5h1420_writereg(state, 0x31, 0x1b);
296
297 /* wait a bit then update lock status */
298 mdelay(200);
299 *status = s5h1420_get_status_bits(state);
300 }
301 }
302
303 /* perform post lock setup */
304 if ((*status & FE_HAS_LOCK) && (!state->postlocked)) {
305
306 /* calculate the data rate */
307 u32 tmp = s5h1420_getsymbolrate(state);
308 switch(s5h1420_readreg(state, 0x32) & 0x07) {
309 case 0:
310 tmp = (tmp * 2 * 1) / 2;
311 break;
312
313 case 1:
314 tmp = (tmp * 2 * 2) / 3;
315 break;
316
317 case 2:
318 tmp = (tmp * 2 * 3) / 4;
319 break;
320
321 case 3:
322 tmp = (tmp * 2 * 5) / 6;
323 break;
324
325 case 4:
326 tmp = (tmp * 2 * 6) / 7;
327 break;
328
329 case 5:
330 tmp = (tmp * 2 * 7) / 8;
331 break;
332 }
333 tmp = state->fclk / tmp;
334
335 /* set the MPEG_CLK_INTL for the calculated data rate */
336 if (tmp < 4)
337 val = 0x00;
338 else if (tmp < 8)
339 val = 0x01;
340 else if (tmp < 12)
341 val = 0x02;
342 else if (tmp < 16)
343 val = 0x03;
344 else if (tmp < 24)
345 val = 0x04;
346 else if (tmp < 32)
347 val = 0x05;
348 else
349 val = 0x06;
350 s5h1420_writereg(state, 0x22, val);
351
352 /* DC freeze */
353 s5h1420_writereg(state, 0x1f, s5h1420_readreg(state, 0x1f) | 0x01);
354
355 /* kicker disable + remove DC offset */
356 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) & 0x6f);
357
358 /* post-lock processing has been done! */
359 state->postlocked = 1;
360 }
361
362 return 0;
363}
364
365static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
366{
367 struct s5h1420_state* state = fe->demodulator_priv;
368
369 s5h1420_writereg(state, 0x46, 0x1d);
370 mdelay(25);
371 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
372}
373
374static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
375{
376 struct s5h1420_state* state = fe->demodulator_priv;
377
378 u8 val = 0xff - s5h1420_readreg(state, 0x15);
379
380 return (int) ((val << 8) | val);
381}
382
383static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
384{
385 struct s5h1420_state* state = fe->demodulator_priv;
386
387 s5h1420_writereg(state, 0x46, 0x1f);
388 mdelay(25);
389 return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
390}
391
392static void s5h1420_reset(struct s5h1420_state* state)
393{
394 s5h1420_writereg (state, 0x01, 0x08);
395 s5h1420_writereg (state, 0x01, 0x00);
396 udelay(10);
397}
398
399static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
400{
401 u64 val;
402
403 val = (p->u.qpsk.symbol_rate / 1000) * (1<<24);
404 if (p->u.qpsk.symbol_rate <= 21000000) {
405 val *= 2;
406 }
407 do_div(val, (state->fclk / 1000));
408
409 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0x7f);
410 s5h1420_writereg(state, 0x11, val >> 16);
411 s5h1420_writereg(state, 0x12, val >> 8);
412 s5h1420_writereg(state, 0x13, val & 0xff);
413 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x80);
414}
415
416static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
417{
418 u64 val;
419 int sampling = 2;
420
421 if (s5h1420_readreg(state, 0x05) & 0x2)
422 sampling = 1;
423
424 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
425 val = s5h1420_readreg(state, 0x11) << 16;
426 val |= s5h1420_readreg(state, 0x12) << 8;
427 val |= s5h1420_readreg(state, 0x13);
428 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
429
430 val *= (state->fclk / 1000);
431 do_div(val, ((1<<24) * sampling));
432
433 return (u32) (val * 1000);
434}
435
436static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
437{
438 int val;
439
440 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
441 * divide fclk by 1000000 to get the correct value. */
442 val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
443
444 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0xbf);
445 s5h1420_writereg(state, 0x0e, val >> 16);
446 s5h1420_writereg(state, 0x0f, val >> 8);
447 s5h1420_writereg(state, 0x10, val & 0xff);
448 s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x40);
449}
450
451static int s5h1420_getfreqoffset(struct s5h1420_state* state)
452{
453 int val;
454
455 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
456 val = s5h1420_readreg(state, 0x0e) << 16;
457 val |= s5h1420_readreg(state, 0x0f) << 8;
458 val |= s5h1420_readreg(state, 0x10);
459 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
460
461 if (val & 0x800000)
462 val |= 0xff000000;
463
464 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
465 * divide fclk by 1000000 to get the correct value. */
466 val = - ((val * (state->fclk/1000000)) / (1<<24));
467
468 return val;
469}
470
471static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
472{
473 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
474 s5h1420_writereg(state, 0x31, 0x00);
475 s5h1420_writereg(state, 0x30, 0x3f);
476 } else {
477 switch(p->u.qpsk.fec_inner) {
478 case FEC_1_2:
479 s5h1420_writereg(state, 0x31, 0x10);
480 s5h1420_writereg(state, 0x30, 0x01);
481 break;
482
483 case FEC_2_3:
484 s5h1420_writereg(state, 0x31, 0x11);
485 s5h1420_writereg(state, 0x30, 0x02);
486 break;
487
488 case FEC_3_4:
489 s5h1420_writereg(state, 0x31, 0x12);
490 s5h1420_writereg(state, 0x30, 0x04);
491 break;
492
493 case FEC_5_6:
494 s5h1420_writereg(state, 0x31, 0x13);
495 s5h1420_writereg(state, 0x30, 0x08);
496 break;
497
498 case FEC_6_7:
499 s5h1420_writereg(state, 0x31, 0x14);
500 s5h1420_writereg(state, 0x30, 0x10);
501 break;
502
503 case FEC_7_8:
504 s5h1420_writereg(state, 0x31, 0x15);
505 s5h1420_writereg(state, 0x30, 0x20);
506 break;
507
508 default:
509 return;
510 }
511 }
512}
513
514static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
515{
516 switch(s5h1420_readreg(state, 0x32) & 0x07) {
517 case 0:
518 return FEC_1_2;
519
520 case 1:
521 return FEC_2_3;
522
523 case 2:
524 return FEC_3_4;
525
526 case 3:
527 return FEC_5_6;
528
529 case 4:
530 return FEC_6_7;
531
532 case 5:
533 return FEC_7_8;
534 }
535
536 return FEC_NONE;
537}
538
539static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
540{
541 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
542 s5h1420_writereg(state, 0x31, 0x00);
543 s5h1420_writereg(state, 0x30, 0x3f);
544 } else {
545 u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
546 tmp |= 0x10;
547
548 if (p->inversion == INVERSION_ON)
549 tmp |= 0x80;
550
551 s5h1420_writereg(state, 0x31, tmp);
552 }
553}
554
555static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
556{
557 if (s5h1420_readreg(state, 0x32) & 0x08)
558 return INVERSION_ON;
559
560 return INVERSION_OFF;
561}
562
563static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
564{
565 struct s5h1420_state* state = fe->demodulator_priv;
566 u32 frequency_delta;
567 struct dvb_frontend_tune_settings fesettings;
568
569 /* check if we should do a fast-tune */
570 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
571 s5h1420_get_tune_settings(fe, &fesettings);
572 frequency_delta = p->frequency - state->tunedfreq;
573 if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) &&
574 (frequency_delta != 0) &&
575 (state->fec_inner == p->u.qpsk.fec_inner) &&
576 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
577
578 s5h1420_setfreqoffset(state, frequency_delta);
579 return 0;
580 }
581
582 /* first of all, software reset */
583 s5h1420_reset(state);
584
585 /* set tuner PLL */
586 if (state->config->pll_set) {
587 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
588 state->config->pll_set(fe, p, &state->tunedfreq);
589 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
590 }
591
592 /* set s5h1420 fclk PLL according to desired symbol rate */
593 if (p->u.qpsk.symbol_rate > 28000000) {
594 state->fclk = 88000000;
595 s5h1420_writereg(state, 0x03, 0x50);
596 s5h1420_writereg(state, 0x04, 0x40);
597 s5h1420_writereg(state, 0x05, 0xae);
598 } else if (p->u.qpsk.symbol_rate > 21000000) {
599 state->fclk = 59000000;
600 s5h1420_writereg(state, 0x03, 0x33);
601 s5h1420_writereg(state, 0x04, 0x40);
602 s5h1420_writereg(state, 0x05, 0xae);
603 } else {
604 state->fclk = 88000000;
605 s5h1420_writereg(state, 0x03, 0x50);
606 s5h1420_writereg(state, 0x04, 0x40);
607 s5h1420_writereg(state, 0x05, 0xac);
608 }
609
610 /* set misc registers */
611 s5h1420_writereg(state, 0x02, 0x00);
612 s5h1420_writereg(state, 0x07, 0xb0);
613 s5h1420_writereg(state, 0x0a, 0x67);
614 s5h1420_writereg(state, 0x0b, 0x78);
615 s5h1420_writereg(state, 0x0c, 0x48);
616 s5h1420_writereg(state, 0x0d, 0x6b);
617 s5h1420_writereg(state, 0x2e, 0x8e);
618 s5h1420_writereg(state, 0x35, 0x33);
619 s5h1420_writereg(state, 0x38, 0x01);
620 s5h1420_writereg(state, 0x39, 0x7d);
621 s5h1420_writereg(state, 0x3a, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
622 s5h1420_writereg(state, 0x3c, 0x00);
623 s5h1420_writereg(state, 0x45, 0x61);
624 s5h1420_writereg(state, 0x46, 0x1d);
625
626 /* start QPSK */
627 s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
628
629 /* set the frequency offset to adjust for PLL inaccuracy */
630 s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq);
631
632 /* set the reset of the parameters */
633 s5h1420_setsymbolrate(state, p);
634 s5h1420_setinversion(state, p);
635 s5h1420_setfec(state, p);
636
637 state->fec_inner = p->u.qpsk.fec_inner;
638 state->symbol_rate = p->u.qpsk.symbol_rate;
639 state->postlocked = 0;
640 return 0;
641}
642
643static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
644{
645 struct s5h1420_state* state = fe->demodulator_priv;
646
647 p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state);
648 p->inversion = s5h1420_getinversion(state);
649 p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state);
650 p->u.qpsk.fec_inner = s5h1420_getfec(state);
651
652 return 0;
653}
654
655static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
656{
657 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
658 fesettings->min_delay_ms = 50;
659 fesettings->step_size = 2000;
660 fesettings->max_drift = 8000;
661 } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
662 fesettings->min_delay_ms = 100;
663 fesettings->step_size = 1500;
664 fesettings->max_drift = 9000;
665 } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
666 fesettings->min_delay_ms = 100;
667 fesettings->step_size = 1000;
668 fesettings->max_drift = 8000;
669 } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
670 fesettings->min_delay_ms = 100;
671 fesettings->step_size = 500;
672 fesettings->max_drift = 7000;
673 } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
674 fesettings->min_delay_ms = 200;
675 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
676 fesettings->max_drift = 14 * fesettings->step_size;
677 } else {
678 fesettings->min_delay_ms = 200;
679 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
680 fesettings->max_drift = 18 * fesettings->step_size;
681 }
682
683 return 0;
684}
685
686static int s5h1420_init (struct dvb_frontend* fe)
687{
688 struct s5h1420_state* state = fe->demodulator_priv;
689
690 /* disable power down and do reset */
691 s5h1420_writereg(state, 0x02, 0x10);
692 msleep(10);
693 s5h1420_reset(state);
694
695 /* init PLL */
696 if (state->config->pll_init) {
697 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
698 state->config->pll_init(fe);
699 s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
700 }
701
702 return 0;
703}
704
705static int s5h1420_sleep(struct dvb_frontend* fe)
706{
707 struct s5h1420_state* state = fe->demodulator_priv;
708
709 return s5h1420_writereg(state, 0x02, 0x12);
710}
711
712static void s5h1420_release(struct dvb_frontend* fe)
713{
714 struct s5h1420_state* state = fe->demodulator_priv;
715 kfree(state);
716}
717
718static struct dvb_frontend_ops s5h1420_ops;
719
720struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c)
721{
722 struct s5h1420_state* state = NULL;
723 u8 identity;
724
725 /* allocate memory for the internal state */
726 state = kmalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
727 if (state == NULL)
728 goto error;
729
730 /* setup the state */
731 state->config = config;
732 state->i2c = i2c;
733 memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
734 state->postlocked = 0;
735 state->fclk = 88000000;
736 state->tunedfreq = 0;
737 state->fec_inner = FEC_NONE;
738 state->symbol_rate = 0;
739
740 /* check if the demod is there + identify it */
741 identity = s5h1420_readreg(state, 0x00);
742 if (identity != 0x03)
743 goto error;
744
745 /* create dvb_frontend */
746 state->frontend.ops = &state->ops;
747 state->frontend.demodulator_priv = state;
748 return &state->frontend;
749
750error:
751 kfree(state);
752 return NULL;
753}
754
755static struct dvb_frontend_ops s5h1420_ops = {
756
757 .info = {
758 .name = "Samsung S5H1420 DVB-S",
759 .type = FE_QPSK,
760 .frequency_min = 950000,
761 .frequency_max = 2150000,
762 .frequency_stepsize = 125, /* kHz for QPSK frontends */
763 .frequency_tolerance = 29500,
764 .symbol_rate_min = 1000000,
765 .symbol_rate_max = 45000000,
766 /* .symbol_rate_tolerance = ???,*/
767 .caps = FE_CAN_INVERSION_AUTO |
768 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
769 FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
770 FE_CAN_QPSK
771 },
772
773 .release = s5h1420_release,
774
775 .init = s5h1420_init,
776 .sleep = s5h1420_sleep,
777
778 .set_frontend = s5h1420_set_frontend,
779 .get_frontend = s5h1420_get_frontend,
780 .get_tune_settings = s5h1420_get_tune_settings,
781
782 .read_status = s5h1420_read_status,
783 .read_ber = s5h1420_read_ber,
784 .read_signal_strength = s5h1420_read_signal_strength,
785 .read_ucblocks = s5h1420_read_ucblocks,
786
787 .diseqc_send_master_cmd = s5h1420_send_master_cmd,
788 .diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
789 .diseqc_send_burst = s5h1420_send_burst,
790 .set_tone = s5h1420_set_tone,
791 .set_voltage = s5h1420_set_voltage,
792};
793
794module_param(debug, int, 0644);
795
796MODULE_DESCRIPTION("Samsung S5H1420 DVB-S Demodulator driver");
797MODULE_AUTHOR("Andrew de Quincey");
798MODULE_LICENSE("GPL");
799
800EXPORT_SYMBOL(s5h1420_attach);
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
new file mode 100644
index 000000000000..b687fc77ceb3
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -0,0 +1,41 @@
1/*
2 Driver for S5H1420 QPSK Demodulators
3
4 Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
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
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef S5H1420_H
24#define S5H1420_H
25
26#include <linux/dvb/frontend.h>
27
28struct s5h1420_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* PLL maintenance */
34 int (*pll_init)(struct dvb_frontend* fe);
35 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
36};
37
38extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
39 struct i2c_adapter* i2c);
40
41#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
index e681263bf079..928aca052afe 100644
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -617,7 +617,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
617 617
618 /* wait for WGAGC lock */ 618 /* wait for WGAGC lock */
619 starttime = jiffies; 619 starttime = jiffies;
620 timeout = jiffies + (200 * HZ) / 1000; 620 timeout = jiffies + msecs_to_jiffies(2000);
621 while (time_before(jiffies, timeout)) { 621 while (time_before(jiffies, timeout)) {
622 msleep(10); 622 msleep(10);
623 if (stv0297_readreg(state, 0x43) & 0x08) 623 if (stv0297_readreg(state, 0x43) & 0x08)
@@ -629,7 +629,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
629 msleep(20); 629 msleep(20);
630 630
631 /* wait for equaliser partial convergence */ 631 /* wait for equaliser partial convergence */
632 timeout = jiffies + (50 * HZ) / 1000; 632 timeout = jiffies + msecs_to_jiffies(500);
633 while (time_before(jiffies, timeout)) { 633 while (time_before(jiffies, timeout)) {
634 msleep(10); 634 msleep(10);
635 635
@@ -642,7 +642,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
642 } 642 }
643 643
644 /* wait for equaliser full convergence */ 644 /* wait for equaliser full convergence */
645 timeout = jiffies + (delay * HZ) / 1000; 645 timeout = jiffies + msecs_to_jiffies(delay);
646 while (time_before(jiffies, timeout)) { 646 while (time_before(jiffies, timeout)) {
647 msleep(10); 647 msleep(10);
648 648
@@ -659,7 +659,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
659 stv0297_writereg_mask(state, 0x88, 8, 0); 659 stv0297_writereg_mask(state, 0x88, 8, 0);
660 660
661 /* wait for main lock */ 661 /* wait for main lock */
662 timeout = jiffies + (20 * HZ) / 1000; 662 timeout = jiffies + msecs_to_jiffies(20);
663 while (time_before(jiffies, timeout)) { 663 while (time_before(jiffies, timeout)) {
664 msleep(10); 664 msleep(10);
665 665
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 0beb370792ae..ab0c032472cc 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -49,10 +49,8 @@ struct tda1004x_state {
49 /* private demod data */ 49 /* private demod data */
50 u8 initialised; 50 u8 initialised;
51 enum tda1004x_demod demod_type; 51 enum tda1004x_demod demod_type;
52 u8 fw_version;
53}; 52};
54 53
55
56static int debug; 54static int debug;
57#define dprintk(args...) \ 55#define dprintk(args...) \
58 do { \ 56 do { \
@@ -122,6 +120,8 @@ static int debug;
122#define TDA10046H_GPIO_OUT_SEL 0x41 120#define TDA10046H_GPIO_OUT_SEL 0x41
123#define TDA10046H_GPIO_SELECT 0x42 121#define TDA10046H_GPIO_SELECT 0x42
124#define TDA10046H_AGC_CONF 0x43 122#define TDA10046H_AGC_CONF 0x43
123#define TDA10046H_AGC_THR 0x44
124#define TDA10046H_AGC_RENORM 0x45
125#define TDA10046H_AGC_GAINS 0x46 125#define TDA10046H_AGC_GAINS 0x46
126#define TDA10046H_AGC_TUN_MIN 0x47 126#define TDA10046H_AGC_TUN_MIN 0x47
127#define TDA10046H_AGC_TUN_MAX 0x48 127#define TDA10046H_AGC_TUN_MAX 0x48
@@ -274,14 +274,26 @@ static int tda10046h_set_bandwidth(struct tda1004x_state *state,
274 switch (bandwidth) { 274 switch (bandwidth) {
275 case BANDWIDTH_6_MHZ: 275 case BANDWIDTH_6_MHZ:
276 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz)); 276 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
277 if (state->config->if_freq == TDA10046_FREQ_045) {
278 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09);
279 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f);
280 }
277 break; 281 break;
278 282
279 case BANDWIDTH_7_MHZ: 283 case BANDWIDTH_7_MHZ:
280 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz)); 284 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
285 if (state->config->if_freq == TDA10046_FREQ_045) {
286 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
287 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79);
288 }
281 break; 289 break;
282 290
283 case BANDWIDTH_8_MHZ: 291 case BANDWIDTH_8_MHZ:
284 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz)); 292 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
293 if (state->config->if_freq == TDA10046_FREQ_045) {
294 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
295 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
296 }
285 break; 297 break;
286 298
287 default: 299 default:
@@ -315,20 +327,35 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
315 memcpy(buf + 1, mem + pos, tx_size); 327 memcpy(buf + 1, mem + pos, tx_size);
316 fw_msg.len = tx_size + 1; 328 fw_msg.len = tx_size + 1;
317 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) { 329 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
318 printk("tda1004x: Error during firmware upload\n"); 330 printk(KERN_ERR "tda1004x: Error during firmware upload\n");
319 return -EIO; 331 return -EIO;
320 } 332 }
321 pos += tx_size; 333 pos += tx_size;
322 334
323 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); 335 dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
324 } 336 }
337 // give the DSP a chance to settle 03/10/05 Hac
338 msleep(100);
325 339
326 return 0; 340 return 0;
327} 341}
328 342
329static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion) 343static int tda1004x_check_upload_ok(struct tda1004x_state *state)
330{ 344{
331 u8 data1, data2; 345 u8 data1, data2;
346 unsigned long timeout;
347
348 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
349 timeout = jiffies + 2 * HZ;
350 while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
351 if (time_after(jiffies, timeout)) {
352 printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
353 break;
354 }
355 msleep(1);
356 }
357 } else
358 msleep(100);
332 359
333 // check upload was OK 360 // check upload was OK
334 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP 361 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
@@ -336,9 +363,11 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
336 363
337 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); 364 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
338 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); 365 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
339 if ((data1 != 0x67) || (data2 != dspVersion)) 366 if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
367 printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
340 return -EIO; 368 return -EIO;
341 369 }
370 printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
342 return 0; 371 return 0;
343} 372}
344 373
@@ -349,14 +378,14 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
349 const struct firmware *fw; 378 const struct firmware *fw;
350 379
351 /* don't re-upload unless necessary */ 380 /* don't re-upload unless necessary */
352 if (tda1004x_check_upload_ok(state, 0x2c) == 0) 381 if (tda1004x_check_upload_ok(state) == 0)
353 return 0; 382 return 0;
354 383
355 /* request the firmware, this will block until someone uploads it */ 384 /* request the firmware, this will block until someone uploads it */
356 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); 385 printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
357 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); 386 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
358 if (ret) { 387 if (ret) {
359 printk("tda1004x: no firmware upload (timeout or file not found?)\n"); 388 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
360 return ret; 389 return ret;
361 } 390 }
362 391
@@ -370,95 +399,93 @@ static int tda10045_fwupload(struct dvb_frontend* fe)
370 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ); 399 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
371 400
372 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN); 401 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
402 release_firmware(fw);
373 if (ret) 403 if (ret)
374 return ret; 404 return ret;
375 printk("tda1004x: firmware upload complete\n"); 405 printk(KERN_INFO "tda1004x: firmware upload complete\n");
376 406
377 /* wait for DSP to initialise */ 407 /* wait for DSP to initialise */
378 /* DSPREADY doesn't seem to work on the TDA10045H */ 408 /* DSPREADY doesn't seem to work on the TDA10045H */
379 msleep(100); 409 msleep(100);
380 410
381 return tda1004x_check_upload_ok(state, 0x2c); 411 return tda1004x_check_upload_ok(state);
382} 412}
383 413
384static int tda10046_get_fw_version(struct tda1004x_state *state, 414static void tda10046_init_plls(struct dvb_frontend* fe)
385 const struct firmware *fw)
386{ 415{
387 const unsigned char pattern[] = { 0x67, 0x00, 0x50, 0x62, 0x5e, 0x18, 0x67 }; 416 struct tda1004x_state* state = fe->demodulator_priv;
388 unsigned int i;
389
390 /* area guessed from firmware v20, v21 and v25 */
391 for (i = 0x660; i < 0x700; i++) {
392 if (!memcmp(&fw->data[i], pattern, sizeof(pattern))) {
393 state->fw_version = fw->data[i + sizeof(pattern)];
394 printk(KERN_INFO "tda1004x: using firmware v%02x\n",
395 state->fw_version);
396 return 0;
397 }
398 }
399 417
400 return -EINVAL; 418 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
419 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
420 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
421 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
422 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
423 } else {
424 dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
425 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
426 }
427 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
428 switch (state->config->if_freq) {
429 case TDA10046_FREQ_3617:
430 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
431 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
432 break;
433 case TDA10046_FREQ_3613:
434 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
435 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13);
436 break;
437 case TDA10046_FREQ_045:
438 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
439 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
440 break;
441 case TDA10046_FREQ_052:
442 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
443 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06);
444 break;
445 }
446 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
401} 447}
402 448
403static int tda10046_fwupload(struct dvb_frontend* fe) 449static int tda10046_fwupload(struct dvb_frontend* fe)
404{ 450{
405 struct tda1004x_state* state = fe->demodulator_priv; 451 struct tda1004x_state* state = fe->demodulator_priv;
406 unsigned long timeout;
407 int ret; 452 int ret;
408 const struct firmware *fw; 453 const struct firmware *fw;
409 454
410 /* reset + wake up chip */ 455 /* reset + wake up chip */
411 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); 456 tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
412 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); 457 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
413 msleep(100); 458 /* let the clocks recover from sleep */
459 msleep(5);
414 460
415 /* don't re-upload unless necessary */ 461 /* don't re-upload unless necessary */
416 if (tda1004x_check_upload_ok(state, state->fw_version) == 0) 462 if (tda1004x_check_upload_ok(state) == 0)
417 return 0; 463 return 0;
418 464
419 /* request the firmware, this will block until someone uploads it */
420 printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
421 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
422 if (ret) {
423 printk("tda1004x: no firmware upload (timeout or file not found?)\n");
424 return ret;
425 }
426
427 if (fw->size < 24478) { /* size of firmware v20, which is the smallest of v20, v21 and v25 */
428 printk("tda1004x: firmware file seems to be too small (%d bytes)\n", fw->size);
429 return -EINVAL;
430 }
431
432 ret = tda10046_get_fw_version(state, fw);
433 if (ret < 0) {
434 printk("tda1004x: unable to find firmware version\n");
435 return ret;
436 }
437
438 /* set parameters */ 465 /* set parameters */
439 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); 466 tda10046_init_plls(fe);
440 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); 467
441 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); 468 if (state->config->request_firmware != NULL) {
442 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); 469 /* request the firmware, this will block until someone uploads it */
443 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); 470 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
444 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST 471 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
445 472 if (ret) {
446 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); 473 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
447 if (ret) 474 return ret;
448 return ret;
449 printk("tda1004x: firmware upload complete\n");
450
451 /* wait for DSP to initialise */
452 timeout = jiffies + HZ;
453 while (!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
454 if (time_after(jiffies, timeout)) {
455 printk("tda1004x: DSP failed to initialised.\n");
456 return -EIO;
457 } 475 }
458 msleep(1); 476 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
477 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
478 release_firmware(fw);
479 if (ret)
480 return ret;
481 } else {
482 /* boot from firmware eeprom */
483 /* Hac Note: we might need to do some GPIO Magic here */
484 printk(KERN_INFO "tda1004x: booting from eeprom\n");
485 tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
486 msleep(300);
459 } 487 }
460 488 return tda1004x_check_upload_ok(state);
461 return tda1004x_check_upload_ok(state, state->fw_version);
462} 489}
463 490
464static int tda1004x_encode_fec(int fec) 491static int tda1004x_encode_fec(int fec)
@@ -560,12 +587,10 @@ static int tda10046_init(struct dvb_frontend* fe)
560 587
561 if (tda10046_fwupload(fe)) { 588 if (tda10046_fwupload(fe)) {
562 printk("tda1004x: firmware upload failed\n"); 589 printk("tda1004x: firmware upload failed\n");
563 return -EIO; 590 return -EIO;
564 } 591 }
565 592
566 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); // wake up the chip 593 // Init the tuner PLL
567
568 // Init the PLL
569 if (state->config->pll_init) { 594 if (state->config->pll_init) {
570 tda1004x_enable_tuner_i2c(state); 595 tda1004x_enable_tuner_i2c(state);
571 state->config->pll_init(fe); 596 state->config->pll_init(fe);
@@ -574,32 +599,44 @@ static int tda10046_init(struct dvb_frontend* fe)
574 599
575 // tda setup 600 // tda setup
576 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer 601 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
577 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0x40); 602 tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream
578 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream 603 tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
579 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer 604
580 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 605 tda10046_init_plls(fe);
581 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); // PLL P = N = 0 606 switch (state->config->agc_config) {
582 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99 607 case TDA10046_AGC_DEFAULT:
583 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221 608 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
584 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // } 609 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
585 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0); // AGC setup 610 break;
586 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities 611 case TDA10046_AGC_IFO_AUTO_NEG:
612 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
613 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
614 break;
615 case TDA10046_AGC_IFO_AUTO_POS:
616 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
617 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities
618 break;
619 case TDA10046_AGC_TDA827X:
620 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
621 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
622 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize
623 tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
624 break;
625 }
626 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
587 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } 627 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
588 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values 628 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
589 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } 629 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
590 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } 630 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
591 tda1004x_write_mask(state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
592 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1 631 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
593 tda1004x_write_mask(state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm 632 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
594 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config 633 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
595 tda1004x_write_mask(state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config 634 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
596 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN 635 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
636
597 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup 637 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
598 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config 638 tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
599 tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select 639 tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select
600 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
601
602 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
603 640
604 state->initialised = 1; 641 state->initialised = 1;
605 return 0; 642 return 0;
@@ -629,9 +666,6 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
629 state->config->pll_set(fe, fe_params); 666 state->config->pll_set(fe, fe_params);
630 tda1004x_disable_tuner_i2c(state); 667 tda1004x_disable_tuner_i2c(state);
631 668
632 if (state->demod_type == TDA1004X_DEMOD_TDA10046)
633 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
634
635 // Hardcoded to use auto as much as possible on the TDA10045 as it 669 // Hardcoded to use auto as much as possible on the TDA10045 as it
636 // is very unreliable if AUTO mode is _not_ used. 670 // is very unreliable if AUTO mode is _not_ used.
637 if (state->demod_type == TDA1004X_DEMOD_TDA10045) { 671 if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
@@ -1089,6 +1123,11 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1089 break; 1123 break;
1090 1124
1091 case TDA1004X_DEMOD_TDA10046: 1125 case TDA1004X_DEMOD_TDA10046:
1126 if (state->config->pll_sleep != NULL) {
1127 tda1004x_enable_tuner_i2c(state);
1128 state->config->pll_sleep(fe);
1129 tda1004x_disable_tuner_i2c(state);
1130 }
1092 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1131 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1093 break; 1132 break;
1094 } 1133 }
@@ -1100,8 +1139,9 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1100static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) 1139static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1101{ 1140{
1102 fesettings->min_delay_ms = 800; 1141 fesettings->min_delay_ms = 800;
1103 fesettings->step_size = 166667; 1142 /* Drift compensation makes no sense for DVB-T */
1104 fesettings->max_drift = 166667*2; 1143 fesettings->step_size = 0;
1144 fesettings->max_drift = 0;
1105 return 0; 1145 return 0;
1106} 1146}
1107 1147
@@ -1216,7 +1256,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1216 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); 1256 memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1217 state->initialised = 0; 1257 state->initialised = 0;
1218 state->demod_type = TDA1004X_DEMOD_TDA10046; 1258 state->demod_type = TDA1004X_DEMOD_TDA10046;
1219 state->fw_version = 0x20; /* dummy default value */
1220 1259
1221 /* check if the demod is there */ 1260 /* check if the demod is there */
1222 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { 1261 if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index c8e1d54ff262..8659c52647ad 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -26,6 +26,25 @@
26#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h> 27#include <linux/firmware.h>
28 28
29enum tda10046_xtal {
30 TDA10046_XTAL_4M,
31 TDA10046_XTAL_16M,
32};
33
34enum tda10046_agc {
35 TDA10046_AGC_DEFAULT, /* original configuration */
36 TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
37 TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
38 TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
39};
40
41enum tda10046_if {
42 TDA10046_FREQ_3617, /* original config, 36,166 MHZ */
43 TDA10046_FREQ_3613, /* 36,13 MHZ */
44 TDA10046_FREQ_045, /* low IF, 4.0, 4.5, or 5.0 MHZ */
45 TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */
46};
47
29struct tda1004x_config 48struct tda1004x_config
30{ 49{
31 /* the demodulator's i2c address */ 50 /* the demodulator's i2c address */
@@ -37,14 +56,22 @@ struct tda1004x_config
37 /* Does the OCLK signal need inverted? */ 56 /* Does the OCLK signal need inverted? */
38 u8 invert_oclk; 57 u8 invert_oclk;
39 58
40 /* value of N_I2C of the CONF_PLL3 register */ 59 /* Xtal frequency, 4 or 16MHz*/
41 u8 n_i2c; 60 enum tda10046_xtal xtal_freq;
61
62 /* IF frequency */
63 enum tda10046_if if_freq;
64
65 /* AGC configuration */
66 enum tda10046_agc agc_config;
42 67
43 /* PLL maintenance */ 68 /* PLL maintenance */
44 int (*pll_init)(struct dvb_frontend* fe); 69 int (*pll_init)(struct dvb_frontend* fe);
70 void (*pll_sleep)(struct dvb_frontend* fe);
45 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 71 int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
46 72
47 /* request firmware for device */ 73 /* request firmware for device */
74 /* set this to NULL if the card has a firmware EEPROM */
48 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 75 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
49}; 76};
50 77
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
new file mode 100644
index 000000000000..f02842be0d60
--- /dev/null
+++ b/drivers/media/dvb/pluto2/Kconfig
@@ -0,0 +1,16 @@
1config DVB_PLUTO2
2 tristate "Pluto2 cards"
3 depends on DVB_CORE && PCI
4 select I2C
5 select I2C_ALGOBIT
6 select DVB_TDA1004X
7 help
8 Support for PCI cards based on the Pluto2 FPGA like the Satelco
9 Easywatch Mobile Terrestrial DVB-T Receiver.
10
11 Since these cards have no MPEG decoder onboard, they transmit
12 only compressed MPEG data over the PCI bus, so you need
13 an external software decoder to watch TV on your computer.
14
15 Say Y or M if you own such a device and want to use it.
16
diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile
new file mode 100644
index 000000000000..86ca84b2be6e
--- /dev/null
+++ b/drivers/media/dvb/pluto2/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_PLUTO2) = pluto2.o
2
3EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
new file mode 100644
index 000000000000..706e0bcb5ede
--- /dev/null
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -0,0 +1,809 @@
1/*
2 * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T]
3 *
4 * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org>
5 *
6 * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
7 * by Dany Salman <salmandany@yahoo.fr>
8 * Copyright (c) 2004 TDF
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,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26#include <linux/i2c.h>
27#include <linux/i2c-algo-bit.h>
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/pci.h>
32#include <linux/dma-mapping.h>
33
34#include "demux.h"
35#include "dmxdev.h"
36#include "dvb_demux.h"
37#include "dvb_frontend.h"
38#include "dvb_net.h"
39#include "dvbdev.h"
40#include "tda1004x.h"
41
42#define DRIVER_NAME "pluto2"
43
44#define REG_PIDn(n) ((n) << 2) /* PID n pattern registers */
45#define REG_PCAR 0x0020 /* PC address register */
46#define REG_TSCR 0x0024 /* TS ctrl & status */
47#define REG_MISC 0x0028 /* miscellaneous */
48#define REG_MMAC 0x002c /* MSB MAC address */
49#define REG_IMAC 0x0030 /* ISB MAC address */
50#define REG_LMAC 0x0034 /* LSB MAC address */
51#define REG_SPID 0x0038 /* SPI data */
52#define REG_SLCS 0x003c /* serial links ctrl/status */
53
54#define PID0_NOFIL (0x0001 << 16)
55#define PIDn_ENP (0x0001 << 15)
56#define PID0_END (0x0001 << 14)
57#define PID0_AFIL (0x0001 << 13)
58#define PIDn_PID (0x1fff << 0)
59
60#define TSCR_NBPACKETS (0x00ff << 24)
61#define TSCR_DEM (0x0001 << 17)
62#define TSCR_DE (0x0001 << 16)
63#define TSCR_RSTN (0x0001 << 15)
64#define TSCR_MSKO (0x0001 << 14)
65#define TSCR_MSKA (0x0001 << 13)
66#define TSCR_MSKL (0x0001 << 12)
67#define TSCR_OVR (0x0001 << 11)
68#define TSCR_AFUL (0x0001 << 10)
69#define TSCR_LOCK (0x0001 << 9)
70#define TSCR_IACK (0x0001 << 8)
71#define TSCR_ADEF (0x007f << 0)
72
73#define MISC_DVR (0x0fff << 4)
74#define MISC_ALED (0x0001 << 3)
75#define MISC_FRST (0x0001 << 2)
76#define MISC_LED1 (0x0001 << 1)
77#define MISC_LED0 (0x0001 << 0)
78
79#define SPID_SPIDR (0x00ff << 0)
80
81#define SLCS_SCL (0x0001 << 7)
82#define SLCS_SDA (0x0001 << 6)
83#define SLCS_CSN (0x0001 << 2)
84#define SLCS_OVR (0x0001 << 1)
85#define SLCS_SWC (0x0001 << 0)
86
87#define TS_DMA_PACKETS (8)
88#define TS_DMA_BYTES (188 * TS_DMA_PACKETS)
89
90#define I2C_ADDR_TDA10046 0x10
91#define I2C_ADDR_TUA6034 0xc2
92#define NHWFILTERS 8
93
94struct pluto {
95 /* pci */
96 struct pci_dev *pdev;
97 u8 __iomem *io_mem;
98
99 /* dvb */
100 struct dmx_frontend hw_frontend;
101 struct dmx_frontend mem_frontend;
102 struct dmxdev dmxdev;
103 struct dvb_adapter dvb_adapter;
104 struct dvb_demux demux;
105 struct dvb_frontend *fe;
106 struct dvb_net dvbnet;
107 unsigned int full_ts_users;
108 unsigned int users;
109
110 /* i2c */
111 struct i2c_algo_bit_data i2c_bit;
112 struct i2c_adapter i2c_adap;
113 unsigned int i2cbug;
114
115 /* irq */
116 unsigned int overflow;
117
118 /* dma */
119 dma_addr_t dma_addr;
120 u8 dma_buf[TS_DMA_BYTES];
121 u8 dummy[4096];
122};
123
124static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed)
125{
126 return container_of(feed->demux, struct pluto, demux);
127}
128
129static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe)
130{
131 return container_of(fe->dvb, struct pluto, dvb_adapter);
132}
133
134static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
135{
136 return readl(&pluto->io_mem[reg]);
137}
138
139static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
140{
141 writel(val, &pluto->io_mem[reg]);
142}
143
144static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
145{
146 u32 val = readl(&pluto->io_mem[reg]);
147 val &= ~mask;
148 val |= bits;
149 writel(val, &pluto->io_mem[reg]);
150}
151
152static void pluto_setsda(void *data, int state)
153{
154 struct pluto *pluto = data;
155
156 if (state)
157 pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
158 else
159 pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
160}
161
162static void pluto_setscl(void *data, int state)
163{
164 struct pluto *pluto = data;
165
166 if (state)
167 pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
168 else
169 pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
170
171 /* try to detect i2c_inb() to workaround hardware bug:
172 * reset SDA to high after SCL has been set to low */
173 if ((state) && (pluto->i2cbug == 0)) {
174 pluto->i2cbug = 1;
175 } else {
176 if ((!state) && (pluto->i2cbug == 1))
177 pluto_setsda(pluto, 1);
178 pluto->i2cbug = 0;
179 }
180}
181
182static int pluto_getsda(void *data)
183{
184 struct pluto *pluto = data;
185
186 return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
187}
188
189static int pluto_getscl(void *data)
190{
191 struct pluto *pluto = data;
192
193 return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
194}
195
196static void pluto_reset_frontend(struct pluto *pluto, int reenable)
197{
198 u32 val = pluto_readreg(pluto, REG_MISC);
199
200 if (val & MISC_FRST) {
201 val &= ~MISC_FRST;
202 pluto_writereg(pluto, REG_MISC, val);
203 }
204 if (reenable) {
205 val |= MISC_FRST;
206 pluto_writereg(pluto, REG_MISC, val);
207 }
208}
209
210static void pluto_reset_ts(struct pluto *pluto, int reenable)
211{
212 u32 val = pluto_readreg(pluto, REG_TSCR);
213
214 if (val & TSCR_RSTN) {
215 val &= ~TSCR_RSTN;
216 pluto_writereg(pluto, REG_TSCR, val);
217 }
218 if (reenable) {
219 val |= TSCR_RSTN;
220 pluto_writereg(pluto, REG_TSCR, val);
221 }
222}
223
224static void pluto_set_dma_addr(struct pluto *pluto)
225{
226 pluto_writereg(pluto, REG_PCAR, cpu_to_le32(pluto->dma_addr));
227}
228
229static int __devinit pluto_dma_map(struct pluto *pluto)
230{
231 pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf,
232 TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
233
234 return pci_dma_mapping_error(pluto->dma_addr);
235}
236
237static void pluto_dma_unmap(struct pluto *pluto)
238{
239 pci_unmap_single(pluto->pdev, pluto->dma_addr,
240 TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
241}
242
243static int pluto_start_feed(struct dvb_demux_feed *f)
244{
245 struct pluto *pluto = feed_to_pluto(f);
246
247 /* enable PID filtering */
248 if (pluto->users++ == 0)
249 pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0);
250
251 if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
252 pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid);
253 else if (pluto->full_ts_users++ == 0)
254 pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL);
255
256 return 0;
257}
258
259static int pluto_stop_feed(struct dvb_demux_feed *f)
260{
261 struct pluto *pluto = feed_to_pluto(f);
262
263 /* disable PID filtering */
264 if (--pluto->users == 0)
265 pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
266
267 if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
268 pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff);
269 else if (--pluto->full_ts_users == 0)
270 pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0);
271
272 return 0;
273}
274
275static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
276{
277 /* synchronize the DMA transfer with the CPU
278 * first so that we see updated contents. */
279 pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr,
280 TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
281
282 /* Workaround for broken hardware:
283 * [1] On startup NBPACKETS seems to contain an uninitialized value,
284 * but no packets have been transfered.
285 * [2] Sometimes (actually very often) NBPACKETS stays at zero
286 * although one packet has been transfered.
287 */
288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
289 unsigned int i = 0, valid;
290 while (pluto->dma_buf[i] == 0x47)
291 i += 188;
292 valid = i / 188;
293 if (nbpackets != valid) {
294 dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
295 nbpackets, valid);
296 nbpackets = valid;
297 }
298 }
299
300 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
301
302 /* clear the dma buffer. this is needed to be able to identify
303 * new valid ts packets above */
304 memset(pluto->dma_buf, 0, nbpackets * 188);
305
306 /* reset the dma address */
307 pluto_set_dma_addr(pluto);
308
309 /* sync the buffer and give it back to the card */
310 pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr,
311 TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
312}
313
314static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs)
315{
316 struct pluto *pluto = dev_id;
317 u32 tscr;
318
319 /* check whether an interrupt occured on this device */
320 tscr = pluto_readreg(pluto, REG_TSCR);
321 if (!(tscr & (TSCR_DE | TSCR_OVR)))
322 return IRQ_NONE;
323
324 if (tscr == 0xffffffff) {
325 // FIXME: maybe recover somehow
326 dev_err(&pluto->pdev->dev, "card hung up :(\n");
327 return IRQ_HANDLED;
328 }
329
330 /* dma end interrupt */
331 if (tscr & TSCR_DE) {
332 pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24);
333 /* overflow interrupt */
334 if (tscr & TSCR_OVR)
335 pluto->overflow++;
336 if (pluto->overflow) {
337 dev_err(&pluto->pdev->dev, "overflow irq (%d)\n",
338 pluto->overflow);
339 pluto_reset_ts(pluto, 1);
340 pluto->overflow = 0;
341 }
342 } else if (tscr & TSCR_OVR) {
343 pluto->overflow++;
344 }
345
346 /* ACK the interrupt */
347 pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK);
348
349 return IRQ_HANDLED;
350}
351
352static void __devinit pluto_enable_irqs(struct pluto *pluto)
353{
354 u32 val = pluto_readreg(pluto, REG_TSCR);
355
356 /* set the number of packets */
357 val &= ~TSCR_ADEF;
358 val |= TS_DMA_PACKETS / 2;
359 /* disable AFUL and LOCK interrupts */
360 val |= (TSCR_MSKA | TSCR_MSKL);
361 /* enable DMA and OVERFLOW interrupts */
362 val &= ~(TSCR_DEM | TSCR_MSKO);
363 /* clear pending interrupts */
364 val |= TSCR_IACK;
365
366 pluto_writereg(pluto, REG_TSCR, val);
367}
368
369static void pluto_disable_irqs(struct pluto *pluto)
370{
371 u32 val = pluto_readreg(pluto, REG_TSCR);
372
373 /* disable all interrupts */
374 val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL);
375 /* clear pending interrupts */
376 val |= TSCR_IACK;
377
378 pluto_writereg(pluto, REG_TSCR, val);
379}
380
381static int __devinit pluto_hw_init(struct pluto *pluto)
382{
383 pluto_reset_frontend(pluto, 1);
384
385 /* set automatic LED control by FPGA */
386 pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
387
388 /* set data endianess */
389#ifdef __LITTLE_ENDIAN
390 pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
391#else
392 pluto_rw(pluto, REG_PIDn(0), PID0_END, 0);
393#endif
394 /* map DMA and set address */
395 pluto_dma_map(pluto);
396 pluto_set_dma_addr(pluto);
397
398 /* enable interrupts */
399 pluto_enable_irqs(pluto);
400
401 /* reset TS logic */
402 pluto_reset_ts(pluto, 1);
403
404 return 0;
405}
406
407static void pluto_hw_exit(struct pluto *pluto)
408{
409 /* disable interrupts */
410 pluto_disable_irqs(pluto);
411
412 pluto_reset_ts(pluto, 0);
413
414 /* LED: disable automatic control, enable yellow, disable green */
415 pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1);
416
417 /* unmap DMA */
418 pluto_dma_unmap(pluto);
419
420 pluto_reset_frontend(pluto, 0);
421}
422
423static inline u32 divide(u32 numerator, u32 denominator)
424{
425 if (denominator == 0)
426 return ~0;
427
428 return (numerator + denominator / 2) / denominator;
429}
430
431/* LG Innotek TDTE-E001P (Infineon TUA6034) */
432static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe,
433 struct dvb_frontend_parameters *p)
434{
435 struct pluto *pluto = frontend_to_pluto(fe);
436 struct i2c_msg msg;
437 int ret;
438 u8 buf[4];
439 u32 div;
440
441 // Fref = 166.667 Hz
442 // Fref * 3 = 500.000 Hz
443 // IF = 36166667
444 // IF / Fref = 217
445 //div = divide(p->frequency + 36166667, 166667);
446 div = divide(p->frequency * 3, 500000) + 217;
447 buf[0] = (div >> 8) & 0x7f;
448 buf[1] = (div >> 0) & 0xff;
449
450 if (p->frequency < 611000000)
451 buf[2] = 0xb4;
452 else if (p->frequency < 811000000)
453 buf[2] = 0xbc;
454 else
455 buf[2] = 0xf4;
456
457 // VHF: 174-230 MHz
458 // center: 350 MHz
459 // UHF: 470-862 MHz
460 if (p->frequency < 350000000)
461 buf[3] = 0x02;
462 else
463 buf[3] = 0x04;
464
465 if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
466 buf[3] |= 0x08;
467
468 if (sizeof(buf) == 6) {
469 buf[4] = buf[2];
470 buf[4] &= ~0x1c;
471 buf[4] |= 0x18;
472
473 buf[5] = (0 << 7) | (2 << 4);
474 }
475
476 msg.addr = I2C_ADDR_TUA6034 >> 1;
477 msg.flags = 0;
478 msg.buf = buf;
479 msg.len = sizeof(buf);
480
481 ret = i2c_transfer(&pluto->i2c_adap, &msg, 1);
482 if (ret < 0)
483 return ret;
484 else if (ret == 0)
485 return -EREMOTEIO;
486
487 return 0;
488}
489
490static int pluto2_request_firmware(struct dvb_frontend *fe,
491 const struct firmware **fw, char *name)
492{
493 struct pluto *pluto = frontend_to_pluto(fe);
494
495 return request_firmware(fw, name, &pluto->pdev->dev);
496}
497
498static struct tda1004x_config pluto2_fe_config __devinitdata = {
499 .demod_address = I2C_ADDR_TDA10046 >> 1,
500 .invert = 1,
501 .invert_oclk = 0,
502 .xtal_freq = TDA10046_XTAL_16M,
503 .agc_config = TDA10046_AGC_DEFAULT,
504 .if_freq = TDA10046_FREQ_3617,
505 .pll_set = lg_tdtpe001p_pll_set,
506 .pll_sleep = NULL,
507 .request_firmware = pluto2_request_firmware,
508};
509
510static int __devinit frontend_init(struct pluto *pluto)
511{
512 int ret;
513
514 pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap);
515 if (!pluto->fe) {
516 dev_err(&pluto->pdev->dev, "could not attach frontend\n");
517 return -ENODEV;
518 }
519
520 ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe);
521 if (ret < 0) {
522 if (pluto->fe->ops->release)
523 pluto->fe->ops->release(pluto->fe);
524 return ret;
525 }
526
527 return 0;
528}
529
530static void __devinit pluto_read_rev(struct pluto *pluto)
531{
532 u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR;
533 dev_info(&pluto->pdev->dev, "board revision %d.%d\n",
534 (val >> 12) & 0x0f, (val >> 4) & 0xff);
535}
536
537static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
538{
539 u32 val = pluto_readreg(pluto, REG_MMAC);
540 mac[0] = (val >> 8) & 0xff;
541 mac[1] = (val >> 0) & 0xff;
542
543 val = pluto_readreg(pluto, REG_IMAC);
544 mac[2] = (val >> 8) & 0xff;
545 mac[3] = (val >> 0) & 0xff;
546
547 val = pluto_readreg(pluto, REG_LMAC);
548 mac[4] = (val >> 8) & 0xff;
549 mac[5] = (val >> 0) & 0xff;
550
551 dev_info(&pluto->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
552 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
553}
554
555static int __devinit pluto_read_serial(struct pluto *pluto)
556{
557 struct pci_dev *pdev = pluto->pdev;
558 unsigned int i, j;
559 u8 __iomem *cis;
560
561 cis = pci_iomap(pdev, 1, 0);
562 if (!cis)
563 return -EIO;
564
565 dev_info(&pdev->dev, "S/N ");
566
567 for (i = 0xe0; i < 0x100; i += 4) {
568 u32 val = readl(&cis[i]);
569 for (j = 0; j < 32; j += 8) {
570 if ((val & 0xff) == 0xff)
571 goto out;
572 printk("%c", val & 0xff);
573 val >>= 8;
574 }
575 }
576out:
577 printk("\n");
578 pci_iounmap(pdev, cis);
579
580 return 0;
581}
582
583static int __devinit pluto2_probe(struct pci_dev *pdev,
584 const struct pci_device_id *ent)
585{
586 struct pluto *pluto;
587 struct dvb_adapter *dvb_adapter;
588 struct dvb_demux *dvbdemux;
589 struct dmx_demux *dmx;
590 int ret = -ENOMEM;
591
592 pluto = kmalloc(sizeof(struct pluto), GFP_KERNEL);
593 if (!pluto)
594 goto out;
595
596 memset(pluto, 0, sizeof(struct pluto));
597 pluto->pdev = pdev;
598
599 ret = pci_enable_device(pdev);
600 if (ret < 0)
601 goto err_kfree;
602
603 /* enable interrupts */
604 pci_write_config_dword(pdev, 0x6c, 0x8000);
605
606 ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
607 if (ret < 0)
608 goto err_pci_disable_device;
609
610 pci_set_master(pdev);
611
612 ret = pci_request_regions(pdev, DRIVER_NAME);
613 if (ret < 0)
614 goto err_pci_disable_device;
615
616 pluto->io_mem = pci_iomap(pdev, 0, 0x40);
617 if (!pluto->io_mem) {
618 ret = -EIO;
619 goto err_pci_release_regions;
620 }
621
622 pci_set_drvdata(pdev, pluto);
623
624 ret = request_irq(pdev->irq, pluto_irq, SA_SHIRQ, DRIVER_NAME, pluto);
625 if (ret < 0)
626 goto err_pci_iounmap;
627
628 ret = pluto_hw_init(pluto);
629 if (ret < 0)
630 goto err_free_irq;
631
632 /* i2c */
633 i2c_set_adapdata(&pluto->i2c_adap, pluto);
634 strcpy(pluto->i2c_adap.name, DRIVER_NAME);
635 pluto->i2c_adap.owner = THIS_MODULE;
636 pluto->i2c_adap.id = I2C_ALGO_BIT;
637 pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
638 pluto->i2c_adap.dev.parent = &pdev->dev;
639 pluto->i2c_adap.algo_data = &pluto->i2c_bit;
640 pluto->i2c_bit.data = pluto;
641 pluto->i2c_bit.setsda = pluto_setsda;
642 pluto->i2c_bit.setscl = pluto_setscl;
643 pluto->i2c_bit.getsda = pluto_getsda;
644 pluto->i2c_bit.getscl = pluto_getscl;
645 pluto->i2c_bit.udelay = 10;
646 pluto->i2c_bit.timeout = 10;
647
648 /* Raise SCL and SDA */
649 pluto_setsda(pluto, 1);
650 pluto_setscl(pluto, 1);
651
652 ret = i2c_bit_add_bus(&pluto->i2c_adap);
653 if (ret < 0)
654 goto err_pluto_hw_exit;
655
656 /* dvb */
657 ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE);
658 if (ret < 0)
659 goto err_i2c_bit_del_bus;
660
661 dvb_adapter = &pluto->dvb_adapter;
662
663 pluto_read_rev(pluto);
664 pluto_read_serial(pluto);
665 pluto_read_mac(pluto, dvb_adapter->proposed_mac);
666
667 dvbdemux = &pluto->demux;
668 dvbdemux->filternum = 256;
669 dvbdemux->feednum = 256;
670 dvbdemux->start_feed = pluto_start_feed;
671 dvbdemux->stop_feed = pluto_stop_feed;
672 dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
673 DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
674 ret = dvb_dmx_init(dvbdemux);
675 if (ret < 0)
676 goto err_dvb_unregister_adapter;
677
678 dmx = &dvbdemux->dmx;
679
680 pluto->hw_frontend.source = DMX_FRONTEND_0;
681 pluto->mem_frontend.source = DMX_MEMORY_FE;
682 pluto->dmxdev.filternum = NHWFILTERS;
683 pluto->dmxdev.demux = dmx;
684
685 ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter);
686 if (ret < 0)
687 goto err_dvb_dmx_release;
688
689 ret = dmx->add_frontend(dmx, &pluto->hw_frontend);
690 if (ret < 0)
691 goto err_dvb_dmxdev_release;
692
693 ret = dmx->add_frontend(dmx, &pluto->mem_frontend);
694 if (ret < 0)
695 goto err_remove_hw_frontend;
696
697 ret = dmx->connect_frontend(dmx, &pluto->hw_frontend);
698 if (ret < 0)
699 goto err_remove_mem_frontend;
700
701 ret = frontend_init(pluto);
702 if (ret < 0)
703 goto err_disconnect_frontend;
704
705 dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx);
706out:
707 return ret;
708
709err_disconnect_frontend:
710 dmx->disconnect_frontend(dmx);
711err_remove_mem_frontend:
712 dmx->remove_frontend(dmx, &pluto->mem_frontend);
713err_remove_hw_frontend:
714 dmx->remove_frontend(dmx, &pluto->hw_frontend);
715err_dvb_dmxdev_release:
716 dvb_dmxdev_release(&pluto->dmxdev);
717err_dvb_dmx_release:
718 dvb_dmx_release(dvbdemux);
719err_dvb_unregister_adapter:
720 dvb_unregister_adapter(dvb_adapter);
721err_i2c_bit_del_bus:
722 i2c_bit_del_bus(&pluto->i2c_adap);
723err_pluto_hw_exit:
724 pluto_hw_exit(pluto);
725err_free_irq:
726 free_irq(pdev->irq, pluto);
727err_pci_iounmap:
728 pci_iounmap(pdev, pluto->io_mem);
729err_pci_release_regions:
730 pci_release_regions(pdev);
731err_pci_disable_device:
732 pci_disable_device(pdev);
733err_kfree:
734 pci_set_drvdata(pdev, NULL);
735 kfree(pluto);
736 goto out;
737}
738
739static void __devexit pluto2_remove(struct pci_dev *pdev)
740{
741 struct pluto *pluto = pci_get_drvdata(pdev);
742 struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter;
743 struct dvb_demux *dvbdemux = &pluto->demux;
744 struct dmx_demux *dmx = &dvbdemux->dmx;
745
746 dmx->close(dmx);
747 dvb_net_release(&pluto->dvbnet);
748 if (pluto->fe)
749 dvb_unregister_frontend(pluto->fe);
750
751 dmx->disconnect_frontend(dmx);
752 dmx->remove_frontend(dmx, &pluto->mem_frontend);
753 dmx->remove_frontend(dmx, &pluto->hw_frontend);
754 dvb_dmxdev_release(&pluto->dmxdev);
755 dvb_dmx_release(dvbdemux);
756 dvb_unregister_adapter(dvb_adapter);
757 i2c_bit_del_bus(&pluto->i2c_adap);
758 pluto_hw_exit(pluto);
759 free_irq(pdev->irq, pluto);
760 pci_iounmap(pdev, pluto->io_mem);
761 pci_release_regions(pdev);
762 pci_disable_device(pdev);
763 pci_set_drvdata(pdev, NULL);
764 kfree(pluto);
765}
766
767#ifndef PCI_VENDOR_ID_SCM
768#define PCI_VENDOR_ID_SCM 0x0432
769#endif
770#ifndef PCI_DEVICE_ID_PLUTO2
771#define PCI_DEVICE_ID_PLUTO2 0x0001
772#endif
773
774static struct pci_device_id pluto2_id_table[] __devinitdata = {
775 {
776 .vendor = PCI_VENDOR_ID_SCM,
777 .device = PCI_DEVICE_ID_PLUTO2,
778 .subvendor = PCI_ANY_ID,
779 .subdevice = PCI_ANY_ID,
780 }, {
781 /* empty */
782 },
783};
784
785MODULE_DEVICE_TABLE(pci, pluto2_id_table);
786
787static struct pci_driver pluto2_driver = {
788 .name = DRIVER_NAME,
789 .id_table = pluto2_id_table,
790 .probe = pluto2_probe,
791 .remove = __devexit_p(pluto2_remove),
792};
793
794static int __init pluto2_init(void)
795{
796 return pci_register_driver(&pluto2_driver);
797}
798
799static void __exit pluto2_exit(void)
800{
801 pci_unregister_driver(&pluto2_driver);
802}
803
804module_init(pluto2_init);
805module_exit(pluto2_exit);
806
807MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
808MODULE_DESCRIPTION("Pluto2 driver");
809MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 7ffa2c7315b3..bf3c011d2cfb 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -12,7 +12,7 @@ config DVB_AV7110
12 select DVB_STV0297 12 select DVB_STV0297
13 select DVB_L64781 13 select DVB_L64781
14 help 14 help
15 Support for SAA7146 and AV7110 based DVB cards as produced 15 Support for SAA7146 and AV7110 based DVB cards as produced
16 by Fujitsu-Siemens, Technotrend, Hauppauge and others. 16 by Fujitsu-Siemens, Technotrend, Hauppauge and others.
17 17
18 This driver only supports the fullfeatured cards with 18 This driver only supports the fullfeatured cards with
@@ -33,7 +33,7 @@ config DVB_AV7110_FIRMWARE
33 If you want to compile the firmware into the driver you need to say 33 If you want to compile the firmware into the driver you need to say
34 Y here and provide the correct path of the firmware. You need this 34 Y here and provide the correct path of the firmware. You need this
35 option if you want to compile the whole driver statically into the 35 option if you want to compile the whole driver statically into the
36 kernel. 36 kernel.
37 37
38 All other people say N. 38 All other people say N.
39 39
@@ -66,6 +66,7 @@ config DVB_BUDGET
66 select DVB_L64781 66 select DVB_L64781
67 select DVB_TDA8083 67 select DVB_TDA8083
68 select DVB_TDA10021 68 select DVB_TDA10021
69 select DVB_S5H1420
69 help 70 help
70 Support for simple SAA7146 based DVB cards 71 Support for simple SAA7146 based DVB cards
71 (so called Budget- or Nova-PCI cards) without onboard 72 (so called Budget- or Nova-PCI cards) without onboard
@@ -119,9 +120,9 @@ config DVB_BUDGET_PATCH
119 select DVB_VES1X93 120 select DVB_VES1X93
120 select DVB_TDA8083 121 select DVB_TDA8083
121 help 122 help
122 Support for Budget Patch (full TS) modification on 123 Support for Budget Patch (full TS) modification on
123 SAA7146+AV7110 based cards (DVB-S cards). This 124 SAA7146+AV7110 based cards (DVB-S cards). This
124 driver doesn't use onboard MPEG2 decoder. The 125 driver doesn't use onboard MPEG2 decoder. The
125 card is driven in Budget-only mode. Card is 126 card is driven in Budget-only mode. Card is
126 required to have loaded firmware to tune properly. 127 required to have loaded firmware to tune properly.
127 Firmware can be loaded by insertion and removal of 128 Firmware can be loaded by insertion and removal of
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 8e33a850e13e..e4c6e87f6c5d 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -116,13 +116,18 @@ static int av7110_num = 0;
116 116
117static void init_av7110_av(struct av7110 *av7110) 117static void init_av7110_av(struct av7110 *av7110)
118{ 118{
119 int ret;
119 struct saa7146_dev *dev = av7110->dev; 120 struct saa7146_dev *dev = av7110->dev;
120 121
121 /* set internal volume control to maximum */ 122 /* set internal volume control to maximum */
122 av7110->adac_type = DVB_ADAC_TI; 123 av7110->adac_type = DVB_ADAC_TI;
123 av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); 124 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
125 if (ret < 0)
126 printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
124 127
125 av7710_set_video_mode(av7110, vidmode); 128 ret = av7710_set_video_mode(av7110, vidmode);
129 if (ret < 0)
130 printk("dvb-ttpci:cannot set video mode:%d\n",ret);
126 131
127 /* handle different card types */ 132 /* handle different card types */
128 /* remaining inits according to card and frontend type */ 133 /* remaining inits according to card and frontend type */
@@ -156,8 +161,12 @@ static void init_av7110_av(struct av7110 *av7110)
156 161
157 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { 162 if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
158 // switch DVB SCART on 163 // switch DVB SCART on
159 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); 164 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
160 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); 165 if (ret < 0)
166 printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
167 ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
168 if (ret < 0)
169 printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
161 if (rgb_on && 170 if (rgb_on &&
162 (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) { 171 (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
163 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 172 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
@@ -165,8 +174,12 @@ static void init_av7110_av(struct av7110 *av7110)
165 } 174 }
166 } 175 }
167 176
168 av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); 177 ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
169 av7110_setup_irc_config(av7110, 0); 178 if (ret < 0)
179 printk("dvb-ttpci:cannot set volume :%d\n",ret);
180 ret = av7110_setup_irc_config(av7110, 0);
181 if (ret < 0)
182 printk("dvb-ttpci:cannot setup irc config :%d\n",ret);
170} 183}
171 184
172static void recover_arm(struct av7110 *av7110) 185static void recover_arm(struct av7110 *av7110)
@@ -258,8 +271,9 @@ static int arm_thread(void *data)
258 * 271 *
259 * If we want to support multiple controls we would have to do much more... 272 * If we want to support multiple controls we would have to do much more...
260 */ 273 */
261void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) 274int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
262{ 275{
276 int ret = 0;
263 static struct av7110 *last; 277 static struct av7110 *last;
264 278
265 dprintk(4, "%p\n", av7110); 279 dprintk(4, "%p\n", av7110);
@@ -270,9 +284,10 @@ void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
270 last = av7110; 284 last = av7110;
271 285
272 if (av7110) { 286 if (av7110) {
273 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); 287 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
274 av7110->ir_config = ir_config; 288 av7110->ir_config = ir_config;
275 } 289 }
290 return ret;
276} 291}
277 292
278static void (*irc_handler)(u32); 293static void (*irc_handler)(u32);
@@ -765,13 +780,14 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
765 pcrpid, vpid, apid, ttpid, subpid); 780 pcrpid, vpid, apid, ttpid, subpid);
766} 781}
767 782
768void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 783int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
769 u16 subpid, u16 pcrpid) 784 u16 subpid, u16 pcrpid)
770{ 785{
786 int ret = 0;
771 dprintk(4, "%p\n", av7110); 787 dprintk(4, "%p\n", av7110);
772 788
773 if (down_interruptible(&av7110->pid_mutex)) 789 if (down_interruptible(&av7110->pid_mutex))
774 return; 790 return -ERESTARTSYS;
775 791
776 if (!(vpid & 0x8000)) 792 if (!(vpid & 0x8000))
777 av7110->pids[DMX_PES_VIDEO] = vpid; 793 av7110->pids[DMX_PES_VIDEO] = vpid;
@@ -786,10 +802,11 @@ void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
786 802
787 if (av7110->fe_synced) { 803 if (av7110->fe_synced) {
788 pcrpid = av7110->pids[DMX_PES_PCR]; 804 pcrpid = av7110->pids[DMX_PES_PCR];
789 SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); 805 ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
790 } 806 }
791 807
792 up(&av7110->pid_mutex); 808 up(&av7110->pid_mutex);
809 return ret;
793} 810}
794 811
795 812
@@ -832,11 +849,13 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
832 ret = av7110_fw_request(av7110, buf, 20, &handle, 1); 849 ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
833 if (ret != 0 || handle >= 32) { 850 if (ret != 0 || handle >= 32) {
834 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " 851 printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
835 "ret %x handle %04x\n", 852 "ret %d handle %04x\n",
836 __FUNCTION__, buf[0], buf[1], buf[2], buf[3], 853 __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
837 ret, handle); 854 ret, handle);
838 dvbdmxfilter->hw_handle = 0xffff; 855 dvbdmxfilter->hw_handle = 0xffff;
839 return -1; 856 if (!ret)
857 ret = -1;
858 return ret;
840 } 859 }
841 860
842 av7110->handle2filter[handle] = dvbdmxfilter; 861 av7110->handle2filter[handle] = dvbdmxfilter;
@@ -859,7 +878,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
859 if (handle >= 32) { 878 if (handle >= 32) {
860 printk("%s tried to stop invalid filter %04x, filter type = %x\n", 879 printk("%s tried to stop invalid filter %04x, filter type = %x\n",
861 __FUNCTION__, handle, dvbdmxfilter->type); 880 __FUNCTION__, handle, dvbdmxfilter->type);
862 return 0; 881 return -EINVAL;
863 } 882 }
864 883
865 av7110->handle2filter[handle] = NULL; 884 av7110->handle2filter[handle] = NULL;
@@ -873,18 +892,20 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
873 "resp %04x %04x pid %d\n", 892 "resp %04x %04x pid %d\n",
874 __FUNCTION__, buf[0], buf[1], buf[2], ret, 893 __FUNCTION__, buf[0], buf[1], buf[2], ret,
875 answ[0], answ[1], dvbdmxfilter->feed->pid); 894 answ[0], answ[1], dvbdmxfilter->feed->pid);
876 ret = -1; 895 if (!ret)
896 ret = -1;
877 } 897 }
878 return ret; 898 return ret;
879} 899}
880 900
881 901
882static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) 902static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
883{ 903{
884 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 904 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
885 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; 905 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
886 u16 *pid = dvbdmx->pids, npids[5]; 906 u16 *pid = dvbdmx->pids, npids[5];
887 int i; 907 int i;
908 int ret = 0;
888 909
889 dprintk(4, "%p\n", av7110); 910 dprintk(4, "%p\n", av7110);
890 911
@@ -893,36 +914,49 @@ static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
893 npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; 914 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
894 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) { 915 if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
895 npids[i] = 0; 916 npids[i] = 0;
896 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); 917 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
897 StartHWFilter(dvbdmxfeed->filter); 918 if (!ret)
898 return; 919 ret = StartHWFilter(dvbdmxfeed->filter);
920 return ret;
921 }
922 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
923 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
924 if (ret)
925 return ret;
899 } 926 }
900 if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4)
901 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
902 927
903 if (dvbdmxfeed->pes_type < 2 && npids[0]) 928 if (dvbdmxfeed->pes_type < 2 && npids[0])
904 if (av7110->fe_synced) 929 if (av7110->fe_synced)
905 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); 930 {
931 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
932 if (ret)
933 return ret;
934 }
906 935
907 if ((dvbdmxfeed->ts_type & TS_PACKET)) { 936 if ((dvbdmxfeed->ts_type & TS_PACKET)) {
908 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) 937 if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
909 av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); 938 ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
910 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) 939 if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
911 av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed); 940 ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
912 } 941 }
942 return ret;
913} 943}
914 944
915static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) 945static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
916{ 946{
917 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 947 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
918 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; 948 struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
919 u16 *pid = dvbdmx->pids, npids[5]; 949 u16 *pid = dvbdmx->pids, npids[5];
920 int i; 950 int i;
921 951
952 int ret = 0;
953
922 dprintk(4, "%p\n", av7110); 954 dprintk(4, "%p\n", av7110);
923 955
924 if (dvbdmxfeed->pes_type <= 1) { 956 if (dvbdmxfeed->pes_type <= 1) {
925 av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO); 957 ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
958 if (ret)
959 return ret;
926 if (!av7110->rec_mode) 960 if (!av7110->rec_mode)
927 dvbdmx->recording = 0; 961 dvbdmx->recording = 0;
928 if (!av7110->playing) 962 if (!av7110->playing)
@@ -933,24 +967,27 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
933 switch (i) { 967 switch (i) {
934 case 2: //teletext 968 case 2: //teletext
935 if (dvbdmxfeed->ts_type & TS_PACKET) 969 if (dvbdmxfeed->ts_type & TS_PACKET)
936 StopHWFilter(dvbdmxfeed->filter); 970 ret = StopHWFilter(dvbdmxfeed->filter);
937 npids[2] = 0; 971 npids[2] = 0;
938 break; 972 break;
939 case 0: 973 case 0:
940 case 1: 974 case 1:
941 case 4: 975 case 4:
942 if (!pids_off) 976 if (!pids_off)
943 return; 977 return 0;
944 npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; 978 npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
945 break; 979 break;
946 } 980 }
947 ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); 981 if (!ret)
982 ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
983 return ret;
948} 984}
949 985
950static int av7110_start_feed(struct dvb_demux_feed *feed) 986static int av7110_start_feed(struct dvb_demux_feed *feed)
951{ 987{
952 struct dvb_demux *demux = feed->demux; 988 struct dvb_demux *demux = feed->demux;
953 struct av7110 *av7110 = demux->priv; 989 struct av7110 *av7110 = demux->priv;
990 int ret = 0;
954 991
955 dprintk(4, "%p\n", av7110); 992 dprintk(4, "%p\n", av7110);
956 993
@@ -971,21 +1008,22 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
971 !(demux->pids[1] & 0x8000)) { 1008 !(demux->pids[1] & 0x8000)) {
972 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); 1009 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
973 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 1010 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
974 av7110_av_start_play(av7110,RP_AV); 1011 ret = av7110_av_start_play(av7110,RP_AV);
975 demux->playing = 1; 1012 if (!ret)
1013 demux->playing = 1;
976 } 1014 }
977 break; 1015 break;
978 default: 1016 default:
979 dvb_feed_start_pid(feed); 1017 ret = dvb_feed_start_pid(feed);
980 break; 1018 break;
981 } 1019 }
982 } else if ((feed->ts_type & TS_PACKET) && 1020 } else if ((feed->ts_type & TS_PACKET) &&
983 (demux->dmx.frontend->source != DMX_MEMORY_FE)) { 1021 (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
984 StartHWFilter(feed->filter); 1022 ret = StartHWFilter(feed->filter);
985 } 1023 }
986 } 1024 }
987 1025
988 if (feed->type == DMX_TYPE_SEC) { 1026 else if (feed->type == DMX_TYPE_SEC) {
989 int i; 1027 int i;
990 1028
991 for (i = 0; i < demux->filternum; i++) { 1029 for (i = 0; i < demux->filternum; i++) {
@@ -996,12 +1034,15 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
996 if (demux->filter[i].filter.parent != &feed->feed.sec) 1034 if (demux->filter[i].filter.parent != &feed->feed.sec)
997 continue; 1035 continue;
998 demux->filter[i].state = DMX_STATE_GO; 1036 demux->filter[i].state = DMX_STATE_GO;
999 if (demux->dmx.frontend->source != DMX_MEMORY_FE) 1037 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
1000 StartHWFilter(&demux->filter[i]); 1038 ret = StartHWFilter(&demux->filter[i]);
1039 if (ret)
1040 break;
1041 }
1001 } 1042 }
1002 } 1043 }
1003 1044
1004 return 0; 1045 return ret;
1005} 1046}
1006 1047
1007 1048
@@ -1009,7 +1050,7 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
1009{ 1050{
1010 struct dvb_demux *demux = feed->demux; 1051 struct dvb_demux *demux = feed->demux;
1011 struct av7110 *av7110 = demux->priv; 1052 struct av7110 *av7110 = demux->priv;
1012 1053 int i, rc, ret = 0;
1013 dprintk(4, "%p\n", av7110); 1054 dprintk(4, "%p\n", av7110);
1014 1055
1015 if (feed->type == DMX_TYPE_TS) { 1056 if (feed->type == DMX_TYPE_TS) {
@@ -1022,26 +1063,29 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
1022 } 1063 }
1023 if (feed->ts_type & TS_DECODER && 1064 if (feed->ts_type & TS_DECODER &&
1024 feed->pes_type < DMX_TS_PES_OTHER) { 1065 feed->pes_type < DMX_TS_PES_OTHER) {
1025 dvb_feed_stop_pid(feed); 1066 ret = dvb_feed_stop_pid(feed);
1026 } else 1067 } else
1027 if ((feed->ts_type & TS_PACKET) && 1068 if ((feed->ts_type & TS_PACKET) &&
1028 (demux->dmx.frontend->source != DMX_MEMORY_FE)) 1069 (demux->dmx.frontend->source != DMX_MEMORY_FE))
1029 StopHWFilter(feed->filter); 1070 ret = StopHWFilter(feed->filter);
1030 } 1071 }
1031 1072
1032 if (feed->type == DMX_TYPE_SEC) { 1073 if (!ret && feed->type == DMX_TYPE_SEC) {
1033 int i; 1074 for (i = 0; i<demux->filternum; i++) {
1034
1035 for (i = 0; i<demux->filternum; i++)
1036 if (demux->filter[i].state == DMX_STATE_GO && 1075 if (demux->filter[i].state == DMX_STATE_GO &&
1037 demux->filter[i].filter.parent == &feed->feed.sec) { 1076 demux->filter[i].filter.parent == &feed->feed.sec) {
1038 demux->filter[i].state = DMX_STATE_READY; 1077 demux->filter[i].state = DMX_STATE_READY;
1039 if (demux->dmx.frontend->source != DMX_MEMORY_FE) 1078 if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
1040 StopHWFilter(&demux->filter[i]); 1079 rc = StopHWFilter(&demux->filter[i]);
1080 if (!ret)
1081 ret = rc;
1082 /* keep going, stop as many filters as possible */
1083 }
1084 }
1041 } 1085 }
1042 } 1086 }
1043 1087
1044 return 0; 1088 return ret;
1045} 1089}
1046 1090
1047 1091
@@ -1093,7 +1137,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
1093 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4); 1137 ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
1094 if (ret) { 1138 if (ret) {
1095 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__); 1139 printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
1096 return -EIO; 1140 return ret;
1097 } 1141 }
1098 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", 1142 dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
1099 fwstc[0], fwstc[1], fwstc[2], fwstc[3]); 1143 fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
@@ -1119,18 +1163,14 @@ static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
1119 1163
1120 switch (tone) { 1164 switch (tone) {
1121 case SEC_TONE_ON: 1165 case SEC_TONE_ON:
1122 Set22K(av7110, 1); 1166 return Set22K(av7110, 1);
1123 break;
1124 1167
1125 case SEC_TONE_OFF: 1168 case SEC_TONE_OFF:
1126 Set22K(av7110, 0); 1169 return Set22K(av7110, 0);
1127 break;
1128 1170
1129 default: 1171 default:
1130 return -EINVAL; 1172 return -EINVAL;
1131 } 1173 }
1132
1133 return 0;
1134} 1174}
1135 1175
1136static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, 1176static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
@@ -1138,9 +1178,7 @@ static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
1138{ 1178{
1139 struct av7110* av7110 = fe->dvb->priv; 1179 struct av7110* av7110 = fe->dvb->priv;
1140 1180
1141 av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); 1181 return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
1142
1143 return 0;
1144} 1182}
1145 1183
1146static int av7110_diseqc_send_burst(struct dvb_frontend* fe, 1184static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
@@ -1148,9 +1186,7 @@ static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
1148{ 1186{
1149 struct av7110* av7110 = fe->dvb->priv; 1187 struct av7110* av7110 = fe->dvb->priv;
1150 1188
1151 av7110_diseqc_send(av7110, 0, NULL, minicmd); 1189 return av7110_diseqc_send(av7110, 0, NULL, minicmd);
1152
1153 return 0;
1154} 1190}
1155 1191
1156/* simplified code from budget-core.c */ 1192/* simplified code from budget-core.c */
@@ -1992,76 +2028,85 @@ static struct l64781_config grundig_29504_401_config = {
1992 2028
1993 2029
1994 2030
1995static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) 2031static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
1996{ 2032{
2033 int ret = 0;
1997 int synced = (status & FE_HAS_LOCK) ? 1 : 0; 2034 int synced = (status & FE_HAS_LOCK) ? 1 : 0;
1998 2035
1999 av7110->fe_status = status; 2036 av7110->fe_status = status;
2000 2037
2001 if (av7110->fe_synced == synced) 2038 if (av7110->fe_synced == synced)
2002 return; 2039 return 0;
2003
2004 av7110->fe_synced = synced;
2005 2040
2006 if (av7110->playing) 2041 if (av7110->playing)
2007 return; 2042 return 0;
2008 2043
2009 if (down_interruptible(&av7110->pid_mutex)) 2044 if (down_interruptible(&av7110->pid_mutex))
2010 return; 2045 return -ERESTARTSYS;
2011 2046
2012 if (av7110->fe_synced) { 2047 if (synced) {
2013 SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], 2048 ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
2014 av7110->pids[DMX_PES_AUDIO], 2049 av7110->pids[DMX_PES_AUDIO],
2015 av7110->pids[DMX_PES_TELETEXT], 0, 2050 av7110->pids[DMX_PES_TELETEXT], 0,
2016 av7110->pids[DMX_PES_PCR]); 2051 av7110->pids[DMX_PES_PCR]);
2017 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); 2052 if (!ret)
2053 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
2018 } else { 2054 } else {
2019 SetPIDs(av7110, 0, 0, 0, 0, 0); 2055 ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
2020 av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0); 2056 if (!ret) {
2021 av7110_wait_msgstate(av7110, GPMQBusy); 2057 ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
2058 if (!ret)
2059 ret = av7110_wait_msgstate(av7110, GPMQBusy);
2060 }
2022 } 2061 }
2023 2062
2063 if (!ret)
2064 av7110->fe_synced = synced;
2065
2024 up(&av7110->pid_mutex); 2066 up(&av7110->pid_mutex);
2067 return ret;
2025} 2068}
2026 2069
2027static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 2070static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
2028{ 2071{
2029 struct av7110* av7110 = fe->dvb->priv; 2072 struct av7110* av7110 = fe->dvb->priv;
2030 av7110_fe_lock_fix(av7110, 0); 2073
2031 return av7110->fe_set_frontend(fe, params); 2074 int ret = av7110_fe_lock_fix(av7110, 0);
2075 if (!ret)
2076 ret = av7110->fe_set_frontend(fe, params);
2077 return ret;
2032} 2078}
2033 2079
2034static int av7110_fe_init(struct dvb_frontend* fe) 2080static int av7110_fe_init(struct dvb_frontend* fe)
2035{ 2081{
2036 struct av7110* av7110 = fe->dvb->priv; 2082 struct av7110* av7110 = fe->dvb->priv;
2037 2083
2038 av7110_fe_lock_fix(av7110, 0); 2084 int ret = av7110_fe_lock_fix(av7110, 0);
2039 return av7110->fe_init(fe); 2085 if (!ret)
2086 ret = av7110->fe_init(fe);
2087 return ret;
2040} 2088}
2041 2089
2042static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) 2090static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
2043{ 2091{
2044 struct av7110* av7110 = fe->dvb->priv; 2092 struct av7110* av7110 = fe->dvb->priv;
2045 int ret;
2046 2093
2047 /* call the real implementation */ 2094 /* call the real implementation */
2048 ret = av7110->fe_read_status(fe, status); 2095 int ret = av7110->fe_read_status(fe, status);
2049 if (ret) 2096 if (!ret)
2050 return ret; 2097 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
2051 2098 ret = av7110_fe_lock_fix(av7110, *status);
2052 if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) { 2099 return ret;
2053 av7110_fe_lock_fix(av7110, *status);
2054 }
2055
2056 return 0;
2057} 2100}
2058 2101
2059static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) 2102static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
2060{ 2103{
2061 struct av7110* av7110 = fe->dvb->priv; 2104 struct av7110* av7110 = fe->dvb->priv;
2062 2105
2063 av7110_fe_lock_fix(av7110, 0); 2106 int ret = av7110_fe_lock_fix(av7110, 0);
2064 return av7110->fe_diseqc_reset_overload(fe); 2107 if (!ret)
2108 ret = av7110->fe_diseqc_reset_overload(fe);
2109 return ret;
2065} 2110}
2066 2111
2067static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, 2112static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
@@ -2069,40 +2114,50 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
2069{ 2114{
2070 struct av7110* av7110 = fe->dvb->priv; 2115 struct av7110* av7110 = fe->dvb->priv;
2071 2116
2072 av7110_fe_lock_fix(av7110, 0); 2117 int ret = av7110_fe_lock_fix(av7110, 0);
2073 return av7110->fe_diseqc_send_master_cmd(fe, cmd); 2118 if (!ret)
2119 ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
2120 return ret;
2074} 2121}
2075 2122
2076static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) 2123static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
2077{ 2124{
2078 struct av7110* av7110 = fe->dvb->priv; 2125 struct av7110* av7110 = fe->dvb->priv;
2079 2126
2080 av7110_fe_lock_fix(av7110, 0); 2127 int ret = av7110_fe_lock_fix(av7110, 0);
2081 return av7110->fe_diseqc_send_burst(fe, minicmd); 2128 if (!ret)
2129 ret = av7110->fe_diseqc_send_burst(fe, minicmd);
2130 return ret;
2082} 2131}
2083 2132
2084static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) 2133static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
2085{ 2134{
2086 struct av7110* av7110 = fe->dvb->priv; 2135 struct av7110* av7110 = fe->dvb->priv;
2087 2136
2088 av7110_fe_lock_fix(av7110, 0); 2137 int ret = av7110_fe_lock_fix(av7110, 0);
2089 return av7110->fe_set_tone(fe, tone); 2138 if (!ret)
2139 ret = av7110->fe_set_tone(fe, tone);
2140 return ret;
2090} 2141}
2091 2142
2092static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) 2143static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
2093{ 2144{
2094 struct av7110* av7110 = fe->dvb->priv; 2145 struct av7110* av7110 = fe->dvb->priv;
2095 2146
2096 av7110_fe_lock_fix(av7110, 0); 2147 int ret = av7110_fe_lock_fix(av7110, 0);
2097 return av7110->fe_set_voltage(fe, voltage); 2148 if (!ret)
2149 ret = av7110->fe_set_voltage(fe, voltage);
2150 return ret;
2098} 2151}
2099 2152
2100static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) 2153static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
2101{ 2154{
2102 struct av7110* av7110 = fe->dvb->priv; 2155 struct av7110* av7110 = fe->dvb->priv;
2103 2156
2104 av7110_fe_lock_fix(av7110, 0); 2157 int ret = av7110_fe_lock_fix(av7110, 0);
2105 return av7110->fe_dishnetwork_send_legacy_command(fe, cmd); 2158 if (!ret)
2159 ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
2160 return ret;
2106} 2161}
2107 2162
2108static u8 read_pwm(struct av7110* av7110) 2163static u8 read_pwm(struct av7110* av7110)
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index 4f69b4d01479..508b7739c609 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -119,8 +119,7 @@ struct av7110 {
119 volatile int bmp_state; 119 volatile int bmp_state;
120#define BMP_NONE 0 120#define BMP_NONE 0
121#define BMP_LOADING 1 121#define BMP_LOADING 1
122#define BMP_LOADINGS 2 122#define BMP_LOADED 2
123#define BMP_LOADED 3
124 wait_queue_head_t bmpq; 123 wait_queue_head_t bmpq;
125 124
126 125
@@ -255,12 +254,12 @@ struct av7110 {
255}; 254};
256 255
257 256
258extern void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, 257extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
259 u16 subpid, u16 pcrpid); 258 u16 subpid, u16 pcrpid);
260 259
261extern void av7110_register_irc_handler(void (*func)(u32)); 260extern void av7110_register_irc_handler(void (*func)(u32));
262extern void av7110_unregister_irc_handler(void (*func)(u32)); 261extern void av7110_unregister_irc_handler(void (*func)(u32));
263extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config); 262extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
264 263
265extern int av7110_ir_init (void); 264extern int av7110_ir_init (void);
266extern void av7110_ir_exit (void); 265extern void av7110_ir_exit (void);
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index ccf946125d02..0696a5a4f855 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -121,6 +121,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
121int av7110_av_start_record(struct av7110 *av7110, int av, 121int av7110_av_start_record(struct av7110 *av7110, int av,
122 struct dvb_demux_feed *dvbdmxfeed) 122 struct dvb_demux_feed *dvbdmxfeed)
123{ 123{
124 int ret = 0;
124 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 125 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
125 126
126 dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed); 127 dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
@@ -137,7 +138,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
137 dvbdmx->pesfilter[0]->pid, 138 dvbdmx->pesfilter[0]->pid,
138 dvb_filter_pes2ts_cb, 139 dvb_filter_pes2ts_cb,
139 (void *) dvbdmx->pesfilter[0]); 140 (void *) dvbdmx->pesfilter[0]);
140 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); 141 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
141 break; 142 break;
142 143
143 case RP_VIDEO: 144 case RP_VIDEO:
@@ -145,7 +146,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
145 dvbdmx->pesfilter[1]->pid, 146 dvbdmx->pesfilter[1]->pid,
146 dvb_filter_pes2ts_cb, 147 dvb_filter_pes2ts_cb,
147 (void *) dvbdmx->pesfilter[1]); 148 (void *) dvbdmx->pesfilter[1]);
148 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); 149 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
149 break; 150 break;
150 151
151 case RP_AV: 152 case RP_AV:
@@ -157,14 +158,15 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
157 dvbdmx->pesfilter[1]->pid, 158 dvbdmx->pesfilter[1]->pid,
158 dvb_filter_pes2ts_cb, 159 dvb_filter_pes2ts_cb,
159 (void *) dvbdmx->pesfilter[1]); 160 (void *) dvbdmx->pesfilter[1]);
160 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); 161 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
161 break; 162 break;
162 } 163 }
163 return 0; 164 return ret;
164} 165}
165 166
166int av7110_av_start_play(struct av7110 *av7110, int av) 167int av7110_av_start_play(struct av7110 *av7110, int av)
167{ 168{
169 int ret = 0;
168 dprintk(2, "av7110:%p, \n", av7110); 170 dprintk(2, "av7110:%p, \n", av7110);
169 171
170 if (av7110->rec_mode) 172 if (av7110->rec_mode)
@@ -182,54 +184,57 @@ int av7110_av_start_play(struct av7110 *av7110, int av)
182 av7110->playing |= av; 184 av7110->playing |= av;
183 switch (av7110->playing) { 185 switch (av7110->playing) {
184 case RP_AUDIO: 186 case RP_AUDIO:
185 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); 187 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
186 break; 188 break;
187 case RP_VIDEO: 189 case RP_VIDEO:
188 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); 190 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
189 av7110->sinfo = 0; 191 av7110->sinfo = 0;
190 break; 192 break;
191 case RP_AV: 193 case RP_AV:
192 av7110->sinfo = 0; 194 av7110->sinfo = 0;
193 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); 195 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
194 break; 196 break;
195 } 197 }
196 return av7110->playing; 198 if (!ret)
199 ret = av7110->playing;
200 return ret;
197} 201}
198 202
199void av7110_av_stop(struct av7110 *av7110, int av) 203int av7110_av_stop(struct av7110 *av7110, int av)
200{ 204{
205 int ret = 0;
201 dprintk(2, "av7110:%p, \n", av7110); 206 dprintk(2, "av7110:%p, \n", av7110);
202 207
203 if (!(av7110->playing & av) && !(av7110->rec_mode & av)) 208 if (!(av7110->playing & av) && !(av7110->rec_mode & av))
204 return; 209 return 0;
205
206 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 210 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
207 if (av7110->playing) { 211 if (av7110->playing) {
208 av7110->playing &= ~av; 212 av7110->playing &= ~av;
209 switch (av7110->playing) { 213 switch (av7110->playing) {
210 case RP_AUDIO: 214 case RP_AUDIO:
211 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); 215 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
212 break; 216 break;
213 case RP_VIDEO: 217 case RP_VIDEO:
214 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); 218 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
215 break; 219 break;
216 case RP_NONE: 220 case RP_NONE:
217 av7110_set_vidmode(av7110, av7110->vidmode); 221 ret = av7110_set_vidmode(av7110, av7110->vidmode);
218 break; 222 break;
219 } 223 }
220 } else { 224 } else {
221 av7110->rec_mode &= ~av; 225 av7110->rec_mode &= ~av;
222 switch (av7110->rec_mode) { 226 switch (av7110->rec_mode) {
223 case RP_AUDIO: 227 case RP_AUDIO:
224 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); 228 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
225 break; 229 break;
226 case RP_VIDEO: 230 case RP_VIDEO:
227 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); 231 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
228 break; 232 break;
229 case RP_NONE: 233 case RP_NONE:
230 break; 234 break;
231 } 235 }
232 } 236 }
237 return ret;
233} 238}
234 239
235 240
@@ -317,19 +322,22 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
317 return 0; 322 return 0;
318} 323}
319 324
320void av7110_set_vidmode(struct av7110 *av7110, int mode) 325int av7110_set_vidmode(struct av7110 *av7110, int mode)
321{ 326{
327 int ret;
322 dprintk(2, "av7110:%p, \n", av7110); 328 dprintk(2, "av7110:%p, \n", av7110);
323 329
324 av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); 330 ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
325 331
326 if (!av7110->playing) { 332 if (!ret && !av7110->playing) {
327 ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], 333 ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
328 av7110->pids[DMX_PES_AUDIO], 334 av7110->pids[DMX_PES_AUDIO],
329 av7110->pids[DMX_PES_TELETEXT], 335 av7110->pids[DMX_PES_TELETEXT],
330 0, av7110->pids[DMX_PES_PCR]); 336 0, av7110->pids[DMX_PES_PCR]);
331 av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); 337 if (!ret)
338 ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
332 } 339 }
340 return ret;
333} 341}
334 342
335 343
@@ -340,17 +348,18 @@ static int sw2mode[16] = {
340 VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, 348 VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
341}; 349};
342 350
343static void get_video_format(struct av7110 *av7110, u8 *buf, int count) 351static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
344{ 352{
345 int i; 353 int i;
346 int hsize, vsize; 354 int hsize, vsize;
347 int sw; 355 int sw;
348 u8 *p; 356 u8 *p;
357 int ret = 0;
349 358
350 dprintk(2, "av7110:%p, \n", av7110); 359 dprintk(2, "av7110:%p, \n", av7110);
351 360
352 if (av7110->sinfo) 361 if (av7110->sinfo)
353 return; 362 return 0;
354 for (i = 7; i < count - 10; i++) { 363 for (i = 7; i < count - 10; i++) {
355 p = buf + i; 364 p = buf + i;
356 if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) 365 if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
@@ -359,11 +368,14 @@ static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
359 hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); 368 hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
360 vsize = ((p[1] &0x0F) << 8) | (p[2]); 369 vsize = ((p[1] &0x0F) << 8) | (p[2]);
361 sw = (p[3] & 0x0F); 370 sw = (p[3] & 0x0F);
362 av7110_set_vidmode(av7110, sw2mode[sw]); 371 ret = av7110_set_vidmode(av7110, sw2mode[sw]);
363 dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); 372 if (!ret) {
364 av7110->sinfo = 1; 373 dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
374 av7110->sinfo = 1;
375 }
365 break; 376 break;
366 } 377 }
378 return ret;
367} 379}
368 380
369 381
@@ -974,7 +986,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
974 unsigned long arg = (unsigned long) parg; 986 unsigned long arg = (unsigned long) parg;
975 int ret = 0; 987 int ret = 0;
976 988
977 dprintk(2, "av7110:%p, \n", av7110); 989 dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
978 990
979 if ((file->f_flags & O_ACCMODE) == O_RDONLY) { 991 if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
980 if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && 992 if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
@@ -987,49 +999,57 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
987 case VIDEO_STOP: 999 case VIDEO_STOP:
988 av7110->videostate.play_state = VIDEO_STOPPED; 1000 av7110->videostate.play_state = VIDEO_STOPPED;
989 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) 1001 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
990 av7110_av_stop(av7110, RP_VIDEO); 1002 ret = av7110_av_stop(av7110, RP_VIDEO);
991 else 1003 else
992 vidcom(av7110, VIDEO_CMD_STOP, 1004 ret = vidcom(av7110, VIDEO_CMD_STOP,
993 av7110->videostate.video_blank ? 0 : 1); 1005 av7110->videostate.video_blank ? 0 : 1);
994 av7110->trickmode = TRICK_NONE; 1006 if (!ret)
1007 av7110->trickmode = TRICK_NONE;
995 break; 1008 break;
996 1009
997 case VIDEO_PLAY: 1010 case VIDEO_PLAY:
998 av7110->trickmode = TRICK_NONE; 1011 av7110->trickmode = TRICK_NONE;
999 if (av7110->videostate.play_state == VIDEO_FREEZED) { 1012 if (av7110->videostate.play_state == VIDEO_FREEZED) {
1000 av7110->videostate.play_state = VIDEO_PLAYING; 1013 av7110->videostate.play_state = VIDEO_PLAYING;
1001 vidcom(av7110, VIDEO_CMD_PLAY, 0); 1014 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
1015 if (ret)
1016 break;
1002 } 1017 }
1003 1018
1004 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { 1019 if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
1005 if (av7110->playing == RP_AV) { 1020 if (av7110->playing == RP_AV) {
1006 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); 1021 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
1022 if (ret)
1023 break;
1007 av7110->playing &= ~RP_VIDEO; 1024 av7110->playing &= ~RP_VIDEO;
1008 } 1025 }
1009 av7110_av_start_play(av7110, RP_VIDEO); 1026 ret = av7110_av_start_play(av7110, RP_VIDEO);
1010 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1011 } else {
1012 //av7110_av_stop(av7110, RP_VIDEO);
1013 vidcom(av7110, VIDEO_CMD_PLAY, 0);
1014 } 1027 }
1015 av7110->videostate.play_state = VIDEO_PLAYING; 1028 if (!ret)
1029 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
1030 if (!ret)
1031 av7110->videostate.play_state = VIDEO_PLAYING;
1016 break; 1032 break;
1017 1033
1018 case VIDEO_FREEZE: 1034 case VIDEO_FREEZE:
1019 av7110->videostate.play_state = VIDEO_FREEZED; 1035 av7110->videostate.play_state = VIDEO_FREEZED;
1020 if (av7110->playing & RP_VIDEO) 1036 if (av7110->playing & RP_VIDEO)
1021 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); 1037 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
1022 else 1038 else
1023 vidcom(av7110, VIDEO_CMD_FREEZE, 1); 1039 ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1);
1024 av7110->trickmode = TRICK_FREEZE; 1040 if (!ret)
1041 av7110->trickmode = TRICK_FREEZE;
1025 break; 1042 break;
1026 1043
1027 case VIDEO_CONTINUE: 1044 case VIDEO_CONTINUE:
1028 if (av7110->playing & RP_VIDEO) 1045 if (av7110->playing & RP_VIDEO)
1029 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); 1046 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
1030 vidcom(av7110, VIDEO_CMD_PLAY, 0); 1047 if (!ret)
1031 av7110->videostate.play_state = VIDEO_PLAYING; 1048 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
1032 av7110->trickmode = TRICK_NONE; 1049 if (!ret) {
1050 av7110->videostate.play_state = VIDEO_PLAYING;
1051 av7110->trickmode = TRICK_NONE;
1052 }
1033 break; 1053 break;
1034 1054
1035 case VIDEO_SELECT_SOURCE: 1055 case VIDEO_SELECT_SOURCE:
@@ -1045,7 +1065,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1045 break; 1065 break;
1046 1066
1047 case VIDEO_GET_EVENT: 1067 case VIDEO_GET_EVENT:
1048 ret=dvb_video_get_event(av7110, parg, file->f_flags); 1068 ret = dvb_video_get_event(av7110, parg, file->f_flags);
1049 break; 1069 break;
1050 1070
1051 case VIDEO_GET_SIZE: 1071 case VIDEO_GET_SIZE:
@@ -1105,25 +1125,32 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1105 case VIDEO_FAST_FORWARD: 1125 case VIDEO_FAST_FORWARD:
1106 //note: arg is ignored by firmware 1126 //note: arg is ignored by firmware
1107 if (av7110->playing & RP_VIDEO) 1127 if (av7110->playing & RP_VIDEO)
1108 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1128 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1109 __Scan_I, 2, AV_PES, 0); 1129 __Scan_I, 2, AV_PES, 0);
1110 else 1130 else
1111 vidcom(av7110, VIDEO_CMD_FFWD, arg); 1131 ret = vidcom(av7110, VIDEO_CMD_FFWD, arg);
1112 av7110->trickmode = TRICK_FAST; 1132 if (!ret) {
1113 av7110->videostate.play_state = VIDEO_PLAYING; 1133 av7110->trickmode = TRICK_FAST;
1134 av7110->videostate.play_state = VIDEO_PLAYING;
1135 }
1114 break; 1136 break;
1115 1137
1116 case VIDEO_SLOWMOTION: 1138 case VIDEO_SLOWMOTION:
1117 if (av7110->playing&RP_VIDEO) { 1139 if (av7110->playing&RP_VIDEO) {
1118 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); 1140 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
1119 vidcom(av7110, VIDEO_CMD_SLOW, arg); 1141 if (!ret)
1142 ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
1120 } else { 1143 } else {
1121 vidcom(av7110, VIDEO_CMD_PLAY, 0); 1144 ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
1122 vidcom(av7110, VIDEO_CMD_STOP, 0); 1145 if (!ret)
1123 vidcom(av7110, VIDEO_CMD_SLOW, arg); 1146 ret = vidcom(av7110, VIDEO_CMD_STOP, 0);
1147 if (!ret)
1148 ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
1149 }
1150 if (!ret) {
1151 av7110->trickmode = TRICK_SLOW;
1152 av7110->videostate.play_state = VIDEO_PLAYING;
1124 } 1153 }
1125 av7110->trickmode = TRICK_SLOW;
1126 av7110->videostate.play_state = VIDEO_PLAYING;
1127 break; 1154 break;
1128 1155
1129 case VIDEO_GET_CAPABILITIES: 1156 case VIDEO_GET_CAPABILITIES:
@@ -1136,18 +1163,21 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
1136 av7110_ipack_reset(&av7110->ipack[1]); 1163 av7110_ipack_reset(&av7110->ipack[1]);
1137 1164
1138 if (av7110->playing == RP_AV) { 1165 if (av7110->playing == RP_AV) {
1139 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1166 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1140 __Play, 2, AV_PES, 0); 1167 __Play, 2, AV_PES, 0);
1168 if (ret)
1169 break;
1141 if (av7110->trickmode == TRICK_FAST) 1170 if (av7110->trickmode == TRICK_FAST)
1142 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1171 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1143 __Scan_I, 2, AV_PES, 0); 1172 __Scan_I, 2, AV_PES, 0);
1144 if (av7110->trickmode == TRICK_SLOW) { 1173 if (av7110->trickmode == TRICK_SLOW) {
1145 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1174 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1146 __Slow, 2, 0, 0); 1175 __Slow, 2, 0, 0);
1147 vidcom(av7110, VIDEO_CMD_SLOW, arg); 1176 if (!ret)
1177 ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
1148 } 1178 }
1149 if (av7110->trickmode == TRICK_FREEZE) 1179 if (av7110->trickmode == TRICK_FREEZE)
1150 vidcom(av7110, VIDEO_CMD_STOP, 1); 1180 ret = vidcom(av7110, VIDEO_CMD_STOP, 1);
1151 } 1181 }
1152 break; 1182 break;
1153 1183
@@ -1170,7 +1200,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1170 unsigned long arg = (unsigned long) parg; 1200 unsigned long arg = (unsigned long) parg;
1171 int ret = 0; 1201 int ret = 0;
1172 1202
1173 dprintk(2, "av7110:%p, \n", av7110); 1203 dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
1174 1204
1175 if (((file->f_flags & O_ACCMODE) == O_RDONLY) && 1205 if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
1176 (cmd != AUDIO_GET_STATUS)) 1206 (cmd != AUDIO_GET_STATUS))
@@ -1179,28 +1209,32 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1179 switch (cmd) { 1209 switch (cmd) {
1180 case AUDIO_STOP: 1210 case AUDIO_STOP:
1181 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1211 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1182 av7110_av_stop(av7110, RP_AUDIO); 1212 ret = av7110_av_stop(av7110, RP_AUDIO);
1183 else 1213 else
1184 audcom(av7110, AUDIO_CMD_MUTE); 1214 ret = audcom(av7110, AUDIO_CMD_MUTE);
1185 av7110->audiostate.play_state = AUDIO_STOPPED; 1215 if (!ret)
1216 av7110->audiostate.play_state = AUDIO_STOPPED;
1186 break; 1217 break;
1187 1218
1188 case AUDIO_PLAY: 1219 case AUDIO_PLAY:
1189 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) 1220 if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
1190 av7110_av_start_play(av7110, RP_AUDIO); 1221 ret = av7110_av_start_play(av7110, RP_AUDIO);
1191 audcom(av7110, AUDIO_CMD_UNMUTE); 1222 if (!ret)
1192 av7110->audiostate.play_state = AUDIO_PLAYING; 1223 ret = audcom(av7110, AUDIO_CMD_UNMUTE);
1224 if (!ret)
1225 av7110->audiostate.play_state = AUDIO_PLAYING;
1193 break; 1226 break;
1194 1227
1195 case AUDIO_PAUSE: 1228 case AUDIO_PAUSE:
1196 audcom(av7110, AUDIO_CMD_MUTE); 1229 ret = audcom(av7110, AUDIO_CMD_MUTE);
1197 av7110->audiostate.play_state = AUDIO_PAUSED; 1230 if (!ret)
1231 av7110->audiostate.play_state = AUDIO_PAUSED;
1198 break; 1232 break;
1199 1233
1200 case AUDIO_CONTINUE: 1234 case AUDIO_CONTINUE:
1201 if (av7110->audiostate.play_state == AUDIO_PAUSED) { 1235 if (av7110->audiostate.play_state == AUDIO_PAUSED) {
1202 av7110->audiostate.play_state = AUDIO_PLAYING; 1236 av7110->audiostate.play_state = AUDIO_PLAYING;
1203 audcom(av7110, AUDIO_CMD_MUTE | AUDIO_CMD_PCM16); 1237 ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16);
1204 } 1238 }
1205 break; 1239 break;
1206 1240
@@ -1210,14 +1244,15 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1210 1244
1211 case AUDIO_SET_MUTE: 1245 case AUDIO_SET_MUTE:
1212 { 1246 {
1213 audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); 1247 ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
1214 av7110->audiostate.mute_state = (int) arg; 1248 if (!ret)
1249 av7110->audiostate.mute_state = (int) arg;
1215 break; 1250 break;
1216 } 1251 }
1217 1252
1218 case AUDIO_SET_AV_SYNC: 1253 case AUDIO_SET_AV_SYNC:
1219 av7110->audiostate.AV_sync_state = (int) arg; 1254 av7110->audiostate.AV_sync_state = (int) arg;
1220 audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); 1255 ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
1221 break; 1256 break;
1222 1257
1223 case AUDIO_SET_BYPASS_MODE: 1258 case AUDIO_SET_BYPASS_MODE:
@@ -1229,21 +1264,24 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1229 1264
1230 switch(av7110->audiostate.channel_select) { 1265 switch(av7110->audiostate.channel_select) {
1231 case AUDIO_STEREO: 1266 case AUDIO_STEREO:
1232 audcom(av7110, AUDIO_CMD_STEREO); 1267 ret = audcom(av7110, AUDIO_CMD_STEREO);
1233 if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1268 if (!ret)
1234 i2c_writereg(av7110, 0x20, 0x02, 0x49); 1269 if (av7110->adac_type == DVB_ADAC_CRYSTAL)
1270 i2c_writereg(av7110, 0x20, 0x02, 0x49);
1235 break; 1271 break;
1236 1272
1237 case AUDIO_MONO_LEFT: 1273 case AUDIO_MONO_LEFT:
1238 audcom(av7110, AUDIO_CMD_MONO_L); 1274 ret = audcom(av7110, AUDIO_CMD_MONO_L);
1239 if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1275 if (!ret)
1240 i2c_writereg(av7110, 0x20, 0x02, 0x4a); 1276 if (av7110->adac_type == DVB_ADAC_CRYSTAL)
1277 i2c_writereg(av7110, 0x20, 0x02, 0x4a);
1241 break; 1278 break;
1242 1279
1243 case AUDIO_MONO_RIGHT: 1280 case AUDIO_MONO_RIGHT:
1244 audcom(av7110, AUDIO_CMD_MONO_R); 1281 ret = audcom(av7110, AUDIO_CMD_MONO_R);
1245 if (av7110->adac_type == DVB_ADAC_CRYSTAL) 1282 if (!ret)
1246 i2c_writereg(av7110, 0x20, 0x02, 0x45); 1283 if (av7110->adac_type == DVB_ADAC_CRYSTAL)
1284 i2c_writereg(av7110, 0x20, 0x02, 0x45);
1247 break; 1285 break;
1248 1286
1249 default: 1287 default:
@@ -1264,8 +1302,8 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1264 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); 1302 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
1265 av7110_ipack_reset(&av7110->ipack[0]); 1303 av7110_ipack_reset(&av7110->ipack[0]);
1266 if (av7110->playing == RP_AV) 1304 if (av7110->playing == RP_AV)
1267 av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, 1305 ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
1268 __Play, 2, AV_PES, 0); 1306 __Play, 2, AV_PES, 0);
1269 break; 1307 break;
1270 case AUDIO_SET_ID: 1308 case AUDIO_SET_ID:
1271 1309
@@ -1274,7 +1312,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
1274 { 1312 {
1275 struct audio_mixer *amix = (struct audio_mixer *)parg; 1313 struct audio_mixer *amix = (struct audio_mixer *)parg;
1276 1314
1277 av7110_set_volume(av7110, amix->volume_left, amix->volume_right); 1315 ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
1278 break; 1316 break;
1279 } 1317 }
1280 case AUDIO_SET_STREAMTYPE: 1318 case AUDIO_SET_STREAMTYPE:
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h
index cc5e7a7e87c3..45dc144b8b43 100644
--- a/drivers/media/dvb/ttpci/av7110_av.h
+++ b/drivers/media/dvb/ttpci/av7110_av.h
@@ -3,14 +3,14 @@
3 3
4struct av7110; 4struct av7110;
5 5
6extern void av7110_set_vidmode(struct av7110 *av7110, int mode); 6extern int av7110_set_vidmode(struct av7110 *av7110, int mode);
7 7
8extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len); 8extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
9extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen); 9extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
10extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len); 10extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
11 11
12extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright); 12extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
13extern void av7110_av_stop(struct av7110 *av7110, int av); 13extern int av7110_av_stop(struct av7110 *av7110, int av);
14extern int av7110_av_start_record(struct av7110 *av7110, int av, 14extern int av7110_av_start_record(struct av7110 *av7110, int av,
15 struct dvb_demux_feed *dvbdmxfeed); 15 struct dvb_demux_feed *dvbdmxfeed);
16extern int av7110_av_start_play(struct av7110 *av7110, int av); 16extern int av7110_av_start_play(struct av7110 *av7110, int av);
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 7fa4a0ebe133..1220826696c5 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -137,7 +137,7 @@ static int waitdebi(struct av7110 *av7110, int adr, int state)
137 return 0; 137 return 0;
138 udelay(5); 138 udelay(5);
139 } 139 }
140 return -1; 140 return -ETIMEDOUT;
141} 141}
142 142
143static int load_dram(struct av7110 *av7110, u32 *data, int len) 143static int load_dram(struct av7110 *av7110, u32 *data, int len)
@@ -155,7 +155,7 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
155 for (i = 0; i < blocks; i++) { 155 for (i = 0; i < blocks; i++) {
156 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { 156 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
157 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i); 157 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
158 return -1; 158 return -ETIMEDOUT;
159 } 159 }
160 dprintk(4, "writing DRAM block %d\n", i); 160 dprintk(4, "writing DRAM block %d\n", i);
161 mwdebi(av7110, DEBISWAB, bootblock, 161 mwdebi(av7110, DEBISWAB, bootblock,
@@ -170,7 +170,7 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
170 if (rest > 0) { 170 if (rest > 0) {
171 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { 171 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
172 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n"); 172 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
173 return -1; 173 return -ETIMEDOUT;
174 } 174 }
175 if (rest > 4) 175 if (rest > 4)
176 mwdebi(av7110, DEBISWAB, bootblock, 176 mwdebi(av7110, DEBISWAB, bootblock,
@@ -185,13 +185,13 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
185 } 185 }
186 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { 186 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
187 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n"); 187 printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
188 return -1; 188 return -ETIMEDOUT;
189 } 189 }
190 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2); 190 iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2);
191 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); 191 iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
192 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) { 192 if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) {
193 printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n"); 193 printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
194 return -1; 194 return -ETIMEDOUT;
195 } 195 }
196 return 0; 196 return 0;
197} 197}
@@ -263,7 +263,7 @@ int av7110_bootarm(struct av7110 *av7110)
263 if (saa7146_wait_for_debi_done(av7110->dev, 1)) { 263 if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
264 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " 264 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
265 "saa7146_wait_for_debi_done() timed out\n"); 265 "saa7146_wait_for_debi_done() timed out\n");
266 return -1; 266 return -ETIMEDOUT;
267 } 267 }
268 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); 268 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
269 mdelay(1); 269 mdelay(1);
@@ -284,7 +284,7 @@ int av7110_bootarm(struct av7110 *av7110)
284 if (saa7146_wait_for_debi_done(av7110->dev, 1)) { 284 if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
285 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " 285 printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
286 "saa7146_wait_for_debi_done() timed out after loading DRAM\n"); 286 "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
287 return -1; 287 return -ETIMEDOUT;
288 } 288 }
289 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); 289 saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
290 msleep(30); /* the firmware needs some time to initialize */ 290 msleep(30); /* the firmware needs some time to initialize */
@@ -308,6 +308,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
308{ 308{
309 unsigned long start; 309 unsigned long start;
310 u32 stat; 310 u32 stat;
311 int err;
311 312
312 if (FW_VERSION(av7110->arm_app) <= 0x261c) { 313 if (FW_VERSION(av7110->arm_app) <= 0x261c) {
313 /* not supported by old firmware */ 314 /* not supported by old firmware */
@@ -318,17 +319,17 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
318 /* new firmware */ 319 /* new firmware */
319 start = jiffies; 320 start = jiffies;
320 for (;;) { 321 for (;;) {
322 err = time_after(jiffies, start + ARM_WAIT_FREE);
321 if (down_interruptible(&av7110->dcomlock)) 323 if (down_interruptible(&av7110->dcomlock))
322 return -ERESTARTSYS; 324 return -ERESTARTSYS;
323 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 325 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
324 up(&av7110->dcomlock); 326 up(&av7110->dcomlock);
325 if ((stat & flags) == 0) { 327 if ((stat & flags) == 0)
326 break; 328 break;
327 } 329 if (err) {
328 if (time_after(jiffies, start + ARM_WAIT_FREE)) {
329 printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n", 330 printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
330 __FUNCTION__, stat & flags); 331 __FUNCTION__, stat & flags);
331 return -1; 332 return -ETIMEDOUT;
332 } 333 }
333 msleep(1); 334 msleep(1);
334 } 335 }
@@ -342,6 +343,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
342 char *type = NULL; 343 char *type = NULL;
343 u16 flags[2] = {0, 0}; 344 u16 flags[2] = {0, 0};
344 u32 stat; 345 u32 stat;
346 int err;
345 347
346// dprintk(4, "%p\n", av7110); 348// dprintk(4, "%p\n", av7110);
347 349
@@ -351,24 +353,30 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
351 } 353 }
352 354
353 start = jiffies; 355 start = jiffies;
354 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) { 356 while (1) {
355 msleep(1); 357 err = time_after(jiffies, start + ARM_WAIT_FREE);
356 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 358 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
359 break;
360 if (err) {
357 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); 361 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
358 return -ETIMEDOUT; 362 return -ETIMEDOUT;
359 } 363 }
364 msleep(1);
360 } 365 }
361 366
362 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2); 367 wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
363 368
364#ifndef _NOHANDSHAKE 369#ifndef _NOHANDSHAKE
365 start = jiffies; 370 start = jiffies;
366 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) { 371 while (1) {
367 msleep(1); 372 err = time_after(jiffies, start + ARM_WAIT_SHAKE);
368 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { 373 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
374 break;
375 if (err) {
369 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); 376 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
370 return -ETIMEDOUT; 377 return -ETIMEDOUT;
371 } 378 }
379 msleep(1);
372 } 380 }
373#endif 381#endif
374 382
@@ -401,6 +409,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
401 /* non-immediate COMMAND type */ 409 /* non-immediate COMMAND type */
402 start = jiffies; 410 start = jiffies;
403 for (;;) { 411 for (;;) {
412 err = time_after(jiffies, start + ARM_WAIT_FREE);
404 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 413 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
405 if (stat & flags[0]) { 414 if (stat & flags[0]) {
406 printk(KERN_ERR "%s: %s QUEUE overflow\n", 415 printk(KERN_ERR "%s: %s QUEUE overflow\n",
@@ -409,10 +418,10 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
409 } 418 }
410 if ((stat & flags[1]) == 0) 419 if ((stat & flags[1]) == 0)
411 break; 420 break;
412 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 421 if (err) {
413 printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", 422 printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
414 __FUNCTION__, type); 423 __FUNCTION__, type);
415 return -1; 424 return -ETIMEDOUT;
416 } 425 }
417 msleep(1); 426 msleep(1);
418 } 427 }
@@ -432,13 +441,16 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
432 441
433#ifdef COM_DEBUG 442#ifdef COM_DEBUG
434 start = jiffies; 443 start = jiffies;
435 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) { 444 while (1) {
436 msleep(1); 445 err = time_after(jiffies, start + ARM_WAIT_FREE);
437 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 446 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
438 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND to complete\n", 447 break;
439 __FUNCTION__); 448 if (err) {
449 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
450 __FUNCTION__, (buf[0] >> 8) & 0xff);
440 return -ETIMEDOUT; 451 return -ETIMEDOUT;
441 } 452 }
453 msleep(1);
442 } 454 }
443 455
444 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); 456 stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
@@ -470,7 +482,7 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
470 482
471 ret = __av7110_send_fw_cmd(av7110, buf, length); 483 ret = __av7110_send_fw_cmd(av7110, buf, length);
472 up(&av7110->dcomlock); 484 up(&av7110->dcomlock);
473 if (ret) 485 if (ret && ret!=-ERESTARTSYS)
474 printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", 486 printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
475 __FUNCTION__, ret); 487 __FUNCTION__, ret);
476 return ret; 488 return ret;
@@ -495,7 +507,7 @@ int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
495 } 507 }
496 508
497 ret = av7110_send_fw_cmd(av7110, buf, num + 2); 509 ret = av7110_send_fw_cmd(av7110, buf, num + 2);
498 if (ret) 510 if (ret && ret != -ERESTARTSYS)
499 printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret); 511 printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
500 return ret; 512 return ret;
501} 513}
@@ -518,7 +530,7 @@ int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
518 } 530 }
519 531
520 ret = av7110_send_fw_cmd(av7110, cmd, 18); 532 ret = av7110_send_fw_cmd(av7110, cmd, 18);
521 if (ret) 533 if (ret && ret != -ERESTARTSYS)
522 printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret); 534 printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
523 return ret; 535 return ret;
524} 536}
@@ -551,26 +563,32 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
551 } 563 }
552 564
553 start = jiffies; 565 start = jiffies;
554 while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) { 566 while (1) {
555#ifdef _NOHANDSHAKE 567 err = time_after(jiffies, start + ARM_WAIT_FREE);
556 msleep(1); 568 if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
557#endif 569 break;
558 if (time_after(jiffies, start + ARM_WAIT_FREE)) { 570 if (err) {
559 printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); 571 printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
560 up(&av7110->dcomlock); 572 up(&av7110->dcomlock);
561 return -1; 573 return -ETIMEDOUT;
562 } 574 }
575#ifdef _NOHANDSHAKE
576 msleep(1);
577#endif
563 } 578 }
564 579
565#ifndef _NOHANDSHAKE 580#ifndef _NOHANDSHAKE
566 start = jiffies; 581 start = jiffies;
567 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) { 582 while (1) {
568 msleep(1); 583 err = time_after(jiffies, start + ARM_WAIT_SHAKE);
569 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { 584 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
585 break;
586 if (err) {
570 printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); 587 printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
571 up(&av7110->dcomlock); 588 up(&av7110->dcomlock);
572 return -1; 589 return -ETIMEDOUT;
573 } 590 }
591 msleep(1);
574 } 592 }
575#endif 593#endif
576 594
@@ -667,10 +685,10 @@ int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long bu
667 for (i = 0; i < len; i++) 685 for (i = 0; i < len; i++)
668 buf[i + 4] = msg[i]; 686 buf[i + 4] = msg[i];
669 687
670 if ((ret = av7110_send_fw_cmd(av7110, buf, 18))) 688 ret = av7110_send_fw_cmd(av7110, buf, 18);
689 if (ret && ret!=-ERESTARTSYS)
671 printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret); 690 printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
672 691 return ret;
673 return 0;
674} 692}
675 693
676 694
@@ -705,18 +723,22 @@ static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize,
705static int FlushText(struct av7110 *av7110) 723static int FlushText(struct av7110 *av7110)
706{ 724{
707 unsigned long start; 725 unsigned long start;
726 int err;
708 727
709 if (down_interruptible(&av7110->dcomlock)) 728 if (down_interruptible(&av7110->dcomlock))
710 return -ERESTARTSYS; 729 return -ERESTARTSYS;
711 start = jiffies; 730 start = jiffies;
712 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) { 731 while (1) {
713 msleep(1); 732 err = time_after(jiffies, start + ARM_WAIT_OSD);
714 if (time_after(jiffies, start + ARM_WAIT_OSD)) { 733 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
734 break;
735 if (err) {
715 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", 736 printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
716 __FUNCTION__); 737 __FUNCTION__);
717 up(&av7110->dcomlock); 738 up(&av7110->dcomlock);
718 return -1; 739 return -ETIMEDOUT;
719 } 740 }
741 msleep(1);
720 } 742 }
721 up(&av7110->dcomlock); 743 up(&av7110->dcomlock);
722 return 0; 744 return 0;
@@ -733,25 +755,31 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
733 return -ERESTARTSYS; 755 return -ERESTARTSYS;
734 756
735 start = jiffies; 757 start = jiffies;
736 while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) { 758 while (1) {
737 msleep(1); 759 ret = time_after(jiffies, start + ARM_WAIT_OSD);
738 if (time_after(jiffies, start + ARM_WAIT_OSD)) { 760 if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
761 break;
762 if (ret) {
739 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", 763 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
740 __FUNCTION__); 764 __FUNCTION__);
741 up(&av7110->dcomlock); 765 up(&av7110->dcomlock);
742 return -1; 766 return -ETIMEDOUT;
743 } 767 }
768 msleep(1);
744 } 769 }
745#ifndef _NOHANDSHAKE 770#ifndef _NOHANDSHAKE
746 start = jiffies; 771 start = jiffies;
747 while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) { 772 while (1) {
748 msleep(1); 773 ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
749 if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { 774 if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
775 break;
776 if (ret) {
750 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", 777 printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
751 __FUNCTION__); 778 __FUNCTION__);
752 up(&av7110->dcomlock); 779 up(&av7110->dcomlock);
753 return -1; 780 return -ETIMEDOUT;
754 } 781 }
782 msleep(1);
755 } 783 }
756#endif 784#endif
757 for (i = 0; i < length / 2; i++) 785 for (i = 0; i < length / 2; i++)
@@ -761,7 +789,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
761 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2); 789 wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
762 ret = __av7110_send_fw_cmd(av7110, cbuf, 5); 790 ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
763 up(&av7110->dcomlock); 791 up(&av7110->dcomlock);
764 if (ret) 792 if (ret && ret!=-ERESTARTSYS)
765 printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret); 793 printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
766 return ret; 794 return ret;
767} 795}
@@ -816,9 +844,25 @@ static osd_raw_window_t bpp2bit[8] = {
816 OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8 844 OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
817}; 845};
818 846
819static inline int LoadBitmap(struct av7110 *av7110, u16 format, 847static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
848{
849 int ret = wait_event_interruptible_timeout(av7110->bmpq,
850 av7110->bmp_state != BMP_LOADING, 10*HZ);
851 if (ret == -ERESTARTSYS)
852 return ret;
853 if (ret == 0) {
854 printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
855 ret, av7110->bmp_state);
856 av7110->bmp_state = BMP_NONE;
857 return -ETIMEDOUT;
858 }
859 return 0;
860}
861
862static inline int LoadBitmap(struct av7110 *av7110,
820 u16 dx, u16 dy, int inc, u8 __user * data) 863 u16 dx, u16 dy, int inc, u8 __user * data)
821{ 864{
865 u16 format;
822 int bpp; 866 int bpp;
823 int i; 867 int i;
824 int d, delta; 868 int d, delta;
@@ -827,14 +871,7 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
827 871
828 dprintk(4, "%p\n", av7110); 872 dprintk(4, "%p\n", av7110);
829 873
830 ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ); 874 format = bpp2bit[av7110->osdbpp[av7110->osdwin]];
831 if (ret == -ERESTARTSYS || ret == 0) {
832 printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
833 ret, av7110->bmp_state);
834 av7110->bmp_state = BMP_NONE;
835 return -1;
836 }
837 BUG_ON (av7110->bmp_state == BMP_LOADING);
838 875
839 av7110->bmp_state = BMP_LOADING; 876 av7110->bmp_state = BMP_LOADING;
840 if (format == OSD_BITMAP8) { 877 if (format == OSD_BITMAP8) {
@@ -847,18 +884,18 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
847 bpp=1; delta = 8; 884 bpp=1; delta = 8;
848 } else { 885 } else {
849 av7110->bmp_state = BMP_NONE; 886 av7110->bmp_state = BMP_NONE;
850 return -1; 887 return -EINVAL;
851 } 888 }
852 av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8; 889 av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
853 av7110->bmpp = 0; 890 av7110->bmpp = 0;
854 if (av7110->bmplen > 32768) { 891 if (av7110->bmplen > 32768) {
855 av7110->bmp_state = BMP_NONE; 892 av7110->bmp_state = BMP_NONE;
856 return -1; 893 return -EINVAL;
857 } 894 }
858 for (i = 0; i < dy; i++) { 895 for (i = 0; i < dy; i++) {
859 if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) { 896 if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
860 av7110->bmp_state = BMP_NONE; 897 av7110->bmp_state = BMP_NONE;
861 return -1; 898 return -EINVAL;
862 } 899 }
863 } 900 }
864 if (format != OSD_BITMAP8) { 901 if (format != OSD_BITMAP8) {
@@ -873,37 +910,27 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
873 } 910 }
874 av7110->bmplen += 1024; 911 av7110->bmplen += 1024;
875 dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen); 912 dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
876 return av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy); 913 ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
914 if (!ret)
915 ret = WaitUntilBmpLoaded(av7110);
916 return ret;
877} 917}
878 918
879static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans) 919static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y)
880{ 920{
881 int ret;
882
883 dprintk(4, "%p\n", av7110); 921 dprintk(4, "%p\n", av7110);
884 922
885 BUG_ON (av7110->bmp_state == BMP_NONE); 923 return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0);
886
887 ret = wait_event_interruptible_timeout(av7110->bmpq,
888 av7110->bmp_state != BMP_LOADING, 10*HZ);
889 if (ret == -ERESTARTSYS || ret == 0) {
890 printk("dvb-ttpci: warning: timeout waiting in BlitBitmap: %d, %d\n",
891 ret, av7110->bmp_state);
892 av7110->bmp_state = BMP_NONE;
893 return (ret == 0) ? -ETIMEDOUT : ret;
894 }
895
896 BUG_ON (av7110->bmp_state != BMP_LOADED);
897
898 return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
899} 924}
900 925
901static inline int ReleaseBitmap(struct av7110 *av7110) 926static inline int ReleaseBitmap(struct av7110 *av7110)
902{ 927{
903 dprintk(4, "%p\n", av7110); 928 dprintk(4, "%p\n", av7110);
904 929
905 if (av7110->bmp_state != BMP_LOADED) 930 if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
906 return -1; 931 return -1;
932 if (av7110->bmp_state == BMP_LOADING)
933 dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
907 av7110->bmp_state = BMP_NONE; 934 av7110->bmp_state = BMP_NONE;
908 return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0); 935 return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
909} 936}
@@ -924,18 +951,22 @@ static u32 RGB2YUV(u16 R, u16 G, u16 B)
924 return Cr | (Cb << 16) | (Y << 8); 951 return Cr | (Cb << 16) | (Y << 8);
925} 952}
926 953
927static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend) 954static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
928{ 955{
956 int ret;
957
929 u16 ch, cl; 958 u16 ch, cl;
930 u32 yuv; 959 u32 yuv;
931 960
932 yuv = blend ? RGB2YUV(r,g,b) : 0; 961 yuv = blend ? RGB2YUV(r,g,b) : 0;
933 cl = (yuv & 0xffff); 962 cl = (yuv & 0xffff);
934 ch = ((yuv >> 16) & 0xffff); 963 ch = ((yuv >> 16) & 0xffff);
935 SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], 964 ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
936 color, ch, cl); 965 color, ch, cl);
937 SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], 966 if (!ret)
938 color, ((blend >> 4) & 0x0f)); 967 ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
968 color, ((blend >> 4) & 0x0f));
969 return ret;
939} 970}
940 971
941static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last) 972static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
@@ -968,14 +999,14 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
968{ 999{
969 uint w, h, bpp, bpl, size, lpb, bnum, brest; 1000 uint w, h, bpp, bpl, size, lpb, bnum, brest;
970 int i; 1001 int i;
971 int rc; 1002 int rc,release_rc;
972 1003
973 w = x1 - x0 + 1; 1004 w = x1 - x0 + 1;
974 h = y1 - y0 + 1; 1005 h = y1 - y0 + 1;
975 if (inc <= 0) 1006 if (inc <= 0)
976 inc = w; 1007 inc = w;
977 if (w <= 0 || w > 720 || h <= 0 || h > 576) 1008 if (w <= 0 || w > 720 || h <= 0 || h > 576)
978 return -1; 1009 return -EINVAL;
979 bpp = av7110->osdbpp[av7110->osdwin] + 1; 1010 bpp = av7110->osdbpp[av7110->osdwin] + 1;
980 bpl = ((w * bpp + 7) & ~7) / 8; 1011 bpl = ((w * bpp + 7) & ~7) / 8;
981 size = h * bpl; 1012 size = h * bpl;
@@ -983,176 +1014,186 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
983 bnum = size / (lpb * bpl); 1014 bnum = size / (lpb * bpl);
984 brest = size - bnum * lpb * bpl; 1015 brest = size - bnum * lpb * bpl;
985 1016
986 for (i = 0; i < bnum; i++) { 1017 if (av7110->bmp_state == BMP_LOADING) {
987 rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]], 1018 /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */
988 w, lpb, inc, data); 1019 BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e);
989 if (rc) 1020 rc = WaitUntilBmpLoaded(av7110);
990 return rc;
991 rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
992 if (rc) 1021 if (rc)
993 return rc; 1022 return rc;
994 data += lpb * inc; 1023 /* just continue. This should work for all fw versions
1024 * if bnum==1 && !brest && LoadBitmap was successful
1025 */
995 } 1026 }
996 if (brest) { 1027
997 rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]], 1028 rc = 0;
998 w, brest / bpl, inc, data); 1029 for (i = 0; i < bnum; i++) {
1030 rc = LoadBitmap(av7110, w, lpb, inc, data);
999 if (rc) 1031 if (rc)
1000 return rc; 1032 break;
1001 rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0); 1033 rc = BlitBitmap(av7110, x0, y0 + i * lpb);
1002 if (rc) 1034 if (rc)
1003 return rc; 1035 break;
1036 data += lpb * inc;
1004 } 1037 }
1005 ReleaseBitmap(av7110); 1038 if (!rc && brest) {
1006 return 0; 1039 rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
1040 if (!rc)
1041 rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
1042 }
1043 release_rc = ReleaseBitmap(av7110);
1044 if (!rc)
1045 rc = release_rc;
1046 if (rc)
1047 dprintk(1,"returns %d\n",rc);
1048 return rc;
1007} 1049}
1008 1050
1009int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) 1051int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
1010{ 1052{
1011 int ret; 1053 int ret;
1012 1054
1013 ret = down_interruptible(&av7110->osd_sema); 1055 if (down_interruptible(&av7110->osd_sema))
1014 if (ret)
1015 return -ERESTARTSYS; 1056 return -ERESTARTSYS;
1016 1057
1017 /* stupid, but OSD functions don't provide a return code anyway */
1018 ret = 0;
1019
1020 switch (dc->cmd) { 1058 switch (dc->cmd) {
1021 case OSD_Close: 1059 case OSD_Close:
1022 DestroyOSDWindow(av7110, av7110->osdwin); 1060 ret = DestroyOSDWindow(av7110, av7110->osdwin);
1023 goto out; 1061 break;
1024 case OSD_Open: 1062 case OSD_Open:
1025 av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7; 1063 av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
1026 CreateOSDWindow(av7110, av7110->osdwin, 1064 ret = CreateOSDWindow(av7110, av7110->osdwin,
1027 bpp2bit[av7110->osdbpp[av7110->osdwin]], 1065 bpp2bit[av7110->osdbpp[av7110->osdwin]],
1028 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); 1066 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1067 if (ret)
1068 break;
1029 if (!dc->data) { 1069 if (!dc->data) {
1030 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); 1070 ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1031 SetColorBlend(av7110, av7110->osdwin); 1071 if (ret)
1072 break;
1073 ret = SetColorBlend(av7110, av7110->osdwin);
1032 } 1074 }
1033 goto out; 1075 break;
1034 case OSD_Show: 1076 case OSD_Show:
1035 MoveWindowRel(av7110, av7110->osdwin, 0, 0); 1077 ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0);
1036 goto out; 1078 break;
1037 case OSD_Hide: 1079 case OSD_Hide:
1038 HideWindow(av7110, av7110->osdwin); 1080 ret = HideWindow(av7110, av7110->osdwin);
1039 goto out; 1081 break;
1040 case OSD_Clear: 1082 case OSD_Clear:
1041 DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0); 1083 ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
1042 goto out; 1084 break;
1043 case OSD_Fill: 1085 case OSD_Fill:
1044 DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color); 1086 ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
1045 goto out; 1087 break;
1046 case OSD_SetColor: 1088 case OSD_SetColor:
1047 OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); 1089 ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
1048 goto out; 1090 break;
1049 case OSD_SetPalette: 1091 case OSD_SetPalette:
1050 { 1092 if (FW_VERSION(av7110->arm_app) >= 0x2618)
1051 if (FW_VERSION(av7110->arm_app) >= 0x2618) {
1052 ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0); 1093 ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
1053 goto out; 1094 else {
1054 } else {
1055 int i, len = dc->x0-dc->color+1; 1095 int i, len = dc->x0-dc->color+1;
1056 u8 __user *colors = (u8 __user *)dc->data; 1096 u8 __user *colors = (u8 __user *)dc->data;
1057 u8 r, g, b, blend; 1097 u8 r, g, b, blend;
1058 1098 ret = 0;
1059 for (i = 0; i<len; i++) { 1099 for (i = 0; i<len; i++) {
1060 if (get_user(r, colors + i * 4) || 1100 if (get_user(r, colors + i * 4) ||
1061 get_user(g, colors + i * 4 + 1) || 1101 get_user(g, colors + i * 4 + 1) ||
1062 get_user(b, colors + i * 4 + 2) || 1102 get_user(b, colors + i * 4 + 2) ||
1063 get_user(blend, colors + i * 4 + 3)) { 1103 get_user(blend, colors + i * 4 + 3)) {
1064 ret = -EFAULT; 1104 ret = -EFAULT;
1065 goto out; 1105 break;
1066 } 1106 }
1067 OSDSetColor(av7110, dc->color + i, r, g, b, blend); 1107 ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
1108 if (ret)
1109 break;
1068 } 1110 }
1069 } 1111 }
1070 ret = 0; 1112 break;
1071 goto out;
1072 }
1073 case OSD_SetTrans:
1074 goto out;
1075 case OSD_SetPixel: 1113 case OSD_SetPixel:
1076 DrawLine(av7110, av7110->osdwin, 1114 ret = DrawLine(av7110, av7110->osdwin,
1077 dc->x0, dc->y0, 0, 0, dc->color); 1115 dc->x0, dc->y0, 0, 0, dc->color);
1078 goto out; 1116 break;
1079 case OSD_GetPixel:
1080 goto out;
1081 case OSD_SetRow: 1117 case OSD_SetRow:
1082 dc->y1 = dc->y0; 1118 dc->y1 = dc->y0;
1083 /* fall through */ 1119 /* fall through */
1084 case OSD_SetBlock: 1120 case OSD_SetBlock:
1085 ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data); 1121 ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
1086 goto out; 1122 break;
1087 case OSD_FillRow: 1123 case OSD_FillRow:
1088 DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, 1124 ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1089 dc->x1-dc->x0+1, dc->y1, dc->color); 1125 dc->x1-dc->x0+1, dc->y1, dc->color);
1090 goto out; 1126 break;
1091 case OSD_FillBlock: 1127 case OSD_FillBlock:
1092 DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, 1128 ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
1093 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color); 1129 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
1094 goto out; 1130 break;
1095 case OSD_Line: 1131 case OSD_Line:
1096 DrawLine(av7110, av7110->osdwin, 1132 ret = DrawLine(av7110, av7110->osdwin,
1097 dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color); 1133 dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
1098 goto out; 1134 break;
1099 case OSD_Query:
1100 goto out;
1101 case OSD_Test:
1102 goto out;
1103 case OSD_Text: 1135 case OSD_Text:
1104 { 1136 {
1105 char textbuf[240]; 1137 char textbuf[240];
1106 1138
1107 if (strncpy_from_user(textbuf, dc->data, 240) < 0) { 1139 if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
1108 ret = -EFAULT; 1140 ret = -EFAULT;
1109 goto out; 1141 break;
1110 } 1142 }
1111 textbuf[239] = 0; 1143 textbuf[239] = 0;
1112 if (dc->x1 > 3) 1144 if (dc->x1 > 3)
1113 dc->x1 = 3; 1145 dc->x1 = 3;
1114 SetFont(av7110, av7110->osdwin, dc->x1, 1146 ret = SetFont(av7110, av7110->osdwin, dc->x1,
1115 (u16) (dc->color & 0xffff), (u16) (dc->color >> 16)); 1147 (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
1116 FlushText(av7110); 1148 if (!ret)
1117 WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf); 1149 ret = FlushText(av7110);
1118 goto out; 1150 if (!ret)
1151 ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
1152 break;
1119 } 1153 }
1120 case OSD_SetWindow: 1154 case OSD_SetWindow:
1121 if (dc->x0 < 1 || dc->x0 > 7) { 1155 if (dc->x0 < 1 || dc->x0 > 7)
1122 ret = -EINVAL; 1156 ret = -EINVAL;
1123 goto out; 1157 else {
1158 av7110->osdwin = dc->x0;
1159 ret = 0;
1124 } 1160 }
1125 av7110->osdwin = dc->x0; 1161 break;
1126 goto out;
1127 case OSD_MoveWindow: 1162 case OSD_MoveWindow:
1128 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); 1163 ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1129 SetColorBlend(av7110, av7110->osdwin); 1164 if (!ret)
1130 goto out; 1165 ret = SetColorBlend(av7110, av7110->osdwin);
1166 break;
1131 case OSD_OpenRaw: 1167 case OSD_OpenRaw:
1132 if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) { 1168 if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
1133 ret = -EINVAL; 1169 ret = -EINVAL;
1134 goto out; 1170 break;
1135 } 1171 }
1136 if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) { 1172 if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR)
1137 av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1; 1173 av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
1138 } 1174 else
1139 else {
1140 av7110->osdbpp[av7110->osdwin] = 0; 1175 av7110->osdbpp[av7110->osdwin] = 0;
1141 } 1176 ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
1142 CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
1143 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); 1177 dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
1178 if (ret)
1179 break;
1144 if (!dc->data) { 1180 if (!dc->data) {
1145 MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); 1181 ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
1146 SetColorBlend(av7110, av7110->osdwin); 1182 if (!ret)
1183 ret = SetColorBlend(av7110, av7110->osdwin);
1147 } 1184 }
1148 goto out; 1185 break;
1149 default: 1186 default:
1150 ret = -EINVAL; 1187 ret = -EINVAL;
1151 goto out; 1188 break;
1152 } 1189 }
1153 1190
1154out:
1155 up(&av7110->osd_sema); 1191 up(&av7110->osd_sema);
1192 if (ret==-ERESTARTSYS)
1193 dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
1194 else if (ret)
1195 dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);
1196
1156 return ret; 1197 return ret;
1157} 1198}
1158 1199
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index 52061e17c6dd..fedd20f9815d 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -458,27 +458,27 @@ static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
458 return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data); 458 return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
459} 459}
460 460
461static inline void av7710_set_video_mode(struct av7110 *av7110, int mode) 461static inline int av7710_set_video_mode(struct av7110 *av7110, int mode)
462{ 462{
463 av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode); 463 return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
464} 464}
465 465
466static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg) 466static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
467{ 467{
468 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4, 468 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
469 (com>>16), (com&0xffff), 469 (com>>16), (com&0xffff),
470 (arg>>16), (arg&0xffff)); 470 (arg>>16), (arg&0xffff));
471} 471}
472 472
473static int inline audcom(struct av7110 *av7110, u32 com) 473static inline int audcom(struct av7110 *av7110, u32 com)
474{ 474{
475 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2, 475 return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
476 (com>>16), (com&0xffff)); 476 (com>>16), (com&0xffff));
477} 477}
478 478
479static inline void Set22K(struct av7110 *av7110, int state) 479static inline int Set22K(struct av7110 *av7110, int state)
480{ 480{
481 av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0); 481 return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
482} 482}
483 483
484 484
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c
index 246640741888..699ef8b5b99a 100644
--- a/drivers/media/dvb/ttpci/av7110_ipack.c
+++ b/drivers/media/dvb/ttpci/av7110_ipack.c
@@ -24,7 +24,7 @@ int av7110_ipack_init(struct ipack *p, int size,
24 void (*func)(u8 *buf, int size, void *priv)) 24 void (*func)(u8 *buf, int size, void *priv))
25{ 25{
26 if (!(p->buf = vmalloc(size*sizeof(u8)))) { 26 if (!(p->buf = vmalloc(size*sizeof(u8)))) {
27 printk ("Couldn't allocate memory for ipack\n"); 27 printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
28 return -ENOMEM; 28 return -ENOMEM;
29 } 29 }
30 p->size = size; 30 p->size = size;
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 6e0f5d307c52..b65f4b0a481f 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -570,9 +570,9 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
570 570
571 buf[0] = (div >> 8) & 0x7f; 571 buf[0] = (div >> 8) & 0x7f;
572 buf[1] = div & 0xff; 572 buf[1] = div & 0xff;
573 buf[2] = 0x8e; 573 buf[2] = 0x86;
574 buf[3] = (params->frequency < 174500000 ? 0xa1 : 574 buf[3] = (params->frequency < 150000000 ? 0x01 :
575 params->frequency < 454000000 ? 0x92 : 0x34); 575 params->frequency < 445000000 ? 0x02 : 0x04);
576 576
577 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) 577 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
578 return -EIO; 578 return -EIO;
@@ -695,8 +695,12 @@ static struct tda1004x_config philips_tu1216_config = {
695 .demod_address = 0x8, 695 .demod_address = 0x8,
696 .invert = 1, 696 .invert = 1,
697 .invert_oclk = 1, 697 .invert_oclk = 1,
698 .xtal_freq = TDA10046_XTAL_4M,
699 .agc_config = TDA10046_AGC_DEFAULT,
700 .if_freq = TDA10046_FREQ_3617,
698 .pll_init = philips_tu1216_pll_init, 701 .pll_init = philips_tu1216_pll_init,
699 .pll_set = philips_tu1216_pll_set, 702 .pll_set = philips_tu1216_pll_set,
703 .pll_sleep = NULL,
700 .request_firmware = philips_tu1216_request_firmware, 704 .request_firmware = philips_tu1216_request_firmware,
701}; 705};
702 706
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index dce116111376..a1267054bc01 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -69,6 +69,7 @@ struct budget_ci {
69 int slot_status; 69 int slot_status;
70 struct dvb_ca_en50221 ca; 70 struct dvb_ca_en50221 ca;
71 char ir_dev_name[50]; 71 char ir_dev_name[50];
72 u8 tuner_pll_address; /* used for philips_tdm1316l configs */
72}; 73};
73 74
74/* from reading the following remotes: 75/* from reading the following remotes:
@@ -723,7 +724,7 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
723 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; 724 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
724 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; 725 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
725 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; 726 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
726 struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = td1316_init,.len = 727 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
727 sizeof(td1316_init) }; 728 sizeof(td1316_init) };
728 729
729 // setup PLL configuration 730 // setup PLL configuration
@@ -746,7 +747,7 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend
746{ 747{
747 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; 748 struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
748 u8 tuner_buf[4]; 749 u8 tuner_buf[4];
749 struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) }; 750 struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
750 int tuner_frequency = 0; 751 int tuner_frequency = 0;
751 u8 band, cp, filter; 752 u8 band, cp, filter;
752 753
@@ -838,8 +839,12 @@ static struct tda1004x_config philips_tdm1316l_config = {
838 .demod_address = 0x8, 839 .demod_address = 0x8,
839 .invert = 0, 840 .invert = 0,
840 .invert_oclk = 0, 841 .invert_oclk = 0,
842 .xtal_freq = TDA10046_XTAL_4M,
843 .agc_config = TDA10046_AGC_DEFAULT,
844 .if_freq = TDA10046_FREQ_3617,
841 .pll_init = philips_tdm1316l_pll_init, 845 .pll_init = philips_tdm1316l_pll_init,
842 .pll_set = philips_tdm1316l_pll_set, 846 .pll_set = philips_tdm1316l_pll_set,
847 .pll_sleep = NULL,
843 .request_firmware = philips_tdm1316l_request_firmware, 848 .request_firmware = philips_tdm1316l_request_firmware,
844}; 849};
845 850
@@ -865,12 +870,22 @@ static void frontend_init(struct budget_ci *budget_ci)
865 break; 870 break;
866 871
867 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889) 872 case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
873 budget_ci->tuner_pll_address = 0x63;
868 budget_ci->budget.dvb_frontend = 874 budget_ci->budget.dvb_frontend =
869 tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); 875 tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
870 if (budget_ci->budget.dvb_frontend) { 876 if (budget_ci->budget.dvb_frontend) {
871 break; 877 break;
872 } 878 }
873 break; 879 break;
880
881 case 0x1012: // Hauppauge/TT Nova-T CI budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
882 budget_ci->tuner_pll_address = 0x60;
883 budget_ci->budget.dvb_frontend =
884 tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
885 if (budget_ci->budget.dvb_frontend) {
886 break;
887 }
888 break;
874 } 889 }
875 890
876 if (budget_ci->budget.dvb_frontend == NULL) { 891 if (budget_ci->budget.dvb_frontend == NULL) {
@@ -950,11 +965,13 @@ static struct saa7146_extension budget_extension;
950 965
951MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); 966MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
952MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 967MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
968MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
953 969
954static struct pci_device_id pci_tbl[] = { 970static struct pci_device_id pci_tbl[] = {
955 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), 971 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
956 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f), 972 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
957 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), 973 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
974 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
958 { 975 {
959 .vendor = 0, 976 .vendor = 0,
960 } 977 }
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 083fd44e5f90..9961917e8a7f 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -40,6 +40,7 @@
40#include "ves1820.h" 40#include "ves1820.h"
41#include "l64781.h" 41#include "l64781.h"
42#include "tda8083.h" 42#include "tda8083.h"
43#include "s5h1420.h"
43 44
44static void Set22K (struct budget *budget, int state) 45static void Set22K (struct budget *budget, int state)
45{ 46{
@@ -177,6 +178,62 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m
177 return 0; 178 return 0;
178} 179}
179 180
181static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
182{
183 struct budget* budget = (struct budget*) fe->dvb->priv;
184 u8 buf;
185 struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
186
187 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
188
189 switch(voltage) {
190 case SEC_VOLTAGE_13:
191 buf = (buf & 0xf7) | 0x04;
192 break;
193
194 case SEC_VOLTAGE_18:
195 buf = (buf & 0xf7) | 0x0c;
196 break;
197
198 case SEC_VOLTAGE_OFF:
199 buf = buf & 0xf0;
200 break;
201 }
202
203 msg.flags = 0;
204 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
205
206 return 0;
207}
208
209static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
210{
211 struct budget* budget = (struct budget*) fe->dvb->priv;
212 u8 buf;
213 struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
214
215 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
216
217 if (arg) {
218 buf = buf | 0x10;
219 } else {
220 buf = buf & 0xef;
221 }
222
223 msg.flags = 0;
224 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
225
226 return 0;
227}
228
229static void lnbp21_init(struct budget* budget)
230{
231 u8 buf = 0x00;
232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
233
234 i2c_transfer (&budget->i2c_adap, &msg, 1);
235}
236
180static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 237static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
181{ 238{
182 struct budget* budget = (struct budget*) fe->dvb->priv; 239 struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -395,6 +452,38 @@ static struct tda8083_config grundig_29504_451_config = {
395 .pll_set = grundig_29504_451_pll_set, 452 .pll_set = grundig_29504_451_pll_set,
396}; 453};
397 454
455static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout)
456{
457 struct budget* budget = (struct budget*) fe->dvb->priv;
458 u32 div;
459 u8 data[4];
460 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
461
462 div = params->frequency / 1000;
463 data[0] = (div >> 8) & 0x7f;
464 data[1] = div & 0xff;
465 data[2] = 0xc2;
466
467 if (div < 1450)
468 data[3] = 0x00;
469 else if (div < 1850)
470 data[3] = 0x40;
471 else if (div < 2000)
472 data[3] = 0x80;
473 else
474 data[3] = 0xc0;
475
476 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
477
478 *freqout = div * 1000;
479 return 0;
480}
481
482static struct s5h1420_config s5h1420_config = {
483 .demod_address = 0x53,
484 .pll_set = s5h1420_pll_set,
485};
486
398static u8 read_pwm(struct budget* budget) 487static u8 read_pwm(struct budget* budget)
399{ 488{
400 u8 b = 0xff; 489 u8 b = 0xff;
@@ -459,6 +548,15 @@ static void frontend_init(struct budget *budget)
459 break; 548 break;
460 } 549 }
461 break; 550 break;
551
552 case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
553 budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
554 if (budget->dvb_frontend) {
555 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
556 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
557 lnbp21_init(budget);
558 break;
559 }
462 } 560 }
463 561
464 if (budget->dvb_frontend == NULL) { 562 if (budget->dvb_frontend == NULL) {
@@ -532,6 +630,7 @@ static struct pci_device_id pci_tbl[] = {
532 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), 630 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
533 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), 631 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
534 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 632 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
633 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
535 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 634 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
536 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 635 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
537 { 636 {
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index 4aa714ab4c28..c6c1d41a2efb 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -3,6 +3,7 @@ config DVB_TTUSB_BUDGET
3 depends on DVB_CORE && USB 3 depends on DVB_CORE && USB
4 select DVB_CX22700 4 select DVB_CX22700
5 select DVB_TDA1004X 5 select DVB_TDA1004X
6 select DVB_VES1820
6 select DVB_TDA8083 7 select DVB_TDA8083
7 select DVB_STV0299 8 select DVB_STV0299
8 help 9 help
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index afa0e7a0e506..2c17a5f58340 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -24,6 +24,7 @@
24#include "dmxdev.h" 24#include "dmxdev.h"
25#include "dvb_demux.h" 25#include "dvb_demux.h"
26#include "dvb_net.h" 26#include "dvb_net.h"
27#include "ves1820.h"
27#include "cx22700.h" 28#include "cx22700.h"
28#include "tda1004x.h" 29#include "tda1004x.h"
29#include "stv0299.h" 30#include "stv0299.h"
@@ -1367,6 +1368,47 @@ static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1367 .pll_set = ttusb_novas_grundig_29504_491_pll_set, 1368 .pll_set = ttusb_novas_grundig_29504_491_pll_set,
1368}; 1369};
1369 1370
1371static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
1372{
1373 struct ttusb* ttusb = fe->dvb->priv;
1374 u32 div;
1375 u8 data[4];
1376 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1377
1378 div = (params->frequency + 35937500 + 31250) / 62500;
1379
1380 data[0] = (div >> 8) & 0x7f;
1381 data[1] = div & 0xff;
1382 data[2] = 0x85 | ((div >> 10) & 0x60);
1383 data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
1384
1385 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1386 return -EIO;
1387
1388 return 0;
1389}
1390
1391
1392static struct ves1820_config alps_tdbe2_config = {
1393 .demod_address = 0x09,
1394 .xin = 57840000UL,
1395 .invert = 1,
1396 .selagc = VES1820_SELAGC_SIGNAMPERR,
1397 .pll_set = alps_tdbe2_pll_set,
1398};
1399
1400static u8 read_pwm(struct ttusb* ttusb)
1401{
1402 u8 b = 0xff;
1403 u8 pwm;
1404 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1405 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1406
1407 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1408 pwm = 0x48;
1409
1410 return pwm;
1411}
1370 1412
1371 1413
1372static void frontend_init(struct ttusb* ttusb) 1414static void frontend_init(struct ttusb* ttusb)
@@ -1394,6 +1436,12 @@ static void frontend_init(struct ttusb* ttusb)
1394 1436
1395 break; 1437 break;
1396 1438
1439 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
1440 ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
1441 if (ttusb->fe != NULL)
1442 break;
1443 break;
1444
1397 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) 1445 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1398 // try the ALPS TDMB7 first 1446 // try the ALPS TDMB7 first
1399 ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); 1447 ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
@@ -1570,7 +1618,7 @@ static void ttusb_disconnect(struct usb_interface *intf)
1570 1618
1571static struct usb_device_id ttusb_table[] = { 1619static struct usb_device_id ttusb_table[] = {
1572 {USB_DEVICE(0xb48, 0x1003)}, 1620 {USB_DEVICE(0xb48, 0x1003)},
1573/* {USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/ /* to be confirmed ???? */ 1621 {USB_DEVICE(0xb48, 0x1004)},
1574 {USB_DEVICE(0xb48, 0x1005)}, 1622 {USB_DEVICE(0xb48, 0x1005)},
1575 {} 1623 {}
1576}; 1624};
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 505bdaff5a7e..45c9a9a08e4d 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1281,6 +1281,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1281 if (firmware_size < 60) { 1281 if (firmware_size < 60) {
1282 printk("%s: firmware size too small for DSP code (%zu < 60).\n", 1282 printk("%s: firmware size too small for DSP code (%zu < 60).\n",
1283 __FUNCTION__, firmware_size); 1283 __FUNCTION__, firmware_size);
1284 release_firmware(fw_entry);
1284 return -1; 1285 return -1;
1285 } 1286 }
1286 1287
@@ -1294,6 +1295,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1294 printk("%s: crc32 check of DSP code failed (calculated " 1295 printk("%s: crc32 check of DSP code failed (calculated "
1295 "0x%08x != 0x%08x in file), file invalid.\n", 1296 "0x%08x != 0x%08x in file), file invalid.\n",
1296 __FUNCTION__, crc32_csum, crc32_check); 1297 __FUNCTION__, crc32_csum, crc32_check);
1298 release_firmware(fw_entry);
1297 return -1; 1299 return -1;
1298 } 1300 }
1299 memcpy(idstring, &firmware[36], 20); 1301 memcpy(idstring, &firmware[36], 20);
@@ -1308,15 +1310,19 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1308 1310
1309 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL); 1311 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1310 1312
1311 if (result) 1313 if (result) {
1314 release_firmware(fw_entry);
1312 return result; 1315 return result;
1316 }
1313 1317
1314 trans_count = 0; 1318 trans_count = 0;
1315 j = 0; 1319 j = 0;
1316 1320
1317 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL); 1321 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
1318 if (b == NULL) 1322 if (b == NULL) {
1323 release_firmware(fw_entry);
1319 return -ENOMEM; 1324 return -ENOMEM;
1325 }
1320 1326
1321 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) { 1327 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1322 size = firmware_size - i; 1328 size = firmware_size - i;
@@ -1345,6 +1351,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1345 1351
1346 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL); 1352 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1347 1353
1354 release_firmware(fw_entry);
1348 kfree(b); 1355 kfree(b);
1349 1356
1350 return result; 1357 return result;
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
index 1699cc9f6bb0..725af3af5b27 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -157,7 +157,8 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
157 157
158 /* allocate memory for the internal state */ 158 /* allocate memory for the internal state */
159 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); 159 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
160 if (state == NULL) goto error; 160 if (state == NULL)
161 return NULL;
161 162
162 /* setup the state */ 163 /* setup the state */
163 state->config = config; 164 state->config = config;
@@ -167,10 +168,6 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf
167 state->frontend.ops = &state->ops; 168 state->frontend.ops = &state->ops;
168 state->frontend.demodulator_priv = state; 169 state->frontend.demodulator_priv = state;
169 return &state->frontend; 170 return &state->frontend;
170
171error:
172 kfree(state);
173 return NULL;
174} 171}
175 172
176static struct dvb_frontend_ops ttusbdecfe_dvbs_ops; 173static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
@@ -181,7 +178,8 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
181 178
182 /* allocate memory for the internal state */ 179 /* allocate memory for the internal state */
183 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); 180 state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
184 if (state == NULL) goto error; 181 if (state == NULL)
182 return NULL;
185 183
186 /* setup the state */ 184 /* setup the state */
187 state->config = config; 185 state->config = config;
@@ -193,10 +191,6 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf
193 state->frontend.ops = &state->ops; 191 state->frontend.ops = &state->ops;
194 state->frontend.demodulator_priv = state; 192 state->frontend.demodulator_priv = state;
195 return &state->frontend; 193 return &state->frontend;
196
197error:
198 kfree(state);
199 return NULL;
200} 194}
201 195
202static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { 196static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 1b70f8b0feb9..e771064689e6 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -344,6 +344,7 @@ config VIDEO_CX88_DVB
344 select DVB_MT352 344 select DVB_MT352
345 select DVB_OR51132 345 select DVB_OR51132
346 select DVB_CX22702 346 select DVB_CX22702
347 select DVB_LGDT3302
347 ---help--- 348 ---help---
348 This adds support for DVB/ATSC cards based on the 349 This adds support for DVB/ATSC cards based on the
349 Connexant 2388x chip. 350 Connexant 2388x chip.
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index b3fb04356b71..b0b47c3cde3c 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.76 2005/06/08 01:28:09 mchehab Exp $ 2 * $Id: cx88-cards.c,v 1.85 2005/07/04 19:35:05 mkrufky 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.
@@ -401,7 +401,7 @@ struct cx88_board cx88_boards[] = {
401 .dvb = 1, 401 .dvb = 1,
402 }, 402 },
403 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { 403 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
404 .name = "DVICO FusionHDTV DVB-T1", 404 .name = "DViCO FusionHDTV DVB-T1",
405 .tuner_type = TUNER_ABSENT, /* No analog tuner */ 405 .tuner_type = TUNER_ABSENT, /* No analog tuner */
406 .radio_type = UNSET, 406 .radio_type = UNSET,
407 .tuner_addr = ADDR_UNSET, 407 .tuner_addr = ADDR_UNSET,
@@ -445,8 +445,8 @@ struct cx88_board cx88_boards[] = {
445 .gpio0 = 0x000007f8, 445 .gpio0 = 0x000007f8,
446 }, 446 },
447 }, 447 },
448 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = { 448 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
449 .name = "DViCO - FusionHDTV 3 Gold", 449 .name = "DViCO FusionHDTV 3 Gold-Q",
450 .tuner_type = TUNER_MICROTUNE_4042FI5, 450 .tuner_type = TUNER_MICROTUNE_4042FI5,
451 .radio_type = UNSET, 451 .radio_type = UNSET,
452 .tuner_addr = ADDR_UNSET, 452 .tuner_addr = ADDR_UNSET,
@@ -464,6 +464,9 @@ struct cx88_board cx88_boards[] = {
464 GPIO[3] selects RF input connector on tuner module 464 GPIO[3] selects RF input connector on tuner module
465 0 - RF connector labeled CABLE 465 0 - RF connector labeled CABLE
466 1 - RF connector labeled ANT 466 1 - RF connector labeled ANT
467 GPIO[4] selects high RF for QAM256 mode
468 0 - normal RF
469 1 - high RF
467 */ 470 */
468 .input = {{ 471 .input = {{
469 .type = CX88_VMUX_TELEVISION, 472 .type = CX88_VMUX_TELEVISION,
@@ -482,6 +485,7 @@ struct cx88_board cx88_boards[] = {
482 .vmux = 2, 485 .vmux = 2,
483 .gpio0 = 0x0f00, 486 .gpio0 = 0x0f00,
484 }}, 487 }},
488 .dvb = 1,
485 }, 489 },
486 [CX88_BOARD_HAUPPAUGE_DVB_T1] = { 490 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
487 .name = "Hauppauge Nova-T DVB-T", 491 .name = "Hauppauge Nova-T DVB-T",
@@ -520,7 +524,7 @@ struct cx88_board cx88_boards[] = {
520 .blackbird = 1, 524 .blackbird = 1,
521 }, 525 },
522 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = { 526 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
523 .name = "DVICO FusionHDTV DVB-T Plus", 527 .name = "DViCO FusionHDTV DVB-T Plus",
524 .tuner_type = TUNER_ABSENT, /* No analog tuner */ 528 .tuner_type = TUNER_ABSENT, /* No analog tuner */
525 .radio_type = UNSET, 529 .radio_type = UNSET,
526 .tuner_addr = ADDR_UNSET, 530 .tuner_addr = ADDR_UNSET,
@@ -700,21 +704,17 @@ struct cx88_board cx88_boards[] = {
700 }, 704 },
701 }, 705 },
702 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { 706 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
703 .name = "DViCO - FusionHDTV 3 Gold-T", 707 .name = "DViCO FusionHDTV 3 Gold-T",
704 .tuner_type = TUNER_THOMSON_DTT7611, 708 .tuner_type = TUNER_THOMSON_DTT7611,
705 .radio_type = UNSET, 709 .radio_type = UNSET,
706 .tuner_addr = ADDR_UNSET, 710 .tuner_addr = ADDR_UNSET,
707 .radio_addr = ADDR_UNSET, 711 .radio_addr = ADDR_UNSET,
708 /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */ 712 /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */
709 .input = {{ 713 .input = {{
710 .type = CX88_VMUX_TELEVISION, 714 .type = CX88_VMUX_TELEVISION,
711 .vmux = 0, 715 .vmux = 0,
712 .gpio0 = 0x0f0d, 716 .gpio0 = 0x0f0d,
713 },{ 717 },{
714 .type = CX88_VMUX_CABLE,
715 .vmux = 0,
716 .gpio0 = 0x0f05,
717 },{
718 .type = CX88_VMUX_COMPOSITE1, 718 .type = CX88_VMUX_COMPOSITE1,
719 .vmux = 1, 719 .vmux = 1,
720 .gpio0 = 0x0f00, 720 .gpio0 = 0x0f00,
@@ -723,7 +723,36 @@ struct cx88_board cx88_boards[] = {
723 .vmux = 2, 723 .vmux = 2,
724 .gpio0 = 0x0f00, 724 .gpio0 = 0x0f00,
725 }}, 725 }},
726 .dvb = 1,
726 }, 727 },
728 [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
729 .name = "ADS Tech Instant TV DVB-T PCI",
730 .tuner_type = TUNER_ABSENT,
731 .radio_type = UNSET,
732 .tuner_addr = ADDR_UNSET,
733 .radio_addr = ADDR_UNSET,
734 .input = {{
735 .type = CX88_VMUX_COMPOSITE1,
736 .vmux = 1,
737 .gpio0 = 0x0700,
738 .gpio2 = 0x0101,
739 },{
740 .type = CX88_VMUX_SVIDEO,
741 .vmux = 2,
742 .gpio0 = 0x0700,
743 .gpio2 = 0x0101,
744 }},
745 .dvb = 1,
746 },
747 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
748 .name = "TerraTec Cinergy 1400 DVB-T",
749 .tuner_type = TUNER_ABSENT,
750 .input = {{
751 .type = CX88_VMUX_DVB,
752 .vmux = 0,
753 }},
754 .dvb = 1,
755 },
727}; 756};
728const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 757const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
729 758
@@ -794,7 +823,7 @@ struct cx88_subid cx88_subids[] = {
794 },{ 823 },{
795 .subvendor = 0x18ac, 824 .subvendor = 0x18ac,
796 .subdevice = 0xd810, 825 .subdevice = 0xd810,
797 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD, 826 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
798 },{ 827 },{
799 .subvendor = 0x18ac, 828 .subvendor = 0x18ac,
800 .subdevice = 0xd820, 829 .subdevice = 0xd820,
@@ -843,7 +872,15 @@ struct cx88_subid cx88_subids[] = {
843 .subvendor = 0x10fc, 872 .subvendor = 0x10fc,
844 .subdevice = 0xd035, 873 .subdevice = 0xd035,
845 .card = CX88_BOARD_IODATA_GVBCTV7E, 874 .card = CX88_BOARD_IODATA_GVBCTV7E,
846 } 875 },{
876 .subvendor = 0x1421,
877 .subdevice = 0x0334,
878 .card = CX88_BOARD_ADSTECH_DVB_T_PCI,
879 },{
880 .subvendor = 0x153b,
881 .subdevice = 0x1166,
882 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
883 },
847}; 884};
848const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 885const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
849 886
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index c046a23537d3..96cb0ff33bbd 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.28 2005/06/12 04:19:19 mchehab Exp $ 2 * $Id: cx88-core.c,v 1.31 2005/06/22 22:58:04 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
@@ -545,12 +545,14 @@ void cx88_sram_channel_dump(struct cx88_core *core,
545 core->name,cx_read(ch->cnt2_reg)); 545 core->name,cx_read(ch->cnt2_reg));
546} 546}
547 547
548/* Used only on cx88-core */
548static char *cx88_pci_irqs[32] = { 549static char *cx88_pci_irqs[32] = {
549 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1", 550 "vid", "aud", "ts", "vip", "hst", "5", "6", "tm1",
550 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err", 551 "src_dma", "dst_dma", "risc_rd_err", "risc_wr_err",
551 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err", 552 "brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
552 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1" 553 "i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
553}; 554};
555/* Used only on cx88-video */
554char *cx88_vid_irqs[32] = { 556char *cx88_vid_irqs[32] = {
555 "y_risci1", "u_risci1", "v_risci1", "vbi_risc1", 557 "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
556 "y_risci2", "u_risci2", "v_risci2", "vbi_risc2", 558 "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
@@ -558,6 +560,7 @@ char *cx88_vid_irqs[32] = {
558 "y_sync", "u_sync", "v_sync", "vbi_sync", 560 "y_sync", "u_sync", "v_sync", "vbi_sync",
559 "opc_err", "par_err", "rip_err", "pci_abort", 561 "opc_err", "par_err", "rip_err", "pci_abort",
560}; 562};
563/* Used only on cx88-mpeg */
561char *cx88_mpeg_irqs[32] = { 564char *cx88_mpeg_irqs[32] = {
562 "ts_risci1", NULL, NULL, NULL, 565 "ts_risci1", NULL, NULL, NULL,
563 "ts_risci2", NULL, NULL, NULL, 566 "ts_risci2", NULL, NULL, NULL,
@@ -1006,21 +1009,7 @@ int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
1006 set_tvaudio(core); 1009 set_tvaudio(core);
1007 1010
1008 // tell i2c chips 1011 // tell i2c chips
1009#ifdef V4L2_I2C_CLIENTS
1010 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id); 1012 cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
1011#else
1012 {
1013 struct video_channel c;
1014 memset(&c,0,sizeof(c));
1015 c.channel = core->input;
1016 c.norm = VIDEO_MODE_PAL;
1017 if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP)))
1018 c.norm = VIDEO_MODE_NTSC;
1019 if (norm->id & V4L2_STD_SECAM)
1020 c.norm = VIDEO_MODE_SECAM;
1021 cx88_call_i2c_clients(core,VIDIOCSCHAN,&c);
1022 }
1023#endif
1024 1013
1025 // done 1014 // done
1026 return 0; 1015 return 0;
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 1a259c3966cd..690477a67917 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.33 2005/06/12 04:19:19 mchehab Exp $ 2 * $Id: cx88-dvb.c,v 1.39 2005/07/02 20:00:46 mkrufky 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
@@ -30,9 +30,10 @@
30#include <linux/file.h> 30#include <linux/file.h>
31#include <linux/suspend.h> 31#include <linux/suspend.h>
32 32
33/* those two frontends need merging via linuxtv cvs ... */ 33/* these three frontends need merging via linuxtv cvs ... */
34#define HAVE_CX22702 1 34#define HAVE_CX22702 1
35#define HAVE_OR51132 1 35#define HAVE_OR51132 1
36#define HAVE_LGDT3302 1
36 37
37#include "cx88.h" 38#include "cx88.h"
38#include "dvb-pll.h" 39#include "dvb-pll.h"
@@ -44,6 +45,9 @@
44#if HAVE_OR51132 45#if HAVE_OR51132
45# include "or51132.h" 46# include "or51132.h"
46#endif 47#endif
48#if HAVE_LGDT3302
49# include "lgdt3302.h"
50#endif
47 51
48MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 52MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
49MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -199,6 +203,32 @@ static struct or51132_config pchdtv_hd3000 = {
199}; 203};
200#endif 204#endif
201 205
206#if HAVE_LGDT3302
207static int lgdt3302_set_ts_param(struct dvb_frontend* fe, int is_punctured)
208{
209 struct cx8802_dev *dev= fe->dvb->priv;
210 if (is_punctured)
211 dev->ts_gen_cntrl |= 0x04;
212 else
213 dev->ts_gen_cntrl &= ~0x04;
214 return 0;
215}
216
217static struct lgdt3302_config fusionhdtv_3_gold_q = {
218 .demod_address = 0x0e,
219 .pll_address = 0x61,
220 .pll_desc = &dvb_pll_microtune_4042,
221 .set_ts_params = lgdt3302_set_ts_param,
222};
223
224static struct lgdt3302_config fusionhdtv_3_gold_t = {
225 .demod_address = 0x0e,
226 .pll_address = 0x61,
227 .pll_desc = &dvb_pll_thomson_dtt7611,
228 .set_ts_params = lgdt3302_set_ts_param,
229};
230#endif
231
202static int dvb_register(struct cx8802_dev *dev) 232static int dvb_register(struct cx8802_dev *dev)
203{ 233{
204 /* init struct videobuf_dvb */ 234 /* init struct videobuf_dvb */
@@ -212,6 +242,7 @@ static int dvb_register(struct cx8802_dev *dev)
212 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config, 242 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
213 &dev->core->i2c_adap); 243 &dev->core->i2c_adap);
214 break; 244 break;
245 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
215 case CX88_BOARD_CONEXANT_DVB_T1: 246 case CX88_BOARD_CONEXANT_DVB_T1:
216 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 247 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
217 &dev->core->i2c_adap); 248 &dev->core->i2c_adap);
@@ -231,6 +262,7 @@ static int dvb_register(struct cx8802_dev *dev)
231 break; 262 break;
232 case CX88_BOARD_KWORLD_DVB_T: 263 case CX88_BOARD_KWORLD_DVB_T:
233 case CX88_BOARD_DNTV_LIVE_DVB_T: 264 case CX88_BOARD_DNTV_LIVE_DVB_T:
265 case CX88_BOARD_ADSTECH_DVB_T_PCI:
234 dev->core->pll_addr = 0x61; 266 dev->core->pll_addr = 0x61;
235 dev->core->pll_desc = &dvb_pll_unknown_1; 267 dev->core->pll_desc = &dvb_pll_unknown_1;
236 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, 268 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
@@ -242,6 +274,36 @@ static int dvb_register(struct cx8802_dev *dev)
242 &dev->core->i2c_adap); 274 &dev->core->i2c_adap);
243 break; 275 break;
244#endif 276#endif
277#if HAVE_LGDT3302
278 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
279 dev->ts_gen_cntrl = 0x08;
280 {
281 /* Do a hardware reset of chip before using it. */
282 struct cx88_core *core = dev->core;
283
284 cx_clear(MO_GP0_IO, 1);
285 mdelay(100);
286 cx_set(MO_GP0_IO, 9); // ANT connector too FIXME
287 mdelay(200);
288 dev->dvb.frontend = lgdt3302_attach(&fusionhdtv_3_gold_q,
289 &dev->core->i2c_adap);
290 }
291 break;
292 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
293 dev->ts_gen_cntrl = 0x08;
294 {
295 /* Do a hardware reset of chip before using it. */
296 struct cx88_core *core = dev->core;
297
298 cx_clear(MO_GP0_IO, 1);
299 mdelay(100);
300 cx_set(MO_GP0_IO, 9); /* ANT connector too FIXME */
301 mdelay(200);
302 dev->dvb.frontend = lgdt3302_attach(&fusionhdtv_3_gold_t,
303 &dev->core->i2c_adap);
304 }
305 break;
306#endif
245 default: 307 default:
246 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 308 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
247 dev->core->name); 309 dev->core->name);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index e20adefcfc6c..b5342234b305 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.23 2005/06/12 04:19:19 mchehab Exp $ 2 $Id: cx88-i2c.c,v 1.24 2005/06/17 18:46:23 mkrufky 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
@@ -157,6 +157,7 @@ static struct i2c_client cx8800_i2c_client_template = {
157}; 157};
158 158
159static char *i2c_devs[128] = { 159static char *i2c_devs[128] = {
160 [ 0x1c >> 1 ] = "lgdt3302",
160 [ 0x86 >> 1 ] = "tda9887/cx22702", 161 [ 0x86 >> 1 ] = "tda9887/cx22702",
161 [ 0xa0 >> 1 ] = "eeprom", 162 [ 0xa0 >> 1 ] = "eeprom",
162 [ 0xc0 >> 1 ] = "tuner (analog)", 163 [ 0xc0 >> 1 ] = "tuner (analog)",
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index dc0dcf249aac..bdc26e75ab5f 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.11 2005/05/22 20:57:56 nsh Exp $ 2 * $Id: cx88-input.c,v 1.13 2005/06/13 16:07:46 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.
@@ -125,6 +125,86 @@ static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
125 125
126/* ---------------------------------------------------------------------- */ 126/* ---------------------------------------------------------------------- */
127 127
128/* ADS Tech Instant TV DVB-T PCI Remote */
129static IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
130 [ 0x5b ] = KEY_POWER,
131 [ 0x5f ] = KEY_MUTE,
132 [ 0x57 ] = KEY_1,
133 [ 0x4f ] = KEY_2,
134 [ 0x53 ] = KEY_3,
135 [ 0x56 ] = KEY_4,
136 [ 0x4e ] = KEY_5,
137 [ 0x5e ] = KEY_6,
138 [ 0x54 ] = KEY_7,
139 [ 0x4c ] = KEY_8,
140 [ 0x5c ] = KEY_9,
141 [ 0x4d ] = KEY_0,
142 [ 0x55 ] = KEY_GOTO,
143 [ 0x5d ] = KEY_SEARCH,
144 [ 0x17 ] = KEY_EPG, // Guide
145 [ 0x1f ] = KEY_MENU,
146 [ 0x0f ] = KEY_UP,
147 [ 0x46 ] = KEY_DOWN,
148 [ 0x16 ] = KEY_LEFT,
149 [ 0x1e ] = KEY_RIGHT,
150 [ 0x0e ] = KEY_SELECT, // Enter
151 [ 0x5a ] = KEY_INFO,
152 [ 0x52 ] = KEY_EXIT,
153 [ 0x59 ] = KEY_PREVIOUS,
154 [ 0x51 ] = KEY_NEXT,
155 [ 0x58 ] = KEY_REWIND,
156 [ 0x50 ] = KEY_FORWARD,
157 [ 0x44 ] = KEY_PLAYPAUSE,
158 [ 0x07 ] = KEY_STOP,
159 [ 0x1b ] = KEY_RECORD,
160 [ 0x13 ] = KEY_TUNER, // Live
161 [ 0x0a ] = KEY_A,
162 [ 0x12 ] = KEY_B,
163 [ 0x03 ] = KEY_PROG1, // 1
164 [ 0x01 ] = KEY_PROG2, // 2
165 [ 0x00 ] = KEY_PROG3, // 3
166 [ 0x06 ] = KEY_DVD,
167 [ 0x48 ] = KEY_AUX, // Photo
168 [ 0x40 ] = KEY_VIDEO,
169 [ 0x19 ] = KEY_AUDIO, // Music
170 [ 0x0b ] = KEY_CHANNELUP,
171 [ 0x08 ] = KEY_CHANNELDOWN,
172 [ 0x15 ] = KEY_VOLUMEUP,
173 [ 0x1c ] = KEY_VOLUMEDOWN,
174};
175
176/* ---------------------------------------------------------------------- */
177
178/* MSI TV@nywhere remote */
179static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
180 [ 0x00 ] = KEY_0, /* '0' */
181 [ 0x01 ] = KEY_1, /* '1' */
182 [ 0x02 ] = KEY_2, /* '2' */
183 [ 0x03 ] = KEY_3, /* '3' */
184 [ 0x04 ] = KEY_4, /* '4' */
185 [ 0x05 ] = KEY_5, /* '5' */
186 [ 0x06 ] = KEY_6, /* '6' */
187 [ 0x07 ] = KEY_7, /* '7' */
188 [ 0x08 ] = KEY_8, /* '8' */
189 [ 0x09 ] = KEY_9, /* '9' */
190 [ 0x0c ] = KEY_MUTE, /* 'Mute' */
191 [ 0x0f ] = KEY_SCREEN, /* 'Full Screen' */
192 [ 0x10 ] = KEY_F, /* 'Funtion' */
193 [ 0x11 ] = KEY_T, /* 'Time shift' */
194 [ 0x12 ] = KEY_POWER, /* 'Power' */
195 [ 0x13 ] = KEY_MEDIA, /* 'MTS' */
196 [ 0x14 ] = KEY_SLOW, /* 'Slow' */
197 [ 0x16 ] = KEY_REWIND, /* 'backward <<' */
198 [ 0x17 ] = KEY_ENTER, /* 'Return' */
199 [ 0x18 ] = KEY_FASTFORWARD, /* 'forward >>' */
200 [ 0x1a ] = KEY_CHANNELUP, /* 'Channel+' */
201 [ 0x1b ] = KEY_VOLUMEUP, /* 'Volume+' */
202 [ 0x1e ] = KEY_CHANNELDOWN, /* 'Channel-' */
203 [ 0x1f ] = KEY_VOLUMEDOWN, /* 'Volume-' */
204};
205
206/* ---------------------------------------------------------------------- */
207
128struct cx88_IR { 208struct cx88_IR {
129 struct cx88_core *core; 209 struct cx88_core *core;
130 struct input_dev input; 210 struct input_dev input;
@@ -269,6 +349,20 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
269 ir->mask_keyup = 0x80; 349 ir->mask_keyup = 0x80;
270 ir->polling = 1; // ms 350 ir->polling = 1; // ms
271 break; 351 break;
352 case CX88_BOARD_ADSTECH_DVB_T_PCI:
353 ir_codes = ir_codes_adstech_dvb_t_pci;
354 ir->gpio_addr = MO_GP1_IO;
355 ir->mask_keycode = 0xbf;
356 ir->mask_keyup = 0x40;
357 ir->polling = 50; // ms
358 break;
359 case CX88_BOARD_MSI_TVANYWHERE_MASTER:
360 ir_codes = ir_codes_msi_tvanywhere;
361 ir->gpio_addr = MO_GP1_IO;
362 ir->mask_keycode = 0x1f;
363 ir->mask_keyup = 0x40;
364 ir->polling = 1;
365 break;
272 } 366 }
273 367
274 if (NULL == ir_codes) { 368 if (NULL == ir_codes) {
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 9ade2ae91e9b..85da6dc8d0e0 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.26 2005/06/03 13:31:51 mchehab Exp $ 2 * $Id: cx88-mpeg.c,v 1.30 2005/07/05 19:44:40 mkrufky 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.
@@ -70,11 +70,16 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
70 70
71 if (cx88_boards[core->board].dvb) { 71 if (cx88_boards[core->board].dvb) {
72 /* negedge driven & software reset */ 72 /* negedge driven & software reset */
73 cx_write(TS_GEN_CNTRL, 0x40); 73 cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
74 udelay(100); 74 udelay(100);
75 cx_write(MO_PINMUX_IO, 0x00); 75 cx_write(MO_PINMUX_IO, 0x00);
76 cx_write(TS_HW_SOP_CNTRL,47<<16|188<<4|0x00); 76 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
77 cx_write(TS_SOP_STAT,0x00); 77 if ((core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q) ||
78 (core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T)) {
79 cx_write(TS_SOP_STAT, 0<<16 | 0<<14 | 1<<13 | 0<<12);
80 } else {
81 cx_write(TS_SOP_STAT,0x00);
82 }
78 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl); 83 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
79 udelay(100); 84 udelay(100);
80 } 85 }
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index e4ca7350df15..dc997549b634 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.63 2005/06/12 04:19:19 mchehab Exp $ 2 * $Id: cx88-video.c,v 1.70 2005/06/20 03:36:00 mkrufky 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
@@ -261,7 +261,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
261 .default_value = 0, 261 .default_value = 0,
262 .type = V4L2_CTRL_TYPE_INTEGER, 262 .type = V4L2_CTRL_TYPE_INTEGER,
263 }, 263 },
264 .off = 0, 264 .off = 128,
265 .reg = MO_HUE, 265 .reg = MO_HUE,
266 .mask = 0x00ff, 266 .mask = 0x00ff,
267 .shift = 0, 267 .shift = 0,
@@ -1351,9 +1351,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1351 V4L2_CAP_STREAMING | 1351 V4L2_CAP_STREAMING |
1352 V4L2_CAP_VBI_CAPTURE | 1352 V4L2_CAP_VBI_CAPTURE |
1353#if 0 1353#if 0
1354 V4L2_TUNER_CAP_LOW |
1355#endif
1356#if 0
1357 V4L2_CAP_VIDEO_OVERLAY | 1354 V4L2_CAP_VIDEO_OVERLAY |
1358#endif 1355#endif
1359 0; 1356 0;
@@ -1475,7 +1472,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1475 } 1472 }
1476 break; 1473 break;
1477 case 1: 1474 case 1:
1478 if (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD == core->board) { 1475 if (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q == core->board) {
1479 strcpy(a->name,"Line In"); 1476 strcpy(a->name,"Line In");
1480 a->capability = V4L2_AUDCAP_STEREO; 1477 a->capability = V4L2_AUDCAP_STEREO;
1481 return 0; 1478 return 0;
@@ -1588,11 +1585,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1588 { 1585 {
1589 struct v4l2_frequency *f = arg; 1586 struct v4l2_frequency *f = arg;
1590 1587
1588 memset(f,0,sizeof(*f));
1589
1591 if (UNSET == core->tuner_type) 1590 if (UNSET == core->tuner_type)
1592 return -EINVAL; 1591 return -EINVAL;
1593 if (f->tuner != 0) 1592
1594 return -EINVAL;
1595 memset(f,0,sizeof(*f));
1596 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1593 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1597 f->frequency = dev->freq; 1594 f->frequency = dev->freq;
1598 return 0; 1595 return 0;
@@ -1612,11 +1609,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1612 down(&dev->lock); 1609 down(&dev->lock);
1613 dev->freq = f->frequency; 1610 dev->freq = f->frequency;
1614 cx88_newstation(core); 1611 cx88_newstation(core);
1615#ifdef V4L2_I2C_CLIENTS
1616 cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f); 1612 cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
1617#else
1618 cx88_call_i2c_clients(dev->core,VIDIOCSFREQ,&dev->freq);
1619#endif
1620 up(&dev->lock); 1613 up(&dev->lock);
1621 return 0; 1614 return 0;
1622 } 1615 }
@@ -1714,11 +1707,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1714 sizeof(cap->card)); 1707 sizeof(cap->card));
1715 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); 1708 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
1716 cap->version = CX88_VERSION_CODE; 1709 cap->version = CX88_VERSION_CODE;
1717 cap->capabilities = V4L2_CAP_TUNER 1710 cap->capabilities = V4L2_CAP_TUNER;
1718#if 0
1719 | V4L2_TUNER_CAP_LOW
1720#endif
1721 ;
1722 return 0; 1711 return 0;
1723 } 1712 }
1724 case VIDIOC_G_TUNER: 1713 case VIDIOC_G_TUNER:
@@ -1730,19 +1719,8 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1730 1719
1731 memset(t,0,sizeof(*t)); 1720 memset(t,0,sizeof(*t));
1732 strcpy(t->name, "Radio"); 1721 strcpy(t->name, "Radio");
1733 t->rangelow = (int)(65*16);
1734 t->rangehigh = (int)(108*16);
1735 1722
1736#ifdef V4L2_I2C_CLIENTS
1737 cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t); 1723 cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t);
1738#else
1739 {
1740 struct video_tuner vt;
1741 memset(&vt,0,sizeof(vt));
1742 cx88_call_i2c_clients(dev,VIDIOCGTUNER,&vt);
1743 t->signal = vt.signal;
1744 }
1745#endif
1746 return 0; 1724 return 0;
1747 } 1725 }
1748 case VIDIOC_ENUMINPUT: 1726 case VIDIOC_ENUMINPUT:
@@ -1775,8 +1753,29 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1775 *id = 0; 1753 *id = 0;
1776 return 0; 1754 return 0;
1777 } 1755 }
1778 case VIDIOC_S_AUDIO: 1756 case VIDIOCSTUNER:
1757 {
1758 struct video_tuner *v = arg;
1759
1760 if (v->tuner) /* Only tuner 0 */
1761 return -EINVAL;
1762
1763 cx88_call_i2c_clients(dev->core,VIDIOCSTUNER,v);
1764 return 0;
1765 }
1779 case VIDIOC_S_TUNER: 1766 case VIDIOC_S_TUNER:
1767 {
1768 struct v4l2_tuner *t = arg;
1769
1770 if (0 != t->index)
1771 return -EINVAL;
1772
1773 cx88_call_i2c_clients(dev->core,VIDIOC_S_TUNER,t);
1774
1775 return 0;
1776 }
1777
1778 case VIDIOC_S_AUDIO:
1780 case VIDIOC_S_INPUT: 1779 case VIDIOC_S_INPUT:
1781 case VIDIOC_S_STD: 1780 case VIDIOC_S_STD:
1782 return 0; 1781 return 0;
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 867e988a5a93..bc5e038bc0fe 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.62 2005/06/12 04:19:19 mchehab Exp $ 2 * $Id: cx88.h,v 1.67 2005/07/01 12:10:07 mkrufky Exp $
3 * 3 *
4 * v4l2 device driver for cx2388x based TV cards 4 * v4l2 device driver for cx2388x based TV cards
5 * 5 *
@@ -51,8 +51,6 @@
51/* ----------------------------------------------------------- */ 51/* ----------------------------------------------------------- */
52/* defines and enums */ 52/* defines and enums */
53 53
54#define V4L2_I2C_CLIENTS 1
55
56#define FORMAT_FLAGS_PACKED 0x01 54#define FORMAT_FLAGS_PACKED 0x01
57#define FORMAT_FLAGS_PLANAR 0x02 55#define FORMAT_FLAGS_PLANAR 0x02
58 56
@@ -159,7 +157,7 @@ extern struct sram_channel cx88_sram_channels[];
159#define CX88_BOARD_KWORLD_DVB_T 14 157#define CX88_BOARD_KWORLD_DVB_T 14
160#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15 158#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15
161#define CX88_BOARD_KWORLD_LTV883 16 159#define CX88_BOARD_KWORLD_LTV883 16
162#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD 17 160#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q 17
163#define CX88_BOARD_HAUPPAUGE_DVB_T1 18 161#define CX88_BOARD_HAUPPAUGE_DVB_T1 18
164#define CX88_BOARD_CONEXANT_DVB_T1 19 162#define CX88_BOARD_CONEXANT_DVB_T1 19
165#define CX88_BOARD_PROVIDEO_PV259 20 163#define CX88_BOARD_PROVIDEO_PV259 20
@@ -167,10 +165,12 @@ extern struct sram_channel cx88_sram_channels[];
167#define CX88_BOARD_PCHDTV_HD3000 22 165#define CX88_BOARD_PCHDTV_HD3000 22
168#define CX88_BOARD_DNTV_LIVE_DVB_T 23 166#define CX88_BOARD_DNTV_LIVE_DVB_T 23
169#define CX88_BOARD_HAUPPAUGE_ROSLYN 24 167#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
170#define CX88_BOARD_DIGITALLOGIC_MEC 25 168#define CX88_BOARD_DIGITALLOGIC_MEC 25
171#define CX88_BOARD_IODATA_GVBCTV7E 26 169#define CX88_BOARD_IODATA_GVBCTV7E 26
172#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27 170#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27
173#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28 171#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28
172#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
173#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
174 174
175enum cx88_itype { 175enum cx88_itype {
176 CX88_VMUX_COMPOSITE1 = 1, 176 CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 8b623278ccd2..ffbe6f4720e1 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1363,19 +1363,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1363 u32 device_state; 1363 u32 device_state;
1364 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1364 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1365 1365
1366 switch(state) 1366 device_state=pci_choose_state(pdev, state);
1367 {
1368 case 1: /* S1 */
1369 device_state=1; /* D1 */;
1370 break;
1371 case 3: /* S3 */
1372 case 4: /* S4 */
1373 device_state=3; /* D3 */;
1374 break;
1375 default:
1376 return -EAGAIN /*FIXME*/;
1377 break;
1378 }
1379 1367
1380 printk(MYIOC_s_INFO_FMT 1368 printk(MYIOC_s_INFO_FMT
1381 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n", 1369 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 5ea89bf0df19..debb8ac59545 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -84,7 +84,7 @@
84extern void mptscsih_remove(struct pci_dev *); 84extern void mptscsih_remove(struct pci_dev *);
85extern void mptscsih_shutdown(struct pci_dev *); 85extern void mptscsih_shutdown(struct pci_dev *);
86#ifdef CONFIG_PM 86#ifdef CONFIG_PM
87extern int mptscsih_suspend(struct pci_dev *pdev, u32 state); 87extern int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
88extern int mptscsih_resume(struct pci_dev *pdev); 88extern int mptscsih_resume(struct pci_dev *pdev);
89#endif 89#endif
90extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func); 90extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
index d0267609a949..fe2e7afc9eae 100644
--- a/drivers/message/i2o/config-osm.c
+++ b/drivers/message/i2o/config-osm.c
@@ -15,7 +15,9 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/i2o.h> 17#include <linux/i2o.h>
18#include <linux/dcache.h>
18#include <linux/namei.h> 19#include <linux/namei.h>
20#include <linux/fs.h>
19 21
20#include <asm/uaccess.h> 22#include <asm/uaccess.h>
21 23
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index c2655a817e3d..ff7c50d10180 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -18,7 +18,6 @@
18#include <asm/io.h> 18#include <asm/io.h>
19#include <asm/system.h> 19#include <asm/system.h>
20 20
21#include <pcmcia/version.h>
22#include <pcmcia/cs_types.h> 21#include <pcmcia/cs_types.h>
23#include <pcmcia/cs.h> 22#include <pcmcia/cs.h>
24#include <pcmcia/cistpl.h> 23#include <pcmcia/cistpl.h>
@@ -800,11 +799,6 @@ static dev_link_t *pcmciamtd_attach(void)
800 799
801 /* Register with Card Services */ 800 /* Register with Card Services */
802 client_reg.dev_info = &dev_info; 801 client_reg.dev_info = &dev_info;
803 client_reg.EventMask =
804 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
805 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
806 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
807 client_reg.event_handler = &pcmciamtd_event;
808 client_reg.Version = 0x0210; 802 client_reg.Version = 0x0210;
809 client_reg.event_callback_args.client_data = link; 803 client_reg.event_callback_args.client_data = link;
810 DEBUG(2, "Calling RegisterClient"); 804 DEBUG(2, "Calling RegisterClient");
@@ -850,6 +844,7 @@ static struct pcmcia_driver pcmciamtd_driver = {
850 .name = "pcmciamtd" 844 .name = "pcmciamtd"
851 }, 845 },
852 .attach = pcmciamtd_attach, 846 .attach = pcmciamtd_attach,
847 .event = pcmciamtd_event,
853 .detach = pcmciamtd_detach, 848 .detach = pcmciamtd_detach,
854 .owner = THIS_MODULE, 849 .owner = THIS_MODULE,
855 .id_table = pcmciamtd_ids, 850 .id_table = pcmciamtd_ids,
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index f0fc04bd37c4..71fd41122c91 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -86,7 +86,6 @@ earlier 3Com products.
86#include <linux/ethtool.h> 86#include <linux/ethtool.h>
87#include <linux/bitops.h> 87#include <linux/bitops.h>
88 88
89#include <pcmcia/version.h>
90#include <pcmcia/cs_types.h> 89#include <pcmcia/cs_types.h>
91#include <pcmcia/cs.h> 90#include <pcmcia/cs.h>
92#include <pcmcia/cistpl.h> 91#include <pcmcia/cistpl.h>
@@ -312,11 +311,6 @@ static dev_link_t *tc574_attach(void)
312 link->next = dev_list; 311 link->next = dev_list;
313 dev_list = link; 312 dev_list = link;
314 client_reg.dev_info = &dev_info; 313 client_reg.dev_info = &dev_info;
315 client_reg.EventMask =
316 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
317 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
318 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
319 client_reg.event_handler = &tc574_event;
320 client_reg.Version = 0x0210; 314 client_reg.Version = 0x0210;
321 client_reg.event_callback_args.client_data = link; 315 client_reg.event_callback_args.client_data = link;
322 ret = pcmcia_register_client(&link->handle, &client_reg); 316 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1299,6 +1293,7 @@ static struct pcmcia_driver tc574_driver = {
1299 .name = "3c574_cs", 1293 .name = "3c574_cs",
1300 }, 1294 },
1301 .attach = tc574_attach, 1295 .attach = tc574_attach,
1296 .event = tc574_event,
1302 .detach = tc574_detach, 1297 .detach = tc574_detach,
1303 .id_table = tc574_ids, 1298 .id_table = tc574_ids,
1304}; 1299};
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 8fa1b5f0fb68..d83fdd8c1943 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -40,7 +40,6 @@
40#include <linux/ioport.h> 40#include <linux/ioport.h>
41#include <linux/bitops.h> 41#include <linux/bitops.h>
42 42
43#include <pcmcia/version.h>
44#include <pcmcia/cs_types.h> 43#include <pcmcia/cs_types.h>
45#include <pcmcia/cs.h> 44#include <pcmcia/cs.h>
46#include <pcmcia/cistpl.h> 45#include <pcmcia/cistpl.h>
@@ -226,11 +225,6 @@ static dev_link_t *tc589_attach(void)
226 link->next = dev_list; 225 link->next = dev_list;
227 dev_list = link; 226 dev_list = link;
228 client_reg.dev_info = &dev_info; 227 client_reg.dev_info = &dev_info;
229 client_reg.EventMask =
230 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
231 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
232 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
233 client_reg.event_handler = &tc589_event;
234 client_reg.Version = 0x0210; 228 client_reg.Version = 0x0210;
235 client_reg.event_callback_args.client_data = link; 229 client_reg.event_callback_args.client_data = link;
236 ret = pcmcia_register_client(&link->handle, &client_reg); 230 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1074,6 +1068,7 @@ static struct pcmcia_driver tc589_driver = {
1074 .name = "3c589_cs", 1068 .name = "3c589_cs",
1075 }, 1069 },
1076 .attach = tc589_attach, 1070 .attach = tc589_attach,
1071 .event = tc589_event,
1077 .detach = tc589_detach, 1072 .detach = tc589_detach,
1078 .id_table = tc589_ids, 1073 .id_table = tc589_ids,
1079}; 1074};
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 23ce77b1d5b0..8bb4e85689ea 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -37,7 +37,6 @@
37#include <linux/netdevice.h> 37#include <linux/netdevice.h>
38#include "../8390.h" 38#include "../8390.h"
39 39
40#include <pcmcia/version.h>
41#include <pcmcia/cs_types.h> 40#include <pcmcia/cs_types.h>
42#include <pcmcia/cs.h> 41#include <pcmcia/cs.h>
43#include <pcmcia/cistpl.h> 42#include <pcmcia/cistpl.h>
@@ -181,11 +180,6 @@ static dev_link_t *axnet_attach(void)
181 link->next = dev_list; 180 link->next = dev_list;
182 dev_list = link; 181 dev_list = link;
183 client_reg.dev_info = &dev_info; 182 client_reg.dev_info = &dev_info;
184 client_reg.EventMask =
185 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
186 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
187 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
188 client_reg.event_handler = &axnet_event;
189 client_reg.Version = 0x0210; 183 client_reg.Version = 0x0210;
190 client_reg.event_callback_args.client_data = link; 184 client_reg.event_callback_args.client_data = link;
191 ret = pcmcia_register_client(&link->handle, &client_reg); 185 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -884,6 +878,7 @@ static struct pcmcia_driver axnet_cs_driver = {
884 .name = "axnet_cs", 878 .name = "axnet_cs",
885 }, 879 },
886 .attach = axnet_attach, 880 .attach = axnet_attach,
881 .event = axnet_event,
887 .detach = axnet_detach, 882 .detach = axnet_detach,
888 .id_table = axnet_ids, 883 .id_table = axnet_ids,
889}; 884};
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 68d58cc58d31..b9355d9498a3 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -43,7 +43,6 @@
43#include <linux/arcdevice.h> 43#include <linux/arcdevice.h>
44#include <linux/com20020.h> 44#include <linux/com20020.h>
45 45
46#include <pcmcia/version.h>
47#include <pcmcia/cs_types.h> 46#include <pcmcia/cs_types.h>
48#include <pcmcia/cs.h> 47#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h> 48#include <pcmcia/cistpl.h>
@@ -200,11 +199,6 @@ static dev_link_t *com20020_attach(void)
200 link->next = dev_list; 199 link->next = dev_list;
201 dev_list = link; 200 dev_list = link;
202 client_reg.dev_info = &dev_info; 201 client_reg.dev_info = &dev_info;
203 client_reg.EventMask =
204 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
205 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
206 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
207 client_reg.event_handler = &com20020_event;
208 client_reg.Version = 0x0210; 202 client_reg.Version = 0x0210;
209 client_reg.event_callback_args.client_data = link; 203 client_reg.event_callback_args.client_data = link;
210 ret = pcmcia_register_client(&link->handle, &client_reg); 204 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -495,6 +489,7 @@ static struct pcmcia_driver com20020_cs_driver = {
495 .name = "com20020_cs", 489 .name = "com20020_cs",
496 }, 490 },
497 .attach = com20020_attach, 491 .attach = com20020_attach,
492 .event = com20020_event,
498 .detach = com20020_detach, 493 .detach = com20020_detach,
499 .id_table = com20020_ids, 494 .id_table = com20020_ids,
500}; 495};
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 917adbbf0b5b..9d8197bb293a 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -49,7 +49,6 @@
49#include <linux/ioport.h> 49#include <linux/ioport.h>
50#include <linux/crc32.h> 50#include <linux/crc32.h>
51 51
52#include <pcmcia/version.h>
53#include <pcmcia/cs_types.h> 52#include <pcmcia/cs_types.h>
54#include <pcmcia/cs.h> 53#include <pcmcia/cs.h>
55#include <pcmcia/cistpl.h> 54#include <pcmcia/cistpl.h>
@@ -288,11 +287,6 @@ static dev_link_t *fmvj18x_attach(void)
288 link->next = dev_list; 287 link->next = dev_list;
289 dev_list = link; 288 dev_list = link;
290 client_reg.dev_info = &dev_info; 289 client_reg.dev_info = &dev_info;
291 client_reg.EventMask =
292 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
293 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
294 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
295 client_reg.event_handler = &fmvj18x_event;
296 client_reg.Version = 0x0210; 290 client_reg.Version = 0x0210;
297 client_reg.event_callback_args.client_data = link; 291 client_reg.event_callback_args.client_data = link;
298 ret = pcmcia_register_client(&link->handle, &client_reg); 292 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -797,6 +791,7 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
797 .name = "fmvj18x_cs", 791 .name = "fmvj18x_cs",
798 }, 792 },
799 .attach = fmvj18x_attach, 793 .attach = fmvj18x_attach,
794 .event = fmvj18x_event,
800 .detach = fmvj18x_detach, 795 .detach = fmvj18x_detach,
801 .id_table = fmvj18x_ids, 796 .id_table = fmvj18x_ids,
802}; 797};
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index cf6d073ea558..b6c140eb9799 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -57,7 +57,6 @@
57#include <linux/trdevice.h> 57#include <linux/trdevice.h>
58#include <linux/ibmtr.h> 58#include <linux/ibmtr.h>
59 59
60#include <pcmcia/version.h>
61#include <pcmcia/cs_types.h> 60#include <pcmcia/cs_types.h>
62#include <pcmcia/cs.h> 61#include <pcmcia/cs.h>
63#include <pcmcia/cistpl.h> 62#include <pcmcia/cistpl.h>
@@ -190,11 +189,6 @@ static dev_link_t *ibmtr_attach(void)
190 link->next = dev_list; 189 link->next = dev_list;
191 dev_list = link; 190 dev_list = link;
192 client_reg.dev_info = &dev_info; 191 client_reg.dev_info = &dev_info;
193 client_reg.EventMask =
194 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
195 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
196 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
197 client_reg.event_handler = &ibmtr_event;
198 client_reg.Version = 0x0210; 192 client_reg.Version = 0x0210;
199 client_reg.event_callback_args.client_data = link; 193 client_reg.event_callback_args.client_data = link;
200 ret = pcmcia_register_client(&link->handle, &client_reg); 194 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -521,6 +515,7 @@ static struct pcmcia_driver ibmtr_cs_driver = {
521 .name = "ibmtr_cs", 515 .name = "ibmtr_cs",
522 }, 516 },
523 .attach = ibmtr_attach, 517 .attach = ibmtr_attach,
518 .event = ibmtr_event,
524 .detach = ibmtr_detach, 519 .detach = ibmtr_detach,
525 .id_table = ibmtr_ids, 520 .id_table = ibmtr_ids,
526}; 521};
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index b86e7253fbfc..dbb941004ae9 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -146,7 +146,6 @@ Include Files
146#include <linux/ioport.h> 146#include <linux/ioport.h>
147#include <linux/bitops.h> 147#include <linux/bitops.h>
148 148
149#include <pcmcia/version.h>
150#include <pcmcia/cs_types.h> 149#include <pcmcia/cs_types.h>
151#include <pcmcia/cs.h> 150#include <pcmcia/cs.h>
152#include <pcmcia/cisreg.h> 151#include <pcmcia/cisreg.h>
@@ -502,11 +501,6 @@ static dev_link_t *nmclan_attach(void)
502 link->next = dev_list; 501 link->next = dev_list;
503 dev_list = link; 502 dev_list = link;
504 client_reg.dev_info = &dev_info; 503 client_reg.dev_info = &dev_info;
505 client_reg.EventMask =
506 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
507 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
508 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
509 client_reg.event_handler = &nmclan_event;
510 client_reg.Version = 0x0210; 504 client_reg.Version = 0x0210;
511 client_reg.event_callback_args.client_data = link; 505 client_reg.event_callback_args.client_data = link;
512 ret = pcmcia_register_client(&link->handle, &client_reg); 506 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1688,6 +1682,7 @@ static struct pcmcia_driver nmclan_cs_driver = {
1688 .name = "nmclan_cs", 1682 .name = "nmclan_cs",
1689 }, 1683 },
1690 .attach = nmclan_attach, 1684 .attach = nmclan_attach,
1685 .event = nmclan_event,
1691 .detach = nmclan_detach, 1686 .detach = nmclan_detach,
1692 .id_table = nmclan_ids, 1687 .id_table = nmclan_ids,
1693}; 1688};
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 855a45d062b1..e1664aef3dfd 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -40,7 +40,6 @@
40#include <linux/netdevice.h> 40#include <linux/netdevice.h>
41#include <../drivers/net/8390.h> 41#include <../drivers/net/8390.h>
42 42
43#include <pcmcia/version.h>
44#include <pcmcia/cs_types.h> 43#include <pcmcia/cs_types.h>
45#include <pcmcia/cs.h> 44#include <pcmcia/cs.h>
46#include <pcmcia/cistpl.h> 45#include <pcmcia/cistpl.h>
@@ -276,11 +275,6 @@ static dev_link_t *pcnet_attach(void)
276 link->next = dev_list; 275 link->next = dev_list;
277 dev_list = link; 276 dev_list = link;
278 client_reg.dev_info = &dev_info; 277 client_reg.dev_info = &dev_info;
279 client_reg.EventMask =
280 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
281 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
282 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
283 client_reg.event_handler = &pcnet_event;
284 client_reg.Version = 0x0210; 278 client_reg.Version = 0x0210;
285 client_reg.event_callback_args.client_data = link; 279 client_reg.event_callback_args.client_data = link;
286 ret = pcmcia_register_client(&link->handle, &client_reg); 280 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1844,6 +1838,7 @@ static struct pcmcia_driver pcnet_driver = {
1844 .name = "pcnet_cs", 1838 .name = "pcnet_cs",
1845 }, 1839 },
1846 .attach = pcnet_attach, 1840 .attach = pcnet_attach,
1841 .event = pcnet_event,
1847 .detach = pcnet_detach, 1842 .detach = pcnet_detach,
1848 .owner = THIS_MODULE, 1843 .owner = THIS_MODULE,
1849 .id_table = pcnet_ids, 1844 .id_table = pcnet_ids,
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index bc01c88c6709..fbc2f58ff688 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -42,7 +42,6 @@
42#include <linux/ethtool.h> 42#include <linux/ethtool.h>
43#include <linux/mii.h> 43#include <linux/mii.h>
44 44
45#include <pcmcia/version.h>
46#include <pcmcia/cs_types.h> 45#include <pcmcia/cs_types.h>
47#include <pcmcia/cs.h> 46#include <pcmcia/cs.h>
48#include <pcmcia/cistpl.h> 47#include <pcmcia/cistpl.h>
@@ -370,10 +369,6 @@ static dev_link_t *smc91c92_attach(void)
370 link->next = dev_list; 369 link->next = dev_list;
371 dev_list = link; 370 dev_list = link;
372 client_reg.dev_info = &dev_info; 371 client_reg.dev_info = &dev_info;
373 client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
374 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
375 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
376 client_reg.event_handler = &smc91c92_event;
377 client_reg.Version = 0x0210; 372 client_reg.Version = 0x0210;
378 client_reg.event_callback_args.client_data = link; 373 client_reg.event_callback_args.client_data = link;
379 ret = pcmcia_register_client(&link->handle, &client_reg); 374 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2365,6 +2360,7 @@ static struct pcmcia_driver smc91c92_cs_driver = {
2365 .name = "smc91c92_cs", 2360 .name = "smc91c92_cs",
2366 }, 2361 },
2367 .attach = smc91c92_attach, 2362 .attach = smc91c92_attach,
2363 .event = smc91c92_event,
2368 .detach = smc91c92_detach, 2364 .detach = smc91c92_detach,
2369 .id_table = smc91c92_ids, 2365 .id_table = smc91c92_ids,
2370}; 2366};
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 0cd225e1595c..9f33bad174e9 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -81,7 +81,6 @@
81#include <linux/ioport.h> 81#include <linux/ioport.h>
82#include <linux/bitops.h> 82#include <linux/bitops.h>
83 83
84#include <pcmcia/version.h>
85#include <pcmcia/cs_types.h> 84#include <pcmcia/cs_types.h>
86#include <pcmcia/cs.h> 85#include <pcmcia/cs.h>
87#include <pcmcia/cistpl.h> 86#include <pcmcia/cistpl.h>
@@ -619,11 +618,6 @@ xirc2ps_attach(void)
619 link->next = dev_list; 618 link->next = dev_list;
620 dev_list = link; 619 dev_list = link;
621 client_reg.dev_info = &dev_info; 620 client_reg.dev_info = &dev_info;
622 client_reg.EventMask =
623 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
624 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
625 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
626 client_reg.event_handler = &xirc2ps_event;
627 client_reg.Version = 0x0210; 621 client_reg.Version = 0x0210;
628 client_reg.event_callback_args.client_data = link; 622 client_reg.event_callback_args.client_data = link;
629 if ((err = pcmcia_register_client(&link->handle, &client_reg))) { 623 if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
@@ -2016,6 +2010,7 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
2016 .name = "xirc2ps_cs", 2010 .name = "xirc2ps_cs",
2017 }, 2011 },
2018 .attach = xirc2ps_attach, 2012 .attach = xirc2ps_attach,
2013 .event = xirc2ps_event,
2019 .detach = xirc2ps_detach, 2014 .detach = xirc2ps_detach,
2020 .id_table = xirc2ps_ids, 2015 .id_table = xirc2ps_ids,
2021}; 2016};
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 3dbb1cb09ed8..5cacc7ad9e79 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3259,7 +3259,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
3259} 3259}
3260 3260
3261#ifdef CONFIG_PM 3261#ifdef CONFIG_PM
3262static int skge_suspend(struct pci_dev *pdev, u32 state) 3262static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
3263{ 3263{
3264 struct skge_hw *hw = pci_get_drvdata(pdev); 3264 struct skge_hw *hw = pci_get_drvdata(pdev);
3265 int i, wol = 0; 3265 int i, wol = 0;
@@ -3279,7 +3279,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state)
3279 } 3279 }
3280 3280
3281 pci_save_state(pdev); 3281 pci_save_state(pdev);
3282 pci_enable_wake(pdev, state, wol); 3282 pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
3283 pci_disable_device(pdev); 3283 pci_disable_device(pdev);
3284 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 3284 pci_set_power_state(pdev, pci_choose_state(pdev, state));
3285 3285
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 1f5655655c40..2608e7a3d214 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -3079,7 +3079,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
3079 gp->phy_mii.dev = dev; 3079 gp->phy_mii.dev = dev;
3080 gp->phy_mii.mdio_read = _phy_read; 3080 gp->phy_mii.mdio_read = _phy_read;
3081 gp->phy_mii.mdio_write = _phy_write; 3081 gp->phy_mii.mdio_write = _phy_write;
3082 3082#ifdef CONFIG_PPC_PMAC
3083 gp->phy_mii.platform_data = gp->of_node;
3084#endif
3083 /* By default, we start with autoneg */ 3085 /* By default, we start with autoneg */
3084 gp->want_autoneg = 1; 3086 gp->want_autoneg = 1;
3085 3087
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 0fca414d3657..d3ddb41d6e5c 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -32,6 +32,10 @@
32#include <linux/ethtool.h> 32#include <linux/ethtool.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34 34
35#ifdef CONFIG_PPC_PMAC
36#include <asm/prom.h>
37#endif
38
35#include "sungem_phy.h" 39#include "sungem_phy.h"
36 40
37/* Link modes of the BCM5400 PHY */ 41/* Link modes of the BCM5400 PHY */
@@ -281,10 +285,12 @@ static int bcm5411_suspend(struct mii_phy* phy)
281static int bcm5421_init(struct mii_phy* phy) 285static int bcm5421_init(struct mii_phy* phy)
282{ 286{
283 u16 data; 287 u16 data;
284 int rev; 288 unsigned int id;
285 289
286 rev = phy_read(phy, MII_PHYSID2) & 0x000f; 290 id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
287 if (rev == 0) { 291
292 /* Revision 0 of 5421 needs some fixups */
293 if (id == 0x002060e0) {
288 /* This is borrowed from MacOS 294 /* This is borrowed from MacOS
289 */ 295 */
290 phy_write(phy, 0x18, 0x1007); 296 phy_write(phy, 0x18, 0x1007);
@@ -297,21 +303,28 @@ static int bcm5421_init(struct mii_phy* phy)
297 data = phy_read(phy, 0x15); 303 data = phy_read(phy, 0x15);
298 phy_write(phy, 0x15, data | 0x0200); 304 phy_write(phy, 0x15, data | 0x0200);
299 } 305 }
300#if 0
301 /* This has to be verified before I enable it */
302 /* Enable automatic low-power */
303 phy_write(phy, 0x1c, 0x9002);
304 phy_write(phy, 0x1c, 0xa821);
305 phy_write(phy, 0x1c, 0x941d);
306#endif
307 return 0;
308}
309 306
310static int bcm5421k2_init(struct mii_phy* phy) 307 /* Pick up some init code from OF for K2 version */
311{ 308 if ((id & 0xfffffff0) == 0x002062e0) {
312 /* Init code borrowed from OF */ 309 phy_write(phy, 4, 0x01e1);
313 phy_write(phy, 4, 0x01e1); 310 phy_write(phy, 9, 0x0300);
314 phy_write(phy, 9, 0x0300); 311 }
312
313 /* Check if we can enable automatic low power */
314#ifdef CONFIG_PPC_PMAC
315 if (phy->platform_data) {
316 struct device_node *np = of_get_parent(phy->platform_data);
317 int can_low_power = 1;
318 if (np == NULL || get_property(np, "no-autolowpower", NULL))
319 can_low_power = 0;
320 if (can_low_power) {
321 /* Enable automatic low-power */
322 phy_write(phy, 0x1c, 0x9002);
323 phy_write(phy, 0x1c, 0xa821);
324 phy_write(phy, 0x1c, 0x941d);
325 }
326 }
327#endif /* CONFIG_PPC_PMAC */
315 328
316 return 0; 329 return 0;
317} 330}
@@ -762,7 +775,7 @@ static struct mii_phy_def bcm5421_phy_def = {
762 775
763/* Broadcom BCM 5421 built-in K2 */ 776/* Broadcom BCM 5421 built-in K2 */
764static struct mii_phy_ops bcm5421k2_phy_ops = { 777static struct mii_phy_ops bcm5421k2_phy_ops = {
765 .init = bcm5421k2_init, 778 .init = bcm5421_init,
766 .suspend = bcm5411_suspend, 779 .suspend = bcm5411_suspend,
767 .setup_aneg = bcm54xx_setup_aneg, 780 .setup_aneg = bcm54xx_setup_aneg,
768 .setup_forced = bcm54xx_setup_forced, 781 .setup_forced = bcm54xx_setup_forced,
@@ -779,6 +792,25 @@ static struct mii_phy_def bcm5421k2_phy_def = {
779 .ops = &bcm5421k2_phy_ops 792 .ops = &bcm5421k2_phy_ops
780}; 793};
781 794
795/* Broadcom BCM 5462 built-in Vesta */
796static struct mii_phy_ops bcm5462V_phy_ops = {
797 .init = bcm5421_init,
798 .suspend = bcm5411_suspend,
799 .setup_aneg = bcm54xx_setup_aneg,
800 .setup_forced = bcm54xx_setup_forced,
801 .poll_link = genmii_poll_link,
802 .read_link = bcm54xx_read_link,
803};
804
805static struct mii_phy_def bcm5462V_phy_def = {
806 .phy_id = 0x002060d0,
807 .phy_id_mask = 0xfffffff0,
808 .name = "BCM5462-Vesta",
809 .features = MII_GBIT_FEATURES,
810 .magic_aneg = 1,
811 .ops = &bcm5462V_phy_ops
812};
813
782/* Marvell 88E1101 (Apple seem to deal with 2 different revs, 814/* Marvell 88E1101 (Apple seem to deal with 2 different revs,
783 * I masked out the 8 last bits to get both, but some specs 815 * I masked out the 8 last bits to get both, but some specs
784 * would be useful here) --BenH. 816 * would be useful here) --BenH.
@@ -824,6 +856,7 @@ static struct mii_phy_def* mii_phy_table[] = {
824 &bcm5411_phy_def, 856 &bcm5411_phy_def,
825 &bcm5421_phy_def, 857 &bcm5421_phy_def,
826 &bcm5421k2_phy_def, 858 &bcm5421k2_phy_def,
859 &bcm5462V_phy_def,
827 &marvell_phy_def, 860 &marvell_phy_def,
828 &genmii_phy_def, 861 &genmii_phy_def,
829 NULL 862 NULL
diff --git a/drivers/net/sungem_phy.h b/drivers/net/sungem_phy.h
index 822cb58174ea..430544496c52 100644
--- a/drivers/net/sungem_phy.h
+++ b/drivers/net/sungem_phy.h
@@ -43,9 +43,10 @@ struct mii_phy
43 int pause; 43 int pause;
44 44
45 /* Provided by host chip */ 45 /* Provided by host chip */
46 struct net_device* dev; 46 struct net_device *dev;
47 int (*mdio_read) (struct net_device *dev, int mii_id, int reg); 47 int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
48 void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val); 48 void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
49 void *platform_data;
49}; 50};
50 51
51/* Pass in a struct mii_phy with dev, mdio_read and mdio_write 52/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 0b5ca2537963..ecfa6f8805ce 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1906,9 +1906,9 @@ typhoon_sleep(struct typhoon *tp, pci_power_t state, u16 events)
1906 */ 1906 */
1907 netif_carrier_off(tp->dev); 1907 netif_carrier_off(tp->dev);
1908 1908
1909 pci_enable_wake(tp->pdev, pci_choose_state(pdev, state), 1); 1909 pci_enable_wake(tp->pdev, state, 1);
1910 pci_disable_device(pdev); 1910 pci_disable_device(pdev);
1911 return pci_set_power_state(pdev, pci_choose_state(pdev, state)); 1911 return pci_set_power_state(pdev, state);
1912} 1912}
1913 1913
1914static int 1914static int
@@ -2274,7 +2274,7 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
2274 goto need_resume; 2274 goto need_resume;
2275 } 2275 }
2276 2276
2277 if(typhoon_sleep(tp, state, tp->wol_events) < 0) { 2277 if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) {
2278 printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name); 2278 printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
2279 goto need_resume; 2279 goto need_resume;
2280 } 2280 }
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index f10a9523034a..bf25584d68d3 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -33,7 +33,6 @@
33#include <linux/timer.h> 33#include <linux/timer.h>
34#include <linux/netdevice.h> 34#include <linux/netdevice.h>
35 35
36#include <pcmcia/version.h>
37#include <pcmcia/cs_types.h> 36#include <pcmcia/cs_types.h>
38#include <pcmcia/cs.h> 37#include <pcmcia/cs.h>
39#include <pcmcia/cistpl.h> 38#include <pcmcia/cistpl.h>
@@ -210,11 +209,6 @@ static dev_link_t *airo_attach(void)
210 link->next = dev_list; 209 link->next = dev_list;
211 dev_list = link; 210 dev_list = link;
212 client_reg.dev_info = &dev_info; 211 client_reg.dev_info = &dev_info;
213 client_reg.EventMask =
214 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
215 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
216 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
217 client_reg.event_handler = &airo_event;
218 client_reg.Version = 0x0210; 212 client_reg.Version = 0x0210;
219 client_reg.event_callback_args.client_data = link; 213 client_reg.event_callback_args.client_data = link;
220 ret = pcmcia_register_client(&link->handle, &client_reg); 214 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -574,6 +568,7 @@ static struct pcmcia_driver airo_driver = {
574 .name = "airo_cs", 568 .name = "airo_cs",
575 }, 569 },
576 .attach = airo_attach, 570 .attach = airo_attach,
571 .event = airo_event,
577 .detach = airo_detach, 572 .detach = airo_detach,
578 .id_table = airo_ids, 573 .id_table = airo_ids,
579}; 574};
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 86379d4998ac..ff031a3985b3 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -43,7 +43,6 @@
43#include <linux/moduleparam.h> 43#include <linux/moduleparam.h>
44#include <linux/device.h> 44#include <linux/device.h>
45 45
46#include <pcmcia/version.h>
47#include <pcmcia/cs_types.h> 46#include <pcmcia/cs_types.h>
48#include <pcmcia/cs.h> 47#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h> 48#include <pcmcia/cistpl.h>
@@ -218,11 +217,6 @@ static dev_link_t *atmel_attach(void)
218 link->next = dev_list; 217 link->next = dev_list;
219 dev_list = link; 218 dev_list = link;
220 client_reg.dev_info = &dev_info; 219 client_reg.dev_info = &dev_info;
221 client_reg.EventMask =
222 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
223 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
224 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
225 client_reg.event_handler = &atmel_event;
226 client_reg.Version = 0x0210; 220 client_reg.Version = 0x0210;
227 client_reg.event_callback_args.client_data = link; 221 client_reg.event_callback_args.client_data = link;
228 ret = pcmcia_register_client(&link->handle, &client_reg); 222 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -668,12 +662,13 @@ static struct pcmcia_device_id atmel_ids[] = {
668MODULE_DEVICE_TABLE(pcmcia, atmel_ids); 662MODULE_DEVICE_TABLE(pcmcia, atmel_ids);
669 663
670static struct pcmcia_driver atmel_driver = { 664static struct pcmcia_driver atmel_driver = {
671 .owner = THIS_MODULE, 665 .owner = THIS_MODULE,
672 .drv = { 666 .drv = {
673 .name = "atmel_cs", 667 .name = "atmel_cs",
674 }, 668 },
675 .attach = atmel_attach, 669 .attach = atmel_attach,
676 .detach = atmel_detach, 670 .event = atmel_event,
671 .detach = atmel_detach,
677 .id_table = atmel_ids, 672 .id_table = atmel_ids,
678}; 673};
679 674
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index e12bd75b2694..5f507c49907b 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -62,7 +62,6 @@
62#endif /* WIRELESS_EXT > 12 */ 62#endif /* WIRELESS_EXT > 12 */
63#endif 63#endif
64 64
65#include <pcmcia/version.h>
66#include <pcmcia/cs_types.h> 65#include <pcmcia/cs_types.h>
67#include <pcmcia/cs.h> 66#include <pcmcia/cs.h>
68#include <pcmcia/cistpl.h> 67#include <pcmcia/cistpl.h>
@@ -491,11 +490,6 @@ static dev_link_t *netwave_attach(void)
491 link->next = dev_list; 490 link->next = dev_list;
492 dev_list = link; 491 dev_list = link;
493 client_reg.dev_info = &dev_info; 492 client_reg.dev_info = &dev_info;
494 client_reg.EventMask =
495 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
496 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
497 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
498 client_reg.event_handler = &netwave_event;
499 client_reg.Version = 0x0210; 493 client_reg.Version = 0x0210;
500 client_reg.event_callback_args.client_data = link; 494 client_reg.event_callback_args.client_data = link;
501 ret = pcmcia_register_client(&link->handle, &client_reg); 495 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1680,6 +1674,7 @@ static struct pcmcia_driver netwave_driver = {
1680 .name = "netwave_cs", 1674 .name = "netwave_cs",
1681 }, 1675 },
1682 .attach = netwave_attach, 1676 .attach = netwave_attach,
1677 .event = netwave_event,
1683 .detach = netwave_detach, 1678 .detach = netwave_detach,
1684 .id_table = netwave_ids, 1679 .id_table = netwave_ids,
1685}; 1680};
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 597c4586d049..368d2f962f67 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -31,7 +31,6 @@
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/wireless.h> 32#include <linux/wireless.h>
33 33
34#include <pcmcia/version.h>
35#include <pcmcia/cs_types.h> 34#include <pcmcia/cs_types.h>
36#include <pcmcia/cs.h> 35#include <pcmcia/cs.h>
37#include <pcmcia/cistpl.h> 36#include <pcmcia/cistpl.h>
@@ -186,11 +185,6 @@ orinoco_cs_attach(void)
186 dev_list = link; 185 dev_list = link;
187 186
188 client_reg.dev_info = &dev_info; 187 client_reg.dev_info = &dev_info;
189 client_reg.EventMask =
190 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
191 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
192 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
193 client_reg.event_handler = &orinoco_cs_event;
194 client_reg.Version = 0x0210; /* FIXME: what does this mean? */ 188 client_reg.Version = 0x0210; /* FIXME: what does this mean? */
195 client_reg.event_callback_args.client_data = link; 189 client_reg.event_callback_args.client_data = link;
196 190
@@ -664,6 +658,7 @@ static struct pcmcia_driver orinoco_driver = {
664 .name = DRIVER_NAME, 658 .name = DRIVER_NAME,
665 }, 659 },
666 .attach = orinoco_cs_attach, 660 .attach = orinoco_cs_attach,
661 .event = orinoco_cs_event,
667 .detach = orinoco_cs_detach, 662 .detach = orinoco_cs_detach,
668 .id_table = orinoco_cs_ids, 663 .id_table = orinoco_cs_ids,
669}; 664};
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 31652af52eac..0e0ba614259a 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -46,7 +46,6 @@
46#include <linux/skbuff.h> 46#include <linux/skbuff.h>
47#include <linux/ethtool.h> 47#include <linux/ethtool.h>
48 48
49#include <pcmcia/version.h>
50#include <pcmcia/cs_types.h> 49#include <pcmcia/cs_types.h>
51#include <pcmcia/cs.h> 50#include <pcmcia/cs.h>
52#include <pcmcia/cistpl.h> 51#include <pcmcia/cistpl.h>
@@ -393,11 +392,6 @@ static dev_link_t *ray_attach(void)
393 link->next = dev_list; 392 link->next = dev_list;
394 dev_list = link; 393 dev_list = link;
395 client_reg.dev_info = &dev_info; 394 client_reg.dev_info = &dev_info;
396 client_reg.EventMask =
397 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
398 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
399 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
400 client_reg.event_handler = &ray_event;
401 client_reg.Version = 0x0210; 395 client_reg.Version = 0x0210;
402 client_reg.event_callback_args.client_data = link; 396 client_reg.event_callback_args.client_data = link;
403 397
@@ -2916,6 +2910,7 @@ static struct pcmcia_driver ray_driver = {
2916 .name = "ray_cs", 2910 .name = "ray_cs",
2917 }, 2911 },
2918 .attach = ray_attach, 2912 .attach = ray_attach,
2913 .event = ray_event,
2919 .detach = ray_detach, 2914 .detach = ray_detach,
2920 .id_table = ray_ids, 2915 .id_table = ray_ids,
2921}; 2916};
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 89532fd92941..f6130a53b796 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4684,12 +4684,6 @@ wavelan_attach(void)
4684 4684
4685 /* Register with Card Services */ 4685 /* Register with Card Services */
4686 client_reg.dev_info = &dev_info; 4686 client_reg.dev_info = &dev_info;
4687 client_reg.EventMask =
4688 CS_EVENT_REGISTRATION_COMPLETE |
4689 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
4690 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
4691 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
4692 client_reg.event_handler = &wavelan_event;
4693 client_reg.Version = 0x0210; 4687 client_reg.Version = 0x0210;
4694 client_reg.event_callback_args.client_data = link; 4688 client_reg.event_callback_args.client_data = link;
4695 4689
@@ -4904,6 +4898,7 @@ static struct pcmcia_driver wavelan_driver = {
4904 .name = "wavelan_cs", 4898 .name = "wavelan_cs",
4905 }, 4899 },
4906 .attach = wavelan_attach, 4900 .attach = wavelan_attach,
4901 .event = wavelan_event,
4907 .detach = wavelan_detach, 4902 .detach = wavelan_detach,
4908 .id_table = wavelan_ids, 4903 .id_table = wavelan_ids,
4909}; 4904};
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index ea2ef8dddb92..677ff71883cb 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -452,7 +452,6 @@
452#include <pcmcia/cistpl.h> 452#include <pcmcia/cistpl.h>
453#include <pcmcia/cisreg.h> 453#include <pcmcia/cisreg.h>
454#include <pcmcia/ds.h> 454#include <pcmcia/ds.h>
455#include <pcmcia/version.h>
456 455
457/* Wavelan declarations */ 456/* Wavelan declarations */
458#include "i82593.h" /* Definitions for the Intel chip */ 457#include "i82593.h" /* Definitions for the Intel chip */
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index e3a900482d92..dd902126d018 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -49,7 +49,6 @@
49 49
50#include <net/iw_handler.h> 50#include <net/iw_handler.h>
51 51
52#include <pcmcia/version.h>
53#include <pcmcia/cs_types.h> 52#include <pcmcia/cs_types.h>
54#include <pcmcia/cs.h> 53#include <pcmcia/cs.h>
55#include <pcmcia/cistpl.h> 54#include <pcmcia/cistpl.h>
@@ -2005,13 +2004,6 @@ static dev_link_t *wl3501_attach(void)
2005 link->next = wl3501_dev_list; 2004 link->next = wl3501_dev_list;
2006 wl3501_dev_list = link; 2005 wl3501_dev_list = link;
2007 client_reg.dev_info = &wl3501_dev_info; 2006 client_reg.dev_info = &wl3501_dev_info;
2008 client_reg.EventMask = CS_EVENT_CARD_INSERTION |
2009 CS_EVENT_RESET_PHYSICAL |
2010 CS_EVENT_CARD_RESET |
2011 CS_EVENT_CARD_REMOVAL |
2012 CS_EVENT_PM_SUSPEND |
2013 CS_EVENT_PM_RESUME;
2014 client_reg.event_handler = wl3501_event;
2015 client_reg.Version = 0x0210; 2007 client_reg.Version = 0x0210;
2016 client_reg.event_callback_args.client_data = link; 2008 client_reg.event_callback_args.client_data = link;
2017 ret = pcmcia_register_client(&link->handle, &client_reg); 2009 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2246,12 +2238,13 @@ static struct pcmcia_device_id wl3501_ids[] = {
2246MODULE_DEVICE_TABLE(pcmcia, wl3501_ids); 2238MODULE_DEVICE_TABLE(pcmcia, wl3501_ids);
2247 2239
2248static struct pcmcia_driver wl3501_driver = { 2240static struct pcmcia_driver wl3501_driver = {
2249 .owner = THIS_MODULE, 2241 .owner = THIS_MODULE,
2250 .drv = { 2242 .drv = {
2251 .name = "wl3501_cs", 2243 .name = "wl3501_cs",
2252 }, 2244 },
2253 .attach = wl3501_attach, 2245 .attach = wl3501_attach,
2254 .detach = wl3501_detach, 2246 .event = wl3501_event,
2247 .detach = wl3501_detach,
2255 .id_table = wl3501_ids, 2248 .id_table = wl3501_ids,
2256}; 2249};
2257 2250
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index ff45662c4f7c..24e6aacddb74 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -48,7 +48,6 @@
48#include <linux/parport.h> 48#include <linux/parport.h>
49#include <linux/parport_pc.h> 49#include <linux/parport_pc.h>
50 50
51#include <pcmcia/version.h>
52#include <pcmcia/cs_types.h> 51#include <pcmcia/cs_types.h>
53#include <pcmcia/cs.h> 52#include <pcmcia/cs.h>
54#include <pcmcia/cistpl.h> 53#include <pcmcia/cistpl.h>
@@ -133,11 +132,6 @@ static dev_link_t *parport_attach(void)
133 link->next = dev_list; 132 link->next = dev_list;
134 dev_list = link; 133 dev_list = link;
135 client_reg.dev_info = &dev_info; 134 client_reg.dev_info = &dev_info;
136 client_reg.EventMask =
137 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
138 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
139 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
140 client_reg.event_handler = &parport_event;
141 client_reg.Version = 0x0210; 135 client_reg.Version = 0x0210;
142 client_reg.event_callback_args.client_data = link; 136 client_reg.event_callback_args.client_data = link;
143 ret = pcmcia_register_client(&link->handle, &client_reg); 137 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -386,6 +380,7 @@ static struct pcmcia_driver parport_cs_driver = {
386 .name = "parport_cs", 380 .name = "parport_cs",
387 }, 381 },
388 .attach = parport_attach, 382 .attach = parport_attach,
383 .event = parport_event,
389 .detach = parport_detach, 384 .detach = parport_detach,
390 .id_table = parport_ids, 385 .id_table = parport_ids,
391 386
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 4db69982876e..393e0cee91a9 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -325,7 +325,7 @@ int pcie_port_device_register(struct pci_dev *dev)
325static int suspend_iter(struct device *dev, void *data) 325static int suspend_iter(struct device *dev, void *data)
326{ 326{
327 struct pcie_port_service_driver *service_driver; 327 struct pcie_port_service_driver *service_driver;
328 u32 state = (u32)data; 328 pm_message_t state = * (pm_message_t *) data;
329 329
330 if ((dev->bus == &pcie_port_bus_type) && 330 if ((dev->bus == &pcie_port_bus_type) &&
331 (dev->driver)) { 331 (dev->driver)) {
@@ -336,9 +336,9 @@ static int suspend_iter(struct device *dev, void *data)
336 return 0; 336 return 0;
337} 337}
338 338
339int pcie_port_device_suspend(struct pci_dev *dev, u32 state) 339int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
340{ 340{
341 device_for_each_child(&dev->dev, (void *)state, suspend_iter); 341 device_for_each_child(&dev->dev, &state, suspend_iter);
342 return 0; 342 return 0;
343} 343}
344 344
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 52ea34594363..6485f75d2fb3 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -1,8 +1,5 @@
1# 1#
2# PCMCIA bus subsystem configuration 2# PCCARD (PCMCIA/CardBus) bus subsystem configuration
3#
4# Right now the non-CardBus choices are not supported
5# by the integrated kernel driver.
6# 3#
7 4
8menu "PCCARD (PCMCIA/CardBus) support" 5menu "PCCARD (PCMCIA/CardBus) support"
@@ -32,7 +29,7 @@ config PCMCIA_DEBUG
32 29
33 The kernel command line options are: 30 The kernel command line options are:
34 pcmcia_core.pc_debug=N 31 pcmcia_core.pc_debug=N
35 ds.pc_debug=N 32 pcmcia.pc_debug=N
36 sa11xx_core.pc_debug=N 33 sa11xx_core.pc_debug=N
37 34
38 The module option is called pc_debug=N 35 The module option is called pc_debug=N
@@ -73,7 +70,7 @@ config PCMCIA_LOAD_CIS
73 If unsure, say Y. 70 If unsure, say Y.
74 71
75config PCMCIA_IOCTL 72config PCMCIA_IOCTL
76 bool 73 bool "PCMCIA control ioctl (obsolete)"
77 depends on PCMCIA 74 depends on PCMCIA
78 default y 75 default y
79 help 76 help
@@ -81,9 +78,8 @@ config PCMCIA_IOCTL
81 subsystem will be built. It is needed by cardmgr and cardctl 78 subsystem will be built. It is needed by cardmgr and cardctl
82 (pcmcia-cs) to function properly. 79 (pcmcia-cs) to function properly.
83 80
84 If you do not use the new pcmciautils package, and have a 81 You should use the new pcmciautils package instead (see
85 yenta, Cirrus PD6729, i82092, i82365 or tcic compatible bridge, 82 <file:Documentation/Changes> for location and details).
86 you need to say Y here to be able to use 16-bit PCMCIA cards.
87 83
88 If unsure, say Y. 84 If unsure, say Y.
89 85
@@ -106,7 +102,8 @@ comment "PC-card bridges"
106 102
107config YENTA 103config YENTA
108 tristate "CardBus yenta-compatible bridge support" 104 tristate "CardBus yenta-compatible bridge support"
109 depends on CARDBUS 105 depends on PCI
106 select CARDBUS if !EMBEDDED
110 select PCCARD_NONSTATIC 107 select PCCARD_NONSTATIC
111 ---help--- 108 ---help---
112 This option enables support for CardBus host bridges. Virtually 109 This option enables support for CardBus host bridges. Virtually
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index 417bc1500bad..d5122b1ea94b 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -22,7 +22,6 @@
22#define __ASM_AU1000_PCMCIA_H 22#define __ASM_AU1000_PCMCIA_H
23 23
24/* include the world */ 24/* include the world */
25#include <pcmcia/version.h>
26#include <pcmcia/cs_types.h> 25#include <pcmcia/cs_types.h>
27#include <pcmcia/cs.h> 26#include <pcmcia/cs.h>
28#include <pcmcia/ss.h> 27#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index df19ce1ea4f3..d414a3bb50b9 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -33,7 +33,6 @@
33#include <linux/version.h> 33#include <linux/version.h>
34#include <linux/types.h> 34#include <linux/types.h>
35 35
36#include <pcmcia/version.h>
37#include <pcmcia/cs_types.h> 36#include <pcmcia/cs_types.h>
38#include <pcmcia/cs.h> 37#include <pcmcia/cs.h>
39#include <pcmcia/ss.h> 38#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 1dfc77653660..f113b69d699b 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -38,7 +38,6 @@
38#include <linux/version.h> 38#include <linux/version.h>
39#include <linux/types.h> 39#include <linux/types.h>
40 40
41#include <pcmcia/version.h>
42#include <pcmcia/cs_types.h> 41#include <pcmcia/cs_types.h>
43#include <pcmcia/cs.h> 42#include <pcmcia/cs.h>
44#include <pcmcia/ss.h> 43#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 3ccb5247ec50..1d755e20880c 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -31,7 +31,6 @@
31#include <asm/io.h> 31#include <asm/io.h>
32 32
33#define IN_CARD_SERVICES 33#define IN_CARD_SERVICES
34#include <pcmcia/version.h>
35#include <pcmcia/cs_types.h> 34#include <pcmcia/cs_types.h>
36#include <pcmcia/ss.h> 35#include <pcmcia/ss.h>
37#include <pcmcia/cs.h> 36#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index e82859d3227a..e39178fc59d0 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -33,7 +33,6 @@
33#include <asm/irq.h> 33#include <asm/irq.h>
34 34
35#define IN_CARD_SERVICES 35#define IN_CARD_SERVICES
36#include <pcmcia/version.h>
37#include <pcmcia/cs_types.h> 36#include <pcmcia/cs_types.h>
38#include <pcmcia/ss.h> 37#include <pcmcia/ss.h>
39#include <pcmcia/cs.h> 38#include <pcmcia/cs.h>
@@ -216,6 +215,13 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
216 list_add_tail(&socket->socket_list, &pcmcia_socket_list); 215 list_add_tail(&socket->socket_list, &pcmcia_socket_list);
217 up_write(&pcmcia_socket_list_rwsem); 216 up_write(&pcmcia_socket_list_rwsem);
218 217
218#ifndef CONFIG_CARDBUS
219 /*
220 * If we do not support Cardbus, ensure that
221 * the Cardbus socket capability is disabled.
222 */
223 socket->features &= ~SS_CAP_CARDBUS;
224#endif
219 225
220 /* set proper values in socket->dev */ 226 /* set proper values in socket->dev */
221 socket->dev.class_data = socket; 227 socket->dev.class_data = socket;
@@ -449,11 +455,11 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
449 } 455 }
450 456
451 if (status & SS_CARDBUS) { 457 if (status & SS_CARDBUS) {
458 if (!(skt->features & SS_CAP_CARDBUS)) {
459 cs_err(skt, "cardbus cards are not supported.\n");
460 return CS_BAD_TYPE;
461 }
452 skt->state |= SOCKET_CARDBUS; 462 skt->state |= SOCKET_CARDBUS;
453#ifndef CONFIG_CARDBUS
454 cs_err(skt, "cardbus cards are not supported.\n");
455 return CS_BAD_TYPE;
456#endif
457 } 463 }
458 464
459 /* 465 /*
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 0b4c18edfa49..6bbfbd0e02a5 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -99,23 +99,11 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
99 } 99 }
100} 100}
101 101
102#define CHECK_HANDLE(h) \
103 (((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC))
104
105#define CHECK_SOCKET(s) \ 102#define CHECK_SOCKET(s) \
106 (((s) >= sockets) || (socket_table[s]->ops == NULL)) 103 (((s) >= sockets) || (socket_table[s]->ops == NULL))
107 104
108#define SOCKET(h) (h->Socket) 105#define SOCKET(h) (h->socket)
109#define CONFIG(h) (&SOCKET(h)->config[(h)->Function]) 106#define CONFIG(h) (&SOCKET(h)->config[(h)->func])
110
111#define CHECK_REGION(r) \
112 (((r) == NULL) || ((r)->region_magic != REGION_MAGIC))
113
114#define CHECK_ERASEQ(q) \
115 (((q) == NULL) || ((q)->eraseq_magic != ERASEQ_MAGIC))
116
117#define EVENT(h, e, p) \
118 ((h)->event_handler((e), (p), &(h)->event_callback_args))
119 107
120/* In cardbus.c */ 108/* In cardbus.c */
121int cb_alloc(struct pcmcia_socket *s); 109int cb_alloc(struct pcmcia_socket *s);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index d5afd557fe37..3e3c6f12bbe6 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -158,17 +158,15 @@ static const lookup_t service_table[] = {
158}; 158};
159 159
160 160
161static int pcmcia_report_error(client_handle_t handle, error_info_t *err) 161static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
162{ 162{
163 int i; 163 int i;
164 char *serv; 164 char *serv;
165 165
166 if (CHECK_HANDLE(handle)) 166 if (!p_dev)
167 printk(KERN_NOTICE); 167 printk(KERN_NOTICE);
168 else { 168 else
169 struct pcmcia_device *p_dev = handle_to_pdev(handle);
170 printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id); 169 printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id);
171 }
172 170
173 for (i = 0; i < ARRAY_SIZE(service_table); i++) 171 for (i = 0; i < ARRAY_SIZE(service_table); i++)
174 if (service_table[i].key == err->func) 172 if (service_table[i].key == err->func)
@@ -193,10 +191,10 @@ static int pcmcia_report_error(client_handle_t handle, error_info_t *err)
193 191
194/*======================================================================*/ 192/*======================================================================*/
195 193
196void cs_error(client_handle_t handle, int func, int ret) 194void cs_error(struct pcmcia_device *p_dev, int func, int ret)
197{ 195{
198 error_info_t err = { func, ret }; 196 error_info_t err = { func, ret };
199 pcmcia_report_error(handle, &err); 197 pcmcia_report_error(p_dev, &err);
200} 198}
201EXPORT_SYMBOL(cs_error); 199EXPORT_SYMBOL(cs_error);
202 200
@@ -207,6 +205,10 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
207 unsigned int i; 205 unsigned int i;
208 u32 hash; 206 u32 hash;
209 207
208 if (!p_drv->attach || !p_drv->event || !p_drv->detach)
209 printk(KERN_DEBUG "pcmcia: %s does misses a callback function",
210 p_drv->drv.name);
211
210 while (did && did->match_flags) { 212 while (did && did->match_flags) {
211 for (i=0; i<4; i++) { 213 for (i=0; i<4; i++) {
212 if (!did->prod_id[i]) 214 if (!did->prod_id[i])
@@ -376,7 +378,7 @@ static int pcmcia_device_probe(struct device * dev)
376 378
377 if (p_drv->attach) { 379 if (p_drv->attach) {
378 p_dev->instance = p_drv->attach(); 380 p_dev->instance = p_drv->attach();
379 if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) { 381 if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) {
380 printk(KERN_NOTICE "ds: unable to create instance " 382 printk(KERN_NOTICE "ds: unable to create instance "
381 "of '%s'!\n", p_drv->drv.name); 383 "of '%s'!\n", p_drv->drv.name);
382 ret = -EINVAL; 384 ret = -EINVAL;
@@ -516,10 +518,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
516 sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); 518 sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
517 519
518 /* compat */ 520 /* compat */
519 p_dev->client.client_magic = CLIENT_MAGIC; 521 p_dev->state = CLIENT_UNBOUND;
520 p_dev->client.Socket = s;
521 p_dev->client.Function = function;
522 p_dev->client.state = CLIENT_UNBOUND;
523 522
524 /* Add to the list in pcmcia_bus_socket */ 523 /* Add to the list in pcmcia_bus_socket */
525 spin_lock_irqsave(&pcmcia_dev_list_lock, flags); 524 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -573,8 +572,6 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
573 else 572 else
574 no_funcs = 1; 573 no_funcs = 1;
575 574
576 /* this doesn't handle multifunction devices on one pcmcia function
577 * yet. */
578 for (i=0; i < no_funcs; i++) 575 for (i=0; i < no_funcs; i++)
579 pcmcia_device_add(s, i); 576 pcmcia_device_add(s, i);
580 577
@@ -914,6 +911,7 @@ struct send_event_data {
914static int send_event_callback(struct device *dev, void * _data) 911static int send_event_callback(struct device *dev, void * _data)
915{ 912{
916 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 913 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
914 struct pcmcia_driver *p_drv;
917 struct send_event_data *data = _data; 915 struct send_event_data *data = _data;
918 916
919 /* we get called for all sockets, but may only pass the event 917 /* we get called for all sockets, but may only pass the event
@@ -921,11 +919,16 @@ static int send_event_callback(struct device *dev, void * _data)
921 if (p_dev->socket != data->skt) 919 if (p_dev->socket != data->skt)
922 return 0; 920 return 0;
923 921
924 if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE)) 922 p_drv = to_pcmcia_drv(p_dev->dev.driver);
923 if (!p_drv)
925 return 0; 924 return 0;
926 925
927 if (p_dev->client.EventMask & data->event) 926 if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
928 return EVENT(&p_dev->client, data->event, data->priority); 927 return 0;
928
929 if (p_drv->event)
930 return p_drv->event(data->event, data->priority,
931 &p_dev->event_callback_args);
929 932
930 return 0; 933 return 0;
931} 934}
@@ -987,11 +990,11 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
987 990
988 991
989 992
990int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) 993int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
991{ 994{
992 client_t *client = NULL;
993 struct pcmcia_socket *s = NULL; 995 struct pcmcia_socket *s = NULL;
994 struct pcmcia_device *p_dev = NULL; 996 struct pcmcia_device *p_dev = NULL;
997 struct pcmcia_driver *p_drv = NULL;
995 998
996 /* Look for unbound client with matching dev_info */ 999 /* Look for unbound client with matching dev_info */
997 down_read(&pcmcia_socket_list_rwsem); 1000 down_read(&pcmcia_socket_list_rwsem);
@@ -1006,18 +1009,16 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1006 continue; 1009 continue;
1007 spin_lock_irqsave(&pcmcia_dev_list_lock, flags); 1010 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
1008 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { 1011 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
1009 struct pcmcia_driver *p_drv;
1010 p_dev = pcmcia_get_dev(p_dev); 1012 p_dev = pcmcia_get_dev(p_dev);
1011 if (!p_dev) 1013 if (!p_dev)
1012 continue; 1014 continue;
1013 if (!(p_dev->client.state & CLIENT_UNBOUND) || 1015 if (!(p_dev->state & CLIENT_UNBOUND) ||
1014 (!p_dev->dev.driver)) { 1016 (!p_dev->dev.driver)) {
1015 pcmcia_put_dev(p_dev); 1017 pcmcia_put_dev(p_dev);
1016 continue; 1018 continue;
1017 } 1019 }
1018 p_drv = to_pcmcia_drv(p_dev->dev.driver); 1020 p_drv = to_pcmcia_drv(p_dev->dev.driver);
1019 if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) { 1021 if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
1020 client = &p_dev->client;
1021 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); 1022 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1022 goto found; 1023 goto found;
1023 } 1024 }
@@ -1028,26 +1029,20 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1028 } 1029 }
1029 found: 1030 found:
1030 up_read(&pcmcia_socket_list_rwsem); 1031 up_read(&pcmcia_socket_list_rwsem);
1031 if (!p_dev || !client) 1032 if (!p_dev)
1032 return -ENODEV; 1033 return -ENODEV;
1033 1034
1034 pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */ 1035 pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
1035 1036
1036 *handle = client; 1037 *handle = p_dev;
1037 client->state &= ~CLIENT_UNBOUND; 1038 p_dev->state &= ~CLIENT_UNBOUND;
1038 client->Socket = s; 1039 p_dev->event_callback_args = req->event_callback_args;
1039 client->EventMask = req->EventMask; 1040 p_dev->event_callback_args.client_handle = p_dev;
1040 client->event_handler = req->event_handler;
1041 client->event_callback_args = req->event_callback_args;
1042 client->event_callback_args.client_handle = client;
1043 1041
1044 if (s->state & SOCKET_CARDBUS)
1045 client->state |= CLIENT_CARDBUS;
1046 1042
1047 if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) && 1043 if (!s->functions) {
1048 (client->Function != BIND_FN_ALL)) {
1049 cistpl_longlink_mfc_t mfc; 1044 cistpl_longlink_mfc_t mfc;
1050 if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc) 1045 if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
1051 == CS_SUCCESS) 1046 == CS_SUCCESS)
1052 s->functions = mfc.nfn; 1047 s->functions = mfc.nfn;
1053 else 1048 else
@@ -1060,13 +1055,13 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1060 } 1055 }
1061 1056
1062 ds_dbg(1, "register_client(): client 0x%p, dev %s\n", 1057 ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
1063 client, p_dev->dev.bus_id); 1058 p_dev, p_dev->dev.bus_id);
1064 if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
1065 EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
1066 1059
1067 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { 1060 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
1068 if (client->EventMask & CS_EVENT_CARD_INSERTION) 1061 if (p_drv->event)
1069 EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); 1062 p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
1063 &p_dev->event_callback_args);
1064
1070 } 1065 }
1071 1066
1072 return CS_SUCCESS; 1067 return CS_SUCCESS;
@@ -1099,7 +1094,7 @@ static int unbind_request(struct pcmcia_socket *s)
1099 } 1094 }
1100 p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); 1095 p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
1101 list_del(&p_dev->socket_device_list); 1096 list_del(&p_dev->socket_device_list);
1102 p_dev->client.state |= CLIENT_STALE; 1097 p_dev->state |= CLIENT_STALE;
1103 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); 1098 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1104 1099
1105 device_unregister(&p_dev->dev); 1100 device_unregister(&p_dev->dev);
@@ -1108,31 +1103,25 @@ static int unbind_request(struct pcmcia_socket *s)
1108 return 0; 1103 return 0;
1109} /* unbind_request */ 1104} /* unbind_request */
1110 1105
1111int pcmcia_deregister_client(client_handle_t handle) 1106int pcmcia_deregister_client(struct pcmcia_device *p_dev)
1112{ 1107{
1113 struct pcmcia_socket *s; 1108 struct pcmcia_socket *s;
1114 int i; 1109 int i;
1115 struct pcmcia_device *p_dev = handle_to_pdev(handle);
1116
1117 if (CHECK_HANDLE(handle))
1118 return CS_BAD_HANDLE;
1119 1110
1120 s = SOCKET(handle); 1111 s = p_dev->socket;
1121 ds_dbg(1, "deregister_client(%p)\n", handle); 1112 ds_dbg(1, "deregister_client(%p)\n", p_dev);
1122 1113
1123 if (handle->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) 1114 if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
1124 goto warn_out; 1115 goto warn_out;
1125 for (i = 0; i < MAX_WIN; i++) 1116 for (i = 0; i < MAX_WIN; i++)
1126 if (handle->state & CLIENT_WIN_REQ(i)) 1117 if (p_dev->state & CLIENT_WIN_REQ(i))
1127 goto warn_out; 1118 goto warn_out;
1128 1119
1129 if (handle->state & CLIENT_STALE) { 1120 if (p_dev->state & CLIENT_STALE) {
1130 handle->client_magic = 0; 1121 p_dev->state &= ~CLIENT_STALE;
1131 handle->state &= ~CLIENT_STALE;
1132 pcmcia_put_dev(p_dev); 1122 pcmcia_put_dev(p_dev);
1133 } else { 1123 } else {
1134 handle->state = CLIENT_UNBOUND; 1124 p_dev->state = CLIENT_UNBOUND;
1135 handle->event_handler = NULL;
1136 } 1125 }
1137 1126
1138 return CS_SUCCESS; 1127 return CS_SUCCESS;
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 5ab55ae0ac36..316f8bcc878b 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -43,7 +43,6 @@
43#include <asm/hd64465/hd64465.h> 43#include <asm/hd64465/hd64465.h>
44#include <asm/hd64465/io.h> 44#include <asm/hd64465/io.h>
45 45
46#include <pcmcia/version.h>
47#include <pcmcia/cs_types.h> 46#include <pcmcia/cs_types.h>
48#include <pcmcia/cs.h> 47#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h> 48#include <pcmcia/cistpl.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index d72f9a35c8bd..a713015e8228 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -53,7 +53,6 @@
53#include <asm/io.h> 53#include <asm/io.h>
54#include <asm/system.h> 54#include <asm/system.h>
55 55
56#include <pcmcia/version.h>
57#include <pcmcia/cs_types.h> 56#include <pcmcia/cs_types.h>
58#include <pcmcia/ss.h> 57#include <pcmcia/ss.h>
59#include <pcmcia/cs.h> 58#include <pcmcia/cs.h>
@@ -698,14 +697,6 @@ static void __init add_pcic(int ns, int type)
698 struct i82365_socket *t = &socket[sockets-ns]; 697 struct i82365_socket *t = &socket[sockets-ns];
699 698
700 base = sockets-ns; 699 base = sockets-ns;
701 if (t->ioaddr > 0) {
702 if (!request_region(t->ioaddr, 2, "i82365")) {
703 printk(KERN_ERR "i82365: IO region conflict at %#lx, not available\n",
704 t->ioaddr);
705 return;
706 }
707 }
708
709 if (base == 0) printk("\n"); 700 if (base == 0) printk("\n");
710 printk(KERN_INFO " %s", pcic[type].name); 701 printk(KERN_INFO " %s", pcic[type].name);
711 printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x", 702 printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x",
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index b1111c6bf062..65f3ee3d4d3c 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -29,7 +29,6 @@
29#include <asm/io.h> 29#include <asm/io.h>
30#include <asm/system.h> 30#include <asm/system.h>
31 31
32#include <pcmcia/version.h>
33#include <pcmcia/cs_types.h> 32#include <pcmcia/cs_types.h>
34#include <pcmcia/ss.h> 33#include <pcmcia/ss.h>
35#include <pcmcia/cs.h> 34#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index c0997c4714f0..7b14d7efd68c 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -30,7 +30,6 @@
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/addrspace.h> 31#include <asm/addrspace.h>
32 32
33#include <pcmcia/version.h>
34#include <pcmcia/cs_types.h> 33#include <pcmcia/cs_types.h>
35#include <pcmcia/ss.h> 34#include <pcmcia/ss.h>
36#include <pcmcia/cs.h> 35#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c
index 1cc83317e7e3..ebb161c4f819 100644
--- a/drivers/pcmcia/pcmcia_compat.c
+++ b/drivers/pcmcia/pcmcia_compat.c
@@ -18,7 +18,6 @@
18#include <linux/init.h> 18#include <linux/init.h>
19 19
20#define IN_CARD_SERVICES 20#define IN_CARD_SERVICES
21#include <pcmcia/version.h>
22#include <pcmcia/cs_types.h> 21#include <pcmcia/cs_types.h>
23#include <pcmcia/cs.h> 22#include <pcmcia/cs.h>
24#include <pcmcia/bulkmem.h> 23#include <pcmcia/bulkmem.h>
@@ -28,64 +27,39 @@
28 27
29#include "cs_internal.h" 28#include "cs_internal.h"
30 29
31int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple) 30int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
32{ 31{
33 struct pcmcia_socket *s; 32 return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple);
34 if (CHECK_HANDLE(handle))
35 return CS_BAD_HANDLE;
36 s = SOCKET(handle);
37 return pccard_get_first_tuple(s, handle->Function, tuple);
38} 33}
39EXPORT_SYMBOL(pcmcia_get_first_tuple); 34EXPORT_SYMBOL(pcmcia_get_first_tuple);
40 35
41int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple) 36int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
42{ 37{
43 struct pcmcia_socket *s; 38 return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple);
44 if (CHECK_HANDLE(handle))
45 return CS_BAD_HANDLE;
46 s = SOCKET(handle);
47 return pccard_get_next_tuple(s, handle->Function, tuple);
48} 39}
49EXPORT_SYMBOL(pcmcia_get_next_tuple); 40EXPORT_SYMBOL(pcmcia_get_next_tuple);
50 41
51int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple) 42int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple)
52{ 43{
53 struct pcmcia_socket *s; 44 return pccard_get_tuple_data(p_dev->socket, tuple);
54 if (CHECK_HANDLE(handle))
55 return CS_BAD_HANDLE;
56 s = SOCKET(handle);
57 return pccard_get_tuple_data(s, tuple);
58} 45}
59EXPORT_SYMBOL(pcmcia_get_tuple_data); 46EXPORT_SYMBOL(pcmcia_get_tuple_data);
60 47
61int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) 48int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse)
62{ 49{
63 return pccard_parse_tuple(tuple, parse); 50 return pccard_parse_tuple(tuple, parse);
64} 51}
65EXPORT_SYMBOL(pcmcia_parse_tuple); 52EXPORT_SYMBOL(pcmcia_parse_tuple);
66 53
67int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info) 54int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info)
68{ 55{
69 struct pcmcia_socket *s; 56 return pccard_validate_cis(p_dev->socket, p_dev->func, info);
70 if (CHECK_HANDLE(handle))
71 return CS_BAD_HANDLE;
72 s = SOCKET(handle);
73 return pccard_validate_cis(s, handle->Function, info);
74} 57}
75EXPORT_SYMBOL(pcmcia_validate_cis); 58EXPORT_SYMBOL(pcmcia_validate_cis);
76 59
77 60
78int pcmcia_reset_card(client_handle_t handle, client_req_t *req) 61int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req)
79{ 62{
80 struct pcmcia_socket *skt; 63 return pccard_reset_card(p_dev->socket);
81
82 if (CHECK_HANDLE(handle))
83 return CS_BAD_HANDLE;
84 skt = SOCKET(handle);
85 if (!skt)
86 return CS_BAD_HANDLE;
87
88 return pccard_reset_card(skt);
89} 64}
90EXPORT_SYMBOL(pcmcia_reset_card); 65EXPORT_SYMBOL(pcmcia_reset_card);
91
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index b883bc151ed0..39ba6406fd54 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -31,7 +31,6 @@
31#include <linux/workqueue.h> 31#include <linux/workqueue.h>
32 32
33#define IN_CARD_SERVICES 33#define IN_CARD_SERVICES
34#include <pcmcia/version.h>
35#include <pcmcia/cs_types.h> 34#include <pcmcia/cs_types.h>
36#include <pcmcia/cs.h> 35#include <pcmcia/cs.h>
37#include <pcmcia/cistpl.h> 36#include <pcmcia/cistpl.h>
@@ -71,29 +70,6 @@ extern int ds_pc_debug;
71#define ds_dbg(lvl, fmt, arg...) do { } while (0) 70#define ds_dbg(lvl, fmt, arg...) do { } while (0)
72#endif 71#endif
73 72
74static const char *release = "Linux Kernel Card Services";
75
76/** pcmcia_get_card_services_info
77 *
78 * Return information about this version of Card Services
79 */
80static int pcmcia_get_card_services_info(servinfo_t *info)
81{
82 unsigned int socket_count = 0;
83 struct list_head *tmp;
84 info->Signature[0] = 'C';
85 info->Signature[1] = 'S';
86 down_read(&pcmcia_socket_list_rwsem);
87 list_for_each(tmp, &pcmcia_socket_list)
88 socket_count++;
89 up_read(&pcmcia_socket_list_rwsem);
90 info->Count = socket_count;
91 info->Revision = CS_RELEASE_CODE;
92 info->CSLevel = 0x0210;
93 info->VendorString = (char *)release;
94 return CS_SUCCESS;
95} /* get_card_services_info */
96
97 73
98/* backwards-compatible accessing of driver --- by name! */ 74/* backwards-compatible accessing of driver --- by name! */
99 75
@@ -591,9 +567,6 @@ static int ds_ioctl(struct inode * inode, struct file * file,
591 case DS_ADJUST_RESOURCE_INFO: 567 case DS_ADJUST_RESOURCE_INFO:
592 ret = pcmcia_adjust_resource_info(&buf->adjust); 568 ret = pcmcia_adjust_resource_info(&buf->adjust);
593 break; 569 break;
594 case DS_GET_CARD_SERVICES_INFO:
595 ret = pcmcia_get_card_services_info(&buf->servinfo);
596 break;
597 case DS_GET_CONFIGURATION_INFO: 570 case DS_GET_CONFIGURATION_INFO:
598 if (buf->config.Function && 571 if (buf->config.Function &&
599 (buf->config.Function >= s->functions)) 572 (buf->config.Function >= s->functions))
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index c01dc6bf1526..184f4f88b2a0 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -23,7 +23,6 @@
23#include <linux/device.h> 23#include <linux/device.h>
24 24
25#define IN_CARD_SERVICES 25#define IN_CARD_SERVICES
26#include <pcmcia/version.h>
27#include <pcmcia/cs_types.h> 26#include <pcmcia/cs_types.h>
28#include <pcmcia/ss.h> 27#include <pcmcia/ss.h>
29#include <pcmcia/cs.h> 28#include <pcmcia/cs.h>
@@ -202,14 +201,11 @@ int pccard_access_configuration_register(struct pcmcia_socket *s,
202 return CS_SUCCESS; 201 return CS_SUCCESS;
203} /* pccard_access_configuration_register */ 202} /* pccard_access_configuration_register */
204 203
205int pcmcia_access_configuration_register(client_handle_t handle, 204int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
206 conf_reg_t *reg) 205 conf_reg_t *reg)
207{ 206{
208 struct pcmcia_socket *s; 207 return pccard_access_configuration_register(p_dev->socket,
209 if (CHECK_HANDLE(handle)) 208 p_dev->func, reg);
210 return CS_BAD_HANDLE;
211 s = SOCKET(handle);
212 return pccard_access_configuration_register(s, handle->Function, reg);
213} 209}
214EXPORT_SYMBOL(pcmcia_access_configuration_register); 210EXPORT_SYMBOL(pcmcia_access_configuration_register);
215 211
@@ -271,17 +267,11 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
271 return CS_SUCCESS; 267 return CS_SUCCESS;
272} /* pccard_get_configuration_info */ 268} /* pccard_get_configuration_info */
273 269
274int pcmcia_get_configuration_info(client_handle_t handle, 270int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
275 config_info_t *config) 271 config_info_t *config)
276{ 272{
277 struct pcmcia_socket *s; 273 return pccard_get_configuration_info(p_dev->socket, p_dev->func,
278 274 config);
279 if ((CHECK_HANDLE(handle)) || !config)
280 return CS_BAD_HANDLE;
281 s = SOCKET(handle);
282 if (!s)
283 return CS_BAD_HANDLE;
284 return pccard_get_configuration_info(s, handle->Function, config);
285} 275}
286EXPORT_SYMBOL(pcmcia_get_configuration_info); 276EXPORT_SYMBOL(pcmcia_get_configuration_info);
287 277
@@ -382,10 +372,8 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
382int pcmcia_get_status(client_handle_t handle, cs_status_t *status) 372int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
383{ 373{
384 struct pcmcia_socket *s; 374 struct pcmcia_socket *s;
385 if (CHECK_HANDLE(handle))
386 return CS_BAD_HANDLE;
387 s = SOCKET(handle); 375 s = SOCKET(handle);
388 return pccard_get_status(s, handle->Function, status); 376 return pccard_get_status(s, handle->func, status);
389} 377}
390EXPORT_SYMBOL(pcmcia_get_status); 378EXPORT_SYMBOL(pcmcia_get_status);
391 379
@@ -426,16 +414,14 @@ EXPORT_SYMBOL(pcmcia_map_mem_page);
426 * 414 *
427 * Modify a locked socket configuration 415 * Modify a locked socket configuration
428 */ 416 */
429int pcmcia_modify_configuration(client_handle_t handle, 417int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
430 modconf_t *mod) 418 modconf_t *mod)
431{ 419{
432 struct pcmcia_socket *s; 420 struct pcmcia_socket *s;
433 config_t *c; 421 config_t *c;
434 422
435 if (CHECK_HANDLE(handle)) 423 s = p_dev->socket;
436 return CS_BAD_HANDLE; 424 c = CONFIG(p_dev);
437 s = SOCKET(handle);
438 c = CONFIG(handle);
439 if (!(s->state & SOCKET_PRESENT)) 425 if (!(s->state & SOCKET_PRESENT))
440 return CS_NO_CARD; 426 return CS_NO_CARD;
441 if (!(c->state & CONFIG_LOCKED)) 427 if (!(c->state & CONFIG_LOCKED))
@@ -472,25 +458,18 @@ int pcmcia_modify_configuration(client_handle_t handle,
472EXPORT_SYMBOL(pcmcia_modify_configuration); 458EXPORT_SYMBOL(pcmcia_modify_configuration);
473 459
474 460
475int pcmcia_release_configuration(client_handle_t handle) 461int pcmcia_release_configuration(struct pcmcia_device *p_dev)
476{ 462{
477 pccard_io_map io = { 0, 0, 0, 0, 1 }; 463 pccard_io_map io = { 0, 0, 0, 0, 1 };
478 struct pcmcia_socket *s; 464 struct pcmcia_socket *s = p_dev->socket;
479 int i; 465 int i;
480 466
481 if (CHECK_HANDLE(handle) || 467 if (!(p_dev->state & CLIENT_CONFIG_LOCKED))
482 !(handle->state & CLIENT_CONFIG_LOCKED))
483 return CS_BAD_HANDLE; 468 return CS_BAD_HANDLE;
484 handle->state &= ~CLIENT_CONFIG_LOCKED; 469 p_dev->state &= ~CLIENT_CONFIG_LOCKED;
485 s = SOCKET(handle);
486
487#ifdef CONFIG_CARDBUS
488 if (handle->state & CLIENT_CARDBUS)
489 return CS_SUCCESS;
490#endif
491 470
492 if (!(handle->state & CLIENT_STALE)) { 471 if (!(p_dev->state & CLIENT_STALE)) {
493 config_t *c = CONFIG(handle); 472 config_t *c = CONFIG(p_dev);
494 if (--(s->lock_count) == 0) { 473 if (--(s->lock_count) == 0) {
495 s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ 474 s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
496 s->socket.Vpp = 0; 475 s->socket.Vpp = 0;
@@ -523,22 +502,16 @@ EXPORT_SYMBOL(pcmcia_release_configuration);
523 * don't bother checking the port ranges against the current socket 502 * don't bother checking the port ranges against the current socket
524 * values. 503 * values.
525 */ 504 */
526int pcmcia_release_io(client_handle_t handle, io_req_t *req) 505int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
527{ 506{
528 struct pcmcia_socket *s; 507 struct pcmcia_socket *s = p_dev->socket;
529 508
530 if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ)) 509 if (!(p_dev->state & CLIENT_IO_REQ))
531 return CS_BAD_HANDLE; 510 return CS_BAD_HANDLE;
532 handle->state &= ~CLIENT_IO_REQ; 511 p_dev->state &= ~CLIENT_IO_REQ;
533 s = SOCKET(handle);
534
535#ifdef CONFIG_CARDBUS
536 if (handle->state & CLIENT_CARDBUS)
537 return CS_SUCCESS;
538#endif
539 512
540 if (!(handle->state & CLIENT_STALE)) { 513 if (!(p_dev->state & CLIENT_STALE)) {
541 config_t *c = CONFIG(handle); 514 config_t *c = CONFIG(p_dev);
542 if (c->state & CONFIG_LOCKED) 515 if (c->state & CONFIG_LOCKED)
543 return CS_CONFIGURATION_LOCKED; 516 return CS_CONFIGURATION_LOCKED;
544 if ((c->io.BasePort1 != req->BasePort1) || 517 if ((c->io.BasePort1 != req->BasePort1) ||
@@ -558,16 +531,15 @@ int pcmcia_release_io(client_handle_t handle, io_req_t *req)
558EXPORT_SYMBOL(pcmcia_release_io); 531EXPORT_SYMBOL(pcmcia_release_io);
559 532
560 533
561int pcmcia_release_irq(client_handle_t handle, irq_req_t *req) 534int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
562{ 535{
563 struct pcmcia_socket *s; 536 struct pcmcia_socket *s = p_dev->socket;
564 if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ)) 537 if (!(p_dev->state & CLIENT_IRQ_REQ))
565 return CS_BAD_HANDLE; 538 return CS_BAD_HANDLE;
566 handle->state &= ~CLIENT_IRQ_REQ; 539 p_dev->state &= ~CLIENT_IRQ_REQ;
567 s = SOCKET(handle);
568 540
569 if (!(handle->state & CLIENT_STALE)) { 541 if (!(p_dev->state & CLIENT_STALE)) {
570 config_t *c = CONFIG(handle); 542 config_t *c = CONFIG(p_dev);
571 if (c->state & CONFIG_LOCKED) 543 if (c->state & CONFIG_LOCKED)
572 return CS_CONFIGURATION_LOCKED; 544 return CS_CONFIGURATION_LOCKED;
573 if (c->irq.Attributes != req->Attributes) 545 if (c->irq.Attributes != req->Attributes)
@@ -623,29 +595,21 @@ int pcmcia_release_window(window_handle_t win)
623EXPORT_SYMBOL(pcmcia_release_window); 595EXPORT_SYMBOL(pcmcia_release_window);
624 596
625 597
626int pcmcia_request_configuration(client_handle_t handle, 598int pcmcia_request_configuration(struct pcmcia_device *p_dev,
627 config_req_t *req) 599 config_req_t *req)
628{ 600{
629 int i; 601 int i;
630 u_int base; 602 u_int base;
631 struct pcmcia_socket *s; 603 struct pcmcia_socket *s = p_dev->socket;
632 config_t *c; 604 config_t *c;
633 pccard_io_map iomap; 605 pccard_io_map iomap;
634 606
635 if (CHECK_HANDLE(handle))
636 return CS_BAD_HANDLE;
637 s = SOCKET(handle);
638 if (!(s->state & SOCKET_PRESENT)) 607 if (!(s->state & SOCKET_PRESENT))
639 return CS_NO_CARD; 608 return CS_NO_CARD;
640 609
641#ifdef CONFIG_CARDBUS
642 if (handle->state & CLIENT_CARDBUS)
643 return CS_UNSUPPORTED_MODE;
644#endif
645
646 if (req->IntType & INT_CARDBUS) 610 if (req->IntType & INT_CARDBUS)
647 return CS_UNSUPPORTED_MODE; 611 return CS_UNSUPPORTED_MODE;
648 c = CONFIG(handle); 612 c = CONFIG(p_dev);
649 if (c->state & CONFIG_LOCKED) 613 if (c->state & CONFIG_LOCKED)
650 return CS_CONFIGURATION_LOCKED; 614 return CS_CONFIGURATION_LOCKED;
651 615
@@ -746,7 +710,7 @@ int pcmcia_request_configuration(client_handle_t handle,
746 } 710 }
747 711
748 c->state |= CONFIG_LOCKED; 712 c->state |= CONFIG_LOCKED;
749 handle->state |= CLIENT_CONFIG_LOCKED; 713 p_dev->state |= CLIENT_CONFIG_LOCKED;
750 return CS_SUCCESS; 714 return CS_SUCCESS;
751} /* pcmcia_request_configuration */ 715} /* pcmcia_request_configuration */
752EXPORT_SYMBOL(pcmcia_request_configuration); 716EXPORT_SYMBOL(pcmcia_request_configuration);
@@ -757,29 +721,17 @@ EXPORT_SYMBOL(pcmcia_request_configuration);
757 * Request_io() reserves ranges of port addresses for a socket. 721 * Request_io() reserves ranges of port addresses for a socket.
758 * I have not implemented range sharing or alias addressing. 722 * I have not implemented range sharing or alias addressing.
759 */ 723 */
760int pcmcia_request_io(client_handle_t handle, io_req_t *req) 724int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
761{ 725{
762 struct pcmcia_socket *s; 726 struct pcmcia_socket *s = p_dev->socket;
763 config_t *c; 727 config_t *c;
764 728
765 if (CHECK_HANDLE(handle))
766 return CS_BAD_HANDLE;
767 s = SOCKET(handle);
768 if (!(s->state & SOCKET_PRESENT)) 729 if (!(s->state & SOCKET_PRESENT))
769 return CS_NO_CARD; 730 return CS_NO_CARD;
770 731
771 if (handle->state & CLIENT_CARDBUS) {
772#ifdef CONFIG_CARDBUS
773 handle->state |= CLIENT_IO_REQ;
774 return CS_SUCCESS;
775#else
776 return CS_UNSUPPORTED_FUNCTION;
777#endif
778 }
779
780 if (!req) 732 if (!req)
781 return CS_UNSUPPORTED_MODE; 733 return CS_UNSUPPORTED_MODE;
782 c = CONFIG(handle); 734 c = CONFIG(p_dev);
783 if (c->state & CONFIG_LOCKED) 735 if (c->state & CONFIG_LOCKED)
784 return CS_CONFIGURATION_LOCKED; 736 return CS_CONFIGURATION_LOCKED;
785 if (c->state & CONFIG_IO_REQ) 737 if (c->state & CONFIG_IO_REQ)
@@ -804,7 +756,7 @@ int pcmcia_request_io(client_handle_t handle, io_req_t *req)
804 756
805 c->io = *req; 757 c->io = *req;
806 c->state |= CONFIG_IO_REQ; 758 c->state |= CONFIG_IO_REQ;
807 handle->state |= CLIENT_IO_REQ; 759 p_dev->state |= CLIENT_IO_REQ;
808 return CS_SUCCESS; 760 return CS_SUCCESS;
809} /* pcmcia_request_io */ 761} /* pcmcia_request_io */
810EXPORT_SYMBOL(pcmcia_request_io); 762EXPORT_SYMBOL(pcmcia_request_io);
@@ -827,19 +779,15 @@ static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)
827} 779}
828#endif 780#endif
829 781
830int pcmcia_request_irq(client_handle_t handle, irq_req_t *req) 782int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
831{ 783{
832 struct pcmcia_socket *s; 784 struct pcmcia_socket *s = p_dev->socket;
833 config_t *c; 785 config_t *c;
834 int ret = CS_IN_USE, irq = 0; 786 int ret = CS_IN_USE, irq = 0;
835 struct pcmcia_device *p_dev = handle_to_pdev(handle);
836 787
837 if (CHECK_HANDLE(handle))
838 return CS_BAD_HANDLE;
839 s = SOCKET(handle);
840 if (!(s->state & SOCKET_PRESENT)) 788 if (!(s->state & SOCKET_PRESENT))
841 return CS_NO_CARD; 789 return CS_NO_CARD;
842 c = CONFIG(handle); 790 c = CONFIG(p_dev);
843 if (c->state & CONFIG_LOCKED) 791 if (c->state & CONFIG_LOCKED)
844 return CS_CONFIGURATION_LOCKED; 792 return CS_CONFIGURATION_LOCKED;
845 if (c->state & CONFIG_IRQ_REQ) 793 if (c->state & CONFIG_IRQ_REQ)
@@ -903,7 +851,7 @@ int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
903 s->irq.Config++; 851 s->irq.Config++;
904 852
905 c->state |= CONFIG_IRQ_REQ; 853 c->state |= CONFIG_IRQ_REQ;
906 handle->state |= CLIENT_IRQ_REQ; 854 p_dev->state |= CLIENT_IRQ_REQ;
907 855
908#ifdef CONFIG_PCMCIA_PROBE 856#ifdef CONFIG_PCMCIA_PROBE
909 pcmcia_used_irq[irq]++; 857 pcmcia_used_irq[irq]++;
@@ -919,16 +867,13 @@ EXPORT_SYMBOL(pcmcia_request_irq);
919 * Request_window() establishes a mapping between card memory space 867 * Request_window() establishes a mapping between card memory space
920 * and system memory space. 868 * and system memory space.
921 */ 869 */
922int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh) 870int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
923{ 871{
924 struct pcmcia_socket *s; 872 struct pcmcia_socket *s = (*p_dev)->socket;
925 window_t *win; 873 window_t *win;
926 u_long align; 874 u_long align;
927 int w; 875 int w;
928 876
929 if (CHECK_HANDLE(*handle))
930 return CS_BAD_HANDLE;
931 s = (*handle)->Socket;
932 if (!(s->state & SOCKET_PRESENT)) 877 if (!(s->state & SOCKET_PRESENT))
933 return CS_NO_CARD; 878 return CS_NO_CARD;
934 if (req->Attributes & (WIN_PAGED | WIN_SHARED)) 879 if (req->Attributes & (WIN_PAGED | WIN_SHARED))
@@ -957,7 +902,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
957 win = &s->win[w]; 902 win = &s->win[w];
958 win->magic = WINDOW_MAGIC; 903 win->magic = WINDOW_MAGIC;
959 win->index = w; 904 win->index = w;
960 win->handle = *handle; 905 win->handle = *p_dev;
961 win->sock = s; 906 win->sock = s;
962 907
963 if (!(s->features & SS_CAP_STATIC_MAP)) { 908 if (!(s->features & SS_CAP_STATIC_MAP)) {
@@ -966,7 +911,7 @@ int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle
966 if (!win->ctl.res) 911 if (!win->ctl.res)
967 return CS_IN_USE; 912 return CS_IN_USE;
968 } 913 }
969 (*handle)->state |= CLIENT_WIN_REQ(w); 914 (*p_dev)->state |= CLIENT_WIN_REQ(w);
970 915
971 /* Configure the socket controller */ 916 /* Configure the socket controller */
972 win->ctl.map = w+1; 917 win->ctl.map = w+1;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index f1bb79153021..e98bb3d80e7c 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -34,7 +34,6 @@
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/config.h> 35#include <linux/config.h>
36 36
37#include <pcmcia/version.h>
38#include <pcmcia/cs_types.h> 37#include <pcmcia/cs_types.h>
39#include <pcmcia/cs.h> 38#include <pcmcia/cs.h>
40#include <pcmcia/ss.h> 39#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 700a155fbc78..6f14126889b3 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -11,7 +11,6 @@
11 11
12/* include the world */ 12/* include the world */
13#include <linux/cpufreq.h> 13#include <linux/cpufreq.h>
14#include <pcmcia/version.h>
15#include <pcmcia/cs_types.h> 14#include <pcmcia/cs_types.h>
16#include <pcmcia/cs.h> 15#include <pcmcia/cs.h>
17#include <pcmcia/ss.h> 16#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index fcef54c1c2da..1040a6c1a8a4 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -29,7 +29,6 @@
29#include <asm/irq.h> 29#include <asm/irq.h>
30 30
31#define IN_CARD_SERVICES 31#define IN_CARD_SERVICES
32#include <pcmcia/version.h>
33#include <pcmcia/cs_types.h> 32#include <pcmcia/cs_types.h>
34#include <pcmcia/ss.h> 33#include <pcmcia/ss.h>
35#include <pcmcia/cs.h> 34#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index aacbbb5f055d..d5a61eae6119 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -50,7 +50,6 @@
50#include <asm/io.h> 50#include <asm/io.h>
51#include <asm/system.h> 51#include <asm/system.h>
52 52
53#include <pcmcia/version.h>
54#include <pcmcia/cs_types.h> 53#include <pcmcia/cs_types.h>
55#include <pcmcia/cs.h> 54#include <pcmcia/cs.h>
56#include <pcmcia/ss.h> 55#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index c7ba99871aca..fbe233e19ceb 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -154,8 +154,6 @@
154#define ENE_TEST_C9 0xc9 /* 8bit */ 154#define ENE_TEST_C9 0xc9 /* 8bit */
155#define ENE_TEST_C9_TLTENABLE 0x02 155#define ENE_TEST_C9_TLTENABLE 0x02
156 156
157#ifdef CONFIG_CARDBUS
158
159/* 157/*
160 * Texas Instruments CardBus controller overrides. 158 * Texas Instruments CardBus controller overrides.
161 */ 159 */
@@ -843,7 +841,5 @@ static int ti1250_override(struct yenta_socket *socket)
843 return ti12xx_override(socket); 841 return ti12xx_override(socket);
844} 842}
845 843
846#endif /* CONFIG_CARDBUS */
847
848#endif /* _LINUX_TI113X_H */ 844#endif /* _LINUX_TI113X_H */
849 845
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 02b23abc2df1..0e7aa8176692 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -18,7 +18,6 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/module.h> 19#include <linux/module.h>
20 20
21#include <pcmcia/version.h>
22#include <pcmcia/cs_types.h> 21#include <pcmcia/cs_types.h>
23#include <pcmcia/ss.h> 22#include <pcmcia/ss.h>
24#include <pcmcia/cs.h> 23#include <pcmcia/cs.h>
@@ -869,14 +868,11 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
869 */ 868 */
870static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask) 869static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
871{ 870{
872 socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
873 socket->socket.map_size = 0x1000;
874 socket->socket.pci_irq = socket->cb_irq; 871 socket->socket.pci_irq = socket->cb_irq;
875 if (isa_probe) 872 if (isa_probe)
876 socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask); 873 socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
877 else 874 else
878 socket->socket.irq_mask = 0; 875 socket->socket.irq_mask = 0;
879 socket->socket.cb_dev = socket->dev;
880 876
881 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",
882 socket->socket.irq_mask, socket->cb_irq); 878 socket->socket.irq_mask, socket->cb_irq);
@@ -942,6 +938,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
942 socket->socket.dev.dev = &dev->dev; 938 socket->socket.dev.dev = &dev->dev;
943 socket->socket.driver_data = socket; 939 socket->socket.driver_data = socket;
944 socket->socket.owner = THIS_MODULE; 940 socket->socket.owner = THIS_MODULE;
941 socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
942 socket->socket.map_size = 0x1000;
943 socket->socket.cb_dev = dev;
945 944
946 /* prepare struct yenta_socket */ 945 /* prepare struct yenta_socket */
947 socket->dev = dev; 946 socket->dev = dev;
@@ -1012,6 +1011,10 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
1012 socket->poll_timer.data = (unsigned long)socket; 1011 socket->poll_timer.data = (unsigned long)socket;
1013 socket->poll_timer.expires = jiffies + HZ; 1012 socket->poll_timer.expires = jiffies + HZ;
1014 add_timer(&socket->poll_timer); 1013 add_timer(&socket->poll_timer);
1014 printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
1015 KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
1016 } else {
1017 socket->socket.features |= SS_CAP_CARDBUS;
1015 } 1018 }
1016 1019
1017 /* Figure out what the dang thing can do for the PCMCIA layer... */ 1020 /* Figure out what the dang thing can do for the PCMCIA layer... */
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index f1f6bf596dc9..7c5306499832 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -50,7 +50,6 @@
50#include <scsi/scsi_host.h> 50#include <scsi/scsi_host.h>
51#include "aha152x.h" 51#include "aha152x.h"
52 52
53#include <pcmcia/version.h>
54#include <pcmcia/cs_types.h> 53#include <pcmcia/cs_types.h>
55#include <pcmcia/cs.h> 54#include <pcmcia/cs.h>
56#include <pcmcia/cistpl.h> 55#include <pcmcia/cistpl.h>
@@ -134,11 +133,6 @@ static dev_link_t *aha152x_attach(void)
134 link->next = dev_list; 133 link->next = dev_list;
135 dev_list = link; 134 dev_list = link;
136 client_reg.dev_info = &dev_info; 135 client_reg.dev_info = &dev_info;
137 client_reg.event_handler = &aha152x_event;
138 client_reg.EventMask =
139 CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
140 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
141 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
142 client_reg.Version = 0x0210; 136 client_reg.Version = 0x0210;
143 client_reg.event_callback_args.client_data = link; 137 client_reg.event_callback_args.client_data = link;
144 ret = pcmcia_register_client(&link->handle, &client_reg); 138 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -334,6 +328,7 @@ static struct pcmcia_driver aha152x_cs_driver = {
334 .name = "aha152x_cs", 328 .name = "aha152x_cs",
335 }, 329 },
336 .attach = aha152x_attach, 330 .attach = aha152x_attach,
331 .event = aha152x_event,
337 .detach = aha152x_detach, 332 .detach = aha152x_detach,
338 .id_table = aha152x_ids, 333 .id_table = aha152x_ids,
339}; 334};
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 853e6ee9b71a..db8f5cd85ffe 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -47,7 +47,6 @@
47#include <scsi/scsi_host.h> 47#include <scsi/scsi_host.h>
48#include "fdomain.h" 48#include "fdomain.h"
49 49
50#include <pcmcia/version.h>
51#include <pcmcia/cs_types.h> 50#include <pcmcia/cs_types.h>
52#include <pcmcia/cs.h> 51#include <pcmcia/cs.h>
53#include <pcmcia/cistpl.h> 52#include <pcmcia/cistpl.h>
@@ -120,11 +119,6 @@ static dev_link_t *fdomain_attach(void)
120 link->next = dev_list; 119 link->next = dev_list;
121 dev_list = link; 120 dev_list = link;
122 client_reg.dev_info = &dev_info; 121 client_reg.dev_info = &dev_info;
123 client_reg.event_handler = &fdomain_event;
124 client_reg.EventMask =
125 CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
126 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
127 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
128 client_reg.Version = 0x0210; 122 client_reg.Version = 0x0210;
129 client_reg.event_callback_args.client_data = link; 123 client_reg.event_callback_args.client_data = link;
130 ret = pcmcia_register_client(&link->handle, &client_reg); 124 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -314,6 +308,7 @@ static struct pcmcia_driver fdomain_cs_driver = {
314 .name = "fdomain_cs", 308 .name = "fdomain_cs",
315 }, 309 },
316 .attach = fdomain_attach, 310 .attach = fdomain_attach,
311 .event = fdomain_event,
317 .detach = fdomain_detach, 312 .detach = fdomain_detach,
318 .id_table = fdomain_ids, 313 .id_table = fdomain_ids,
319}; 314};
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 91b3f28e7a19..3cd3b40b1a4c 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -51,7 +51,6 @@
51#include <scsi/scsi.h> 51#include <scsi/scsi.h>
52#include <scsi/scsi_ioctl.h> 52#include <scsi/scsi_ioctl.h>
53 53
54#include <pcmcia/version.h>
55#include <pcmcia/cs_types.h> 54#include <pcmcia/cs_types.h>
56#include <pcmcia/cs.h> 55#include <pcmcia/cs.h>
57#include <pcmcia/cistpl.h> 56#include <pcmcia/cistpl.h>
@@ -1642,11 +1641,6 @@ static dev_link_t *nsp_cs_attach(void)
1642 link->next = dev_list; 1641 link->next = dev_list;
1643 dev_list = link; 1642 dev_list = link;
1644 client_reg.dev_info = &dev_info; 1643 client_reg.dev_info = &dev_info;
1645 client_reg.EventMask =
1646 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1647 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1648 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
1649 client_reg.event_handler = &nsp_cs_event;
1650 client_reg.Version = 0x0210; 1644 client_reg.Version = 0x0210;
1651 client_reg.event_callback_args.client_data = link; 1645 client_reg.event_callback_args.client_data = link;
1652 ret = pcmcia_register_client(&link->handle, &client_reg); 1646 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2138,12 +2132,13 @@ static struct pcmcia_device_id nsp_cs_ids[] = {
2138MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids); 2132MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
2139 2133
2140static struct pcmcia_driver nsp_driver = { 2134static struct pcmcia_driver nsp_driver = {
2141 .owner = THIS_MODULE, 2135 .owner = THIS_MODULE,
2142 .drv = { 2136 .drv = {
2143 .name = "nsp_cs", 2137 .name = "nsp_cs",
2144 }, 2138 },
2145 .attach = nsp_cs_attach, 2139 .attach = nsp_cs_attach,
2146 .detach = nsp_cs_detach, 2140 .event = nsp_cs_event,
2141 .detach = nsp_cs_detach,
2147 .id_table = nsp_cs_ids, 2142 .id_table = nsp_cs_ids,
2148}; 2143};
2149#endif 2144#endif
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 0dcf41102abf..7a516f35834e 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -49,7 +49,6 @@
49#include <scsi/scsi_host.h> 49#include <scsi/scsi_host.h>
50#include "../qlogicfas408.h" 50#include "../qlogicfas408.h"
51 51
52#include <pcmcia/version.h>
53#include <pcmcia/cs_types.h> 52#include <pcmcia/cs_types.h>
54#include <pcmcia/cs.h> 53#include <pcmcia/cs.h>
55#include <pcmcia/cistpl.h> 54#include <pcmcia/cistpl.h>
@@ -194,8 +193,6 @@ static dev_link_t *qlogic_attach(void)
194 link->next = dev_list; 193 link->next = dev_list;
195 dev_list = link; 194 dev_list = link;
196 client_reg.dev_info = &dev_info; 195 client_reg.dev_info = &dev_info;
197 client_reg.event_handler = &qlogic_event;
198 client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
199 client_reg.Version = 0x0210; 196 client_reg.Version = 0x0210;
200 client_reg.event_callback_args.client_data = link; 197 client_reg.event_callback_args.client_data = link;
201 ret = pcmcia_register_client(&link->handle, &client_reg); 198 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -423,6 +420,7 @@ static struct pcmcia_driver qlogic_cs_driver = {
423 .name = "qlogic_cs", 420 .name = "qlogic_cs",
424 }, 421 },
425 .attach = qlogic_attach, 422 .attach = qlogic_attach,
423 .event = qlogic_event,
426 .detach = qlogic_detach, 424 .detach = qlogic_detach,
427 .id_table = qlogic_ids, 425 .id_table = qlogic_ids,
428}; 426};
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 7d4b16b6797d..b4b3a1a8a0c7 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -979,10 +979,6 @@ SYM53C500_attach(void)
979 link->next = dev_list; 979 link->next = dev_list;
980 dev_list = link; 980 dev_list = link;
981 client_reg.dev_info = &dev_info; 981 client_reg.dev_info = &dev_info;
982 client_reg.event_handler = &SYM53C500_event;
983 client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
984 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
985 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
986 client_reg.Version = 0x0210; 982 client_reg.Version = 0x0210;
987 client_reg.event_callback_args.client_data = link; 983 client_reg.event_callback_args.client_data = link;
988 ret = pcmcia_register_client(&link->handle, &client_reg); 984 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1013,6 +1009,7 @@ static struct pcmcia_driver sym53c500_cs_driver = {
1013 .name = "sym53c500_cs", 1009 .name = "sym53c500_cs",
1014 }, 1010 },
1015 .attach = SYM53C500_attach, 1011 .attach = SYM53C500_attach,
1012 .event = SYM53C500_event,
1016 .detach = SYM53C500_detach, 1013 .detach = SYM53C500_detach,
1017 .id_table = sym53c500_ids, 1014 .id_table = sym53c500_ids,
1018}; 1015};
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 73a34b18866f..de0136cc5938 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -45,7 +45,6 @@
45#include <asm/io.h> 45#include <asm/io.h>
46#include <asm/system.h> 46#include <asm/system.h>
47 47
48#include <pcmcia/version.h>
49#include <pcmcia/cs_types.h> 48#include <pcmcia/cs_types.h>
50#include <pcmcia/cs.h> 49#include <pcmcia/cs.h>
51#include <pcmcia/cistpl.h> 50#include <pcmcia/cistpl.h>
@@ -232,11 +231,6 @@ static dev_link_t *serial_attach(void)
232 link->next = dev_list; 231 link->next = dev_list;
233 dev_list = link; 232 dev_list = link;
234 client_reg.dev_info = &dev_info; 233 client_reg.dev_info = &dev_info;
235 client_reg.EventMask =
236 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
237 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
238 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
239 client_reg.event_handler = &serial_event;
240 client_reg.Version = 0x0210; 234 client_reg.Version = 0x0210;
241 client_reg.event_callback_args.client_data = link; 235 client_reg.event_callback_args.client_data = link;
242 ret = pcmcia_register_client(&link->handle, &client_reg); 236 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -883,6 +877,7 @@ static struct pcmcia_driver serial_cs_driver = {
883 .name = "serial_cs", 877 .name = "serial_cs",
884 }, 878 },
885 .attach = serial_attach, 879 .attach = serial_attach,
880 .event = serial_event,
886 .detach = serial_detach, 881 .detach = serial_detach,
887 .id_table = serial_ids, 882 .id_table = serial_ids,
888}; 883};
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index ce5ebfe4af2b..57c0c6e3fbed 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -9,7 +9,6 @@
9#include <linux/errno.h> /* error codes */ 9#include <linux/errno.h> /* error codes */
10#include <linux/slab.h> 10#include <linux/slab.h>
11 11
12#include <pcmcia/version.h>
13#include <pcmcia/cs_types.h> 12#include <pcmcia/cs_types.h>
14#include <pcmcia/cs.h> 13#include <pcmcia/cs.h>
15#include <pcmcia/cistpl.h> 14#include <pcmcia/cistpl.h>
@@ -69,11 +68,6 @@ static dev_link_t *ixj_attach(void)
69 link->next = dev_list; 68 link->next = dev_list;
70 dev_list = link; 69 dev_list = link;
71 client_reg.dev_info = &dev_info; 70 client_reg.dev_info = &dev_info;
72 client_reg.EventMask =
73 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
74 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
75 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
76 client_reg.event_handler = &ixj_event;
77 client_reg.Version = 0x0210; 71 client_reg.Version = 0x0210;
78 client_reg.event_callback_args.client_data = link; 72 client_reg.event_callback_args.client_data = link;
79 ret = pcmcia_register_client(&link->handle, &client_reg); 73 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -307,6 +301,7 @@ static struct pcmcia_driver ixj_driver = {
307 .name = "ixj_cs", 301 .name = "ixj_cs",
308 }, 302 },
309 .attach = ixj_attach, 303 .attach = ixj_attach,
304 .event = ixj_event,
310 .detach = ixj_detach, 305 .detach = ixj_detach,
311 .id_table = ixj_ids, 306 .id_table = ixj_ids,
312}; 307};
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 269d8ef01459..38aebe361ca1 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -20,7 +20,6 @@
20#include <linux/timer.h> 20#include <linux/timer.h>
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22 22
23#include <pcmcia/version.h>
24#include <pcmcia/cs_types.h> 23#include <pcmcia/cs_types.h>
25#include <pcmcia/cs.h> 24#include <pcmcia/cs.h>
26#include <pcmcia/cistpl.h> 25#include <pcmcia/cistpl.h>
@@ -389,11 +388,6 @@ static dev_link_t *sl811_cs_attach(void)
389 dev_list = link; 388 dev_list = link;
390 client_reg.dev_info = (dev_info_t *) &driver_name; 389 client_reg.dev_info = (dev_info_t *) &driver_name;
391 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; 390 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
392 client_reg.EventMask =
393 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
394 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
395 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
396 client_reg.event_handler = &sl811_cs_event;
397 client_reg.Version = 0x0210; 391 client_reg.Version = 0x0210;
398 client_reg.event_callback_args.client_data = link; 392 client_reg.event_callback_args.client_data = link;
399 ret = pcmcia_register_client(&link->handle, &client_reg); 393 ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -418,6 +412,7 @@ static struct pcmcia_driver sl811_cs_driver = {
418 .name = (char *)driver_name, 412 .name = (char *)driver_name,
419 }, 413 },
420 .attach = sl811_cs_attach, 414 .attach = sl811_cs_attach,
415 .event = sl811_cs_event,
421 .detach = sl811_cs_detach, 416 .detach = sl811_cs_detach,
422 .id_table = sl811_ids, 417 .id_table = sl811_ids,
423}; 418};
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 7dfbf39b4ed3..ddc9443254d9 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -256,7 +256,7 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf)
256 unsigned int offset = 0, i; 256 unsigned int offset = 0, i;
257 257
258 if (!fb_info->cmap.red || !fb_info->cmap.blue || 258 if (!fb_info->cmap.red || !fb_info->cmap.blue ||
259 fb_info->cmap.green || fb_info->cmap.transp) 259 !fb_info->cmap.green || !fb_info->cmap.transp)
260 return -EINVAL; 260 return -EINVAL;
261 261
262 for (i = 0; i < fb_info->cmap.len; i++) { 262 for (i = 0; i < fb_info->cmap.len; i++) {
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 6ba10e3aceff..3e9ccf370ab2 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -63,5 +63,10 @@ config LOGO_SUPERH_CLUT224
63 depends on LOGO && SUPERH 63 depends on LOGO && SUPERH
64 default y 64 default y
65 65
66config LOGO_M32R_CLUT224
67 bool "224-color M32R Linux logo"
68 depends on LOGO && M32R
69 default y
70
66endmenu 71endmenu
67 72
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
index b0d995020bd1..d0244c04af5a 100644
--- a/drivers/video/logo/Makefile
+++ b/drivers/video/logo/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_LOGO_SUN_CLUT224) += logo_sun_clut224.o
12obj-$(CONFIG_LOGO_SUPERH_MONO) += logo_superh_mono.o 12obj-$(CONFIG_LOGO_SUPERH_MONO) += logo_superh_mono.o
13obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o 13obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o
14obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o 14obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o
15obj-$(CONFIG_LOGO_M32R_CLUT224) += logo_m32r_clut224.o
15 16
16# How to generate logo's 17# How to generate logo's
17 18
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 77b622075001..788fa812c871 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -33,6 +33,7 @@ extern const struct linux_logo logo_sun_clut224;
33extern const struct linux_logo logo_superh_mono; 33extern const struct linux_logo logo_superh_mono;
34extern const struct linux_logo logo_superh_vga16; 34extern const struct linux_logo logo_superh_vga16;
35extern const struct linux_logo logo_superh_clut224; 35extern const struct linux_logo logo_superh_clut224;
36extern const struct linux_logo logo_m32r_clut224;
36 37
37 38
38const struct linux_logo *fb_find_logo(int depth) 39const struct linux_logo *fb_find_logo(int depth)
@@ -97,6 +98,10 @@ const struct linux_logo *fb_find_logo(int depth)
97 /* SuperH Linux logo */ 98 /* SuperH Linux logo */
98 logo = &logo_superh_clut224; 99 logo = &logo_superh_clut224;
99#endif 100#endif
101#ifdef CONFIG_LOGO_M32R_CLUT224
102 /* M32R Linux logo */
103 logo = &logo_m32r_clut224;
104#endif
100 } 105 }
101 return logo; 106 return logo;
102} 107}
diff --git a/drivers/video/logo/logo_m32r_clut224.ppm b/drivers/video/logo/logo_m32r_clut224.ppm
new file mode 100644
index 000000000000..8b2983c5a0bd
--- /dev/null
+++ b/drivers/video/logo/logo_m32r_clut224.ppm
@@ -0,0 +1,1292 @@
1P3
2# CREATOR: The GIMP's PNM Filter Version 1.0
3#
4# Note: how to convert ppm to pnm(ascii).
5# $ convert -posterize 224 m32r.ppm - | pnm2asc -f5 >logo_m32r_clut224.ppm
6#
7# convert - imagemagick: /usr/bin/convert
8# pnm2asc - pnm to ascii-pnm format converter
9# http://www.is.aist.go.jp/etlcdb/util/p2a.htm#English
10
1180 80
12255
13 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
14 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
15 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
16 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
17 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
18 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
19 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
20 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
21 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
22 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
23 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
24 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
25 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
26 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
27 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
28 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
29 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
30 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
31 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
32 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
33 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
34 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
35 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
36 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
37 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
38 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
39 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
40 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
41 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
42 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
43 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
44 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
45 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
46 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
47 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
48 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
49 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
50 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
51 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
52 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
53 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
54 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
55 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
56 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
57 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
58 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
59 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
60 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
61 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
62 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
63 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
64 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
65 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
66 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
67 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
68 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
69 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
70 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
71 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
72 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
73 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
74 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
75 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
76 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
77 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
78 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
79 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
80 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
81 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
82 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
83 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
84 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
85 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
86 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
87 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
88 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
89 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
90 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
91 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
92 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
93 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
94 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
95 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
96 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
97 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
98 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
99 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
100 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
101 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
102 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
103 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
104 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
105 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
106 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
107 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
108 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
109 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
110 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
111 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
112 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
113 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
114 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
115 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
116 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
117 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
118 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
119 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
120 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
121 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
122 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
123 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
124 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
125 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
126 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
127 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
128 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
129 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
130 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
131 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
132 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
133 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
134 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
135 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
136 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
137 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
138 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
139 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
140 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
141 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
142 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
143 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
144 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
145 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
146 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
147 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
148 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
149 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
150 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
151 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
152 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
153 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
154 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
155 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
156 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
157 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
158 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
159 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
160 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
161 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
162 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
163 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
164 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
165 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
166 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
167 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
168 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
169 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
170 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
171 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
172 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
173 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
174 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
175 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
176 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
177 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
178 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
179 215 150 13 2 2 3 2 2 3 2 2 3 2 2 3
180 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
181 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
182 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
183 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
184 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
185 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
186 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
187 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
188 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
189 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
190 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
191 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
192 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
193 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
194 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
195 215 150 13 2 2 3 2 2 3 2 2 3 2 2 3
196 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
197 2 2 3 43 43 43 75 75 75 27 27 27 2 2 3
198 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
199 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
200 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
201 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
202 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
203 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
204 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
205 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
206 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
207 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
208 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
209 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
210 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
211 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
212 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
213 2 2 3 59 59 59 123 123 123 67 67 67 27 27 27
214 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
215 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
216 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
217 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
218 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
219 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
220 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
221 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
222 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
223 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
224 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
225 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
226 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
227 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
228 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
229 10 6 3 59 59 59 80 80 80 43 43 43 27 27 27
230 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
231 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
232 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
233 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
234 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
235 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
236 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
237 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
238 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
239 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
240 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
241 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
242 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
243 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
244 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
245 2 2 3 19 19 19 2 2 3 2 2 3 2 2 3
246 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
247 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
248 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
249 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
250 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
251 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
252 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
253 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
254 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
255 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
256 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
257 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
258 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
259 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
260 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
261 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
262 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
263 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
264 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
265 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
266 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
267 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
268 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
269 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
270 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
271 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
272 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
273 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
274 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
275 2 2 3 2 2 3 10 6 3 10 6 3 2 2 3
276 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
277 10 6 3 11 11 11 11 11 11 2 2 3 2 2 3
278 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
279 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
280 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
281 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
282 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
283 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
284 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
285 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
286 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
287 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
288 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
289 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
290 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
291 2 2 3 2 2 3 2 2 3 27 27 27 10 6 3
292 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
293 19 19 19 2 2 3 2 2 3 51 51 51 2 2 3
294 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
295 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
296 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
297 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
298 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
299 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
300 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
301 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
302 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
303 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
304 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
305 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
306 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
307 2 2 3 123 123 123 196 196 196 115 115 115 2 2 3
308 2 2 3 2 2 3 2 2 3 75 75 75 141 141 140
309 172 172 172 196 196 196 190 189 188 2 2 3 11 11 11
310 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
311 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
312 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
313 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
314 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
315 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
316 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
317 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
318 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
319 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
320 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
321 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
322 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
323 27 27 27 164 164 164 228 228 228 221 221 220 10 6 3
324 2 2 3 2 2 3 2 2 3 172 172 172 245 245 245
325 254 254 252 254 254 252 221 221 220 35 35 35 2 2 3
326 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
327 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
328 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
329 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
330 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
331 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
332 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
333 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
334 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
335 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
336 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
337 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
338 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
339 164 164 164 228 228 228 35 35 35 236 236 236 236 236 236
340 2 2 3 11 11 11 2 2 3 254 254 252 245 245 245
341 2 2 3 75 75 75 245 245 245 245 245 245 2 2 3
342 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
343 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
344 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
345 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
346 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
347 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
348 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
349 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
350 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
351 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
352 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
353 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
354 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
355 212 212 212 2 2 3 51 51 51 11 11 11 245 245 245
356 27 27 27 80 80 80 10 6 3 254 254 252 2 2 3
357 2 2 3 91 91 91 19 19 19 254 254 252 2 2 3
358 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
359 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
360 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
361 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
362 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
363 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
364 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
365 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
366 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
367 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
368 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
369 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
370 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
371 196 196 196 10 6 3 2 2 3 11 11 11 107 107 107
372 49 35 5 57 42 11 31 22 3 236 236 236 2 2 3
373 2 2 3 2 2 3 2 2 3 254 254 252 2 2 3
374 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
375 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
376 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
377 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
378 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
379 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
380 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
381 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
382 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
383 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
384 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
385 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
386 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
387 107 107 107 221 221 220 2 2 3 64 43 7 194 148 10
388 236 188 10 225 180 10 170 126 10 236 188 10 94 86 67
389 2 2 3 2 2 3 204 204 204 236 236 236 2 2 3
390 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
391 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
392 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
393 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
394 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
395 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
396 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
397 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
398 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
399 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
400 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
401 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
402 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
403 2 2 3 228 228 228 182 126 10 218 164 9 236 188 10
404 236 188 10 237 204 14 236 205 40 246 214 48 246 214 48
405 245 189 11 209 156 9 196 196 196 11 11 11 2 2 3
406 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
407 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
408 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
409 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
410 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
411 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
412 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
413 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
414 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
415 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
416 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
417 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
418 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
419 2 2 3 165 114 10 207 148 7 229 172 9 236 180 10
420 236 196 11 237 204 14 242 218 43 246 218 75 246 218 19
421 246 213 13 246 218 19 244 205 11 218 164 9 2 2 3
422 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
423 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
424 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
425 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
426 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
427 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
428 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
429 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
430 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
431 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
432 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
433 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
434 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
435 164 109 5 192 133 7 224 165 9 236 180 10 236 188 10
436 236 196 11 241 212 42 246 218 75 246 218 19 246 218 19
437 246 218 19 236 196 11 150 114 10 229 172 9 2 2 3
438 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
439 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
440 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
441 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
442 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
443 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
444 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
445 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
446 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
447 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
448 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
449 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
450 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
451 165 114 10 201 142 7 229 172 9 242 182 11 236 188 10
452 237 204 14 245 213 67 246 218 19 246 213 13 246 213 13
453 154 119 10 207 148 7 218 164 9 216 156 8 2 2 3
454 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
455 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
456 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
457 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
458 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
459 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
460 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
461 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
462 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
463 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
464 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
465 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
466 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
467 2 2 3 120 78 3 225 180 10 245 189 11 236 205 40
468 241 212 42 241 212 17 237 204 14 148 107 9 182 126 10
469 216 156 8 218 164 9 207 148 7 82 70 43 2 2 3
470 2 2 3 123 123 123 35 35 35 2 2 3 2 2 3
471 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
472 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
473 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
474 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
475 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
476 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
477 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
478 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
479 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
480 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
481 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
482 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
483 10 6 3 180 180 180 156 102 5 135 88 5 142 106 7
484 126 98 11 165 114 10 185 132 9 207 148 7 215 150 13
485 199 140 8 188 148 71 196 196 196 190 189 188 2 2 3
486 2 2 3 11 11 11 132 132 132 75 75 75 2 2 3
487 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
488 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
489 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
490 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
491 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
492 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
493 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
494 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
495 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
496 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
497 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
498 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
499 10 6 3 190 189 188 190 189 188 151 97 5 192 133 7
500 207 148 7 206 142 8 199 140 8 180 121 7 180 132 31
501 190 189 188 190 189 188 212 212 212 212 212 212 107 107 107
502 2 2 3 2 2 3 99 99 99 51 51 51 2 2 3
503 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
504 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
505 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
506 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
507 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
508 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
509 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
510 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
511 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
512 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
513 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
514 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
515 2 2 3 190 189 188 190 189 188 190 189 188 136 95 7
516 151 97 5 151 97 5 151 97 5 183 156 91 190 189 188
517 190 189 188 228 228 228 254 254 252 254 254 252 221 221 220
518 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
519 2 2 3 10 6 3 215 150 13 215 150 13 215 150 13
520 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
521 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
522 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
523 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
524 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
525 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
526 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
527 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
528 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
529 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
530 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
531 75 75 75 245 245 245 196 196 196 190 189 188 190 189 188
532 190 189 188 196 196 196 190 189 188 190 189 188 204 204 204
533 236 236 236 254 254 252 254 254 252 254 254 252 254 254 252
534 35 35 35 2 2 3 2 2 3 2 2 3 2 2 3
535 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
536 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
537 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
538 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
539 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
540 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
541 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
542 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
543 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
544 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
545 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
546 215 150 13 215 150 13 2 2 3 27 27 27 2 2 3
547 245 245 245 254 254 252 245 245 245 190 189 188 190 189 188
548 190 189 188 190 189 188 190 189 188 212 212 212 245 245 245
549 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
550 254 254 252 10 6 3 2 2 3 2 2 3 2 2 3
551 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
552 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
553 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
554 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
555 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
556 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
557 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
558 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
559 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
560 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
561 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
562 215 150 13 215 150 13 2 2 3 2 2 3 132 132 132
563 254 254 252 254 254 252 254 254 252 236 236 236 196 196 196
564 190 189 188 204 204 204 245 245 245 245 245 245 254 254 252
565 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
566 254 254 252 80 80 80 2 2 3 2 2 3 2 2 3
567 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
568 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
569 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
570 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
571 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
572 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
573 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
574 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
575 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
576 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
577 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
578 215 150 13 2 2 3 2 2 3 2 2 3 254 254 252
579 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
580 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
581 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
582 254 254 252 254 254 252 2 2 3 2 2 3 2 2 3
583 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
584 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
585 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
586 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
587 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
588 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
589 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
590 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
591 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
592 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
593 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
594 2 2 3 2 2 3 2 2 3 212 212 212 245 245 245
595 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
596 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
597 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
598 254 254 252 254 254 252 2 2 3 2 2 3 2 2 3
599 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
600 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
601 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
602 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
603 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
604 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
605 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
606 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
607 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
608 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
609 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
610 2 2 3 2 2 3 2 2 3 204 204 204 245 245 245
611 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
612 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
613 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
614 245 245 245 236 236 236 2 2 3 2 2 3 2 2 3
615 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
616 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
617 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
618 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
619 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
620 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
621 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
622 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
623 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
624 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
625 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
626 2 2 3 2 2 3 11 11 11 164 164 164 212 212 212
627 236 236 236 245 245 245 254 254 252 236 236 236 221 221 220
628 221 221 220 228 228 228 245 245 245 245 245 245 245 245 245
629 236 236 236 221 221 220 212 212 212 204 204 204 204 204 204
630 196 196 196 204 204 204 59 59 59 2 2 3 2 2 3
631 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
632 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
633 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
634 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
635 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
636 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
637 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
638 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
639 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
640 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
641 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
642 2 2 3 2 2 3 27 27 27 172 172 172 212 212 212
643 236 236 236 254 254 252 254 254 252 254 254 252 228 228 228
644 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
645 254 254 252 245 245 245 221 221 220 204 204 204 196 196 196
646 196 196 196 196 196 196 228 228 228 19 19 19 2 2 3
647 80 80 80 2 2 3 2 2 3 2 2 3 2 2 3
648 2 2 3 2 2 3 215 150 13 215 150 13 215 150 13
649 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
650 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
651 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
652 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
653 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
654 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
655 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
656 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
657 215 150 13 215 150 13 2 2 3 2 2 3 2 2 3
658 11 11 11 2 2 3 164 164 164 236 236 236 254 254 252
659 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
660 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
661 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
662 236 236 236 212 212 212 196 196 196 245 245 245 2 2 3
663 2 2 3 11 11 11 51 51 51 2 2 3 2 2 3
664 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
665 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
666 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
667 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
668 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
669 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
670 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
671 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
672 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
673 215 150 13 215 150 13 2 2 3 2 2 3 86 86 83
674 2 2 3 27 27 27 236 236 236 254 254 252 254 254 252
675 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
676 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
677 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
678 254 254 252 254 254 252 212 212 212 196 196 196 91 91 91
679 2 2 3 2 2 3 2 2 3 11 11 11 2 2 3
680 2 2 3 2 2 3 2 2 3 215 150 13 215 150 13
681 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
682 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
683 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
684 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
685 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
686 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
687 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
688 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
689 215 150 13 215 150 13 2 2 3 2 2 3 2 2 3
690 2 2 3 245 245 245 254 254 252 254 254 252 254 254 252
691 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
692 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
693 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
694 254 254 252 254 254 252 254 254 252 221 221 220 245 245 245
695 2 2 3 11 11 11 43 43 43 19 19 19 10 6 3
696 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
697 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
698 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
699 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
700 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
701 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
702 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
703 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
704 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
705 215 150 13 215 150 13 2 2 3 80 80 80 2 2 3
706 2 2 3 254 254 252 254 254 252 254 254 252 254 254 252
707 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
708 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
709 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
710 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
711 43 43 43 27 27 27 80 80 80 19 19 19 80 80 80
712 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
713 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
714 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
715 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
716 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
717 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
718 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
719 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
720 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
721 215 150 13 2 2 3 2 2 3 2 2 3 2 2 3
722 245 245 245 254 254 252 254 254 252 17 11 233 254 254 252
723 254 254 252 254 254 252 254 254 252 236 236 236 17 11 233
724 17 11 233 254 254 252 254 254 252 254 254 252 254 254 252
725 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
726 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
727 254 254 252 11 11 11 11 11 11 2 2 3 2 2 3
728 2 2 3 2 2 3 2 2 3 2 2 3 215 150 13
729 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
730 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
731 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
732 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
733 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
734 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
735 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
736 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
737 215 150 13 2 2 3 67 67 67 2 2 3 19 19 19
738 254 254 252 254 254 252 245 245 245 17 11 233 245 245 245
739 254 254 252 254 254 252 17 11 233 228 228 228 17 11 233
740 17 11 233 17 11 233 17 11 233 254 254 252 17 11 233
741 17 11 233 254 254 252 254 254 252 17 11 233 17 11 233
742 17 11 233 254 254 252 254 254 252 254 254 252 254 254 252
743 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
744 11 11 11 2 2 3 2 2 3 2 2 3 2 2 3
745 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
746 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
747 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
748 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
749 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
750 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
751 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
752 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
753 2 2 3 10 6 3 11 11 11 2 2 3 228 228 228
754 254 254 252 254 254 252 254 254 252 17 11 233 254 254 252
755 254 254 252 17 11 233 17 11 233 17 11 233 245 245 245
756 254 254 252 254 254 252 17 11 233 17 11 233 17 11 233
757 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
758 17 11 233 17 11 233 254 254 252 254 254 252 254 254 252
759 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
760 27 27 27 2 2 3 2 2 3 2 2 3 2 2 3
761 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
762 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
763 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
764 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
765 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
766 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
767 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
768 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
769 2 2 3 2 2 3 2 2 3 2 2 3 254 254 252
770 254 254 252 254 254 252 254 254 252 17 11 233 17 11 233
771 17 11 233 17 11 233 17 11 233 17 11 233 254 254 252
772 17 11 233 17 11 233 17 11 233 254 254 252 254 254 252
773 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
774 254 254 252 17 11 233 254 254 252 254 254 252 254 254 252
775 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
776 11 11 11 2 2 3 2 2 3 2 2 3 2 2 3
777 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
778 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
779 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
780 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
781 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
782 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
783 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
784 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
785 2 2 3 19 19 19 2 2 3 2 2 3 254 254 252
786 254 254 252 254 254 252 17 11 233 245 245 245 17 11 233
787 17 11 233 245 245 245 254 254 252 17 11 233 254 254 252
788 17 11 233 17 11 233 17 11 233 254 254 252 254 254 252
789 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
790 17 11 233 17 11 233 254 254 252 254 254 252 254 254 252
791 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
792 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
793 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
794 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
795 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
796 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
797 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
798 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
799 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
800 215 150 13 215 150 13 215 150 13 215 150 13 2 2 3
801 2 2 3 19 19 19 2 2 3 19 19 19 254 254 252
802 254 254 252 245 245 245 17 11 233 254 254 252 17 11 233
803 17 11 233 254 254 252 254 254 252 17 11 233 254 254 252
804 254 254 252 254 254 252 17 11 233 17 11 233 254 254 252
805 17 11 233 17 11 233 254 254 252 17 11 233 17 11 233
806 17 11 233 17 11 233 17 11 233 254 254 252 254 254 252
807 254 254 252 2 2 3 2 2 3 2 2 3 2 2 3
808 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
809 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
810 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
811 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
812 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
813 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
814 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
815 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
816 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
817 2 2 3 43 43 43 2 2 3 43 43 43 254 254 252
818 245 245 245 254 254 252 17 11 233 254 254 252 17 11 233
819 254 254 252 254 254 252 254 254 252 17 11 233 17 11 233
820 17 11 233 17 11 233 17 11 233 254 254 252 17 11 233
821 17 11 233 17 11 233 17 11 233 17 11 233 17 11 233
822 245 245 245 254 254 252 17 11 233 254 254 252 254 254 252
823 245 245 245 2 2 3 2 2 3 2 2 3 11 11 11
824 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
825 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
826 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
827 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
828 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
829 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
830 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
831 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
832 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
833 2 2 3 75 75 75 2 2 3 99 99 99 254 254 252
834 254 254 252 254 254 252 17 11 233 254 254 252 254 254 252
835 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
836 254 254 252 17 11 233 245 245 245 254 254 252 254 254 252
837 254 254 252 254 254 252 254 254 252 17 11 233 17 11 233
838 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
839 254 254 252 2 2 3 2 2 3 2 2 3 75 75 75
840 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
841 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
842 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
843 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
844 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
845 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
846 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
847 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
848 215 150 13 215 150 13 215 150 13 2 2 3 2 2 3
849 2 2 3 2 2 3 11 11 11 107 107 107 254 254 252
850 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
851 245 245 245 254 254 252 245 245 245 236 236 236 254 254 252
852 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
853 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
854 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
855 254 254 252 2 2 3 2 2 3 11 11 11 19 19 19
856 11 11 11 2 2 3 2 2 3 2 2 3 2 2 3
857 2 2 3 215 150 13 215 150 13 215 150 13 215 150 13
858 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
859 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
860 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
861 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
862 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
863 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
864 215 150 13 215 150 13 215 150 13 2 2 3 11 11 11
865 140 102 3 11 11 11 10 6 3 67 67 67 254 254 252
866 245 245 245 245 245 245 254 254 252 254 254 252 245 245 245
867 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
868 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
869 254 254 252 245 245 245 254 254 252 254 254 252 245 245 245
870 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
871 254 254 252 2 2 3 43 43 43 2 2 3 2 2 3
872 2 2 3 11 11 11 67 67 67 11 11 11 2 2 3
873 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
874 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
875 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
876 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
877 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
878 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
879 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
880 215 150 13 215 150 13 215 150 13 185 132 9 242 182 11
881 245 189 11 245 189 11 49 35 5 2 2 3 228 228 228
882 254 254 252 254 254 252 254 254 252 245 245 245 254 254 252
883 254 254 252 254 254 252 254 254 252 228 228 228 245 245 245
884 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
885 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
886 254 254 252 254 254 252 254 254 252 245 238 222 232 189 94
887 226 186 99 43 43 43 2 2 3 2 2 3 2 2 3
888 2 2 3 2 2 3 2 2 3 59 59 59 2 2 3
889 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
890 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
891 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
892 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
893 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
894 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
895 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
896 215 150 13 215 150 13 215 150 13 216 156 8 236 180 22
897 245 189 11 245 189 11 245 189 11 49 35 5 11 11 11
898 212 212 212 245 245 245 254 254 252 254 254 252 254 254 252
899 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
900 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
901 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
902 245 245 245 254 254 252 254 254 252 229 172 9 246 218 19
903 246 218 19 41 27 3 2 2 3 2 2 3 2 2 3
904 2 2 3 2 2 3 19 19 19 27 27 27 196 154 14
905 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
906 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
907 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
908 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
909 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
910 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
911 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
912 215 150 13 215 150 13 199 140 8 229 172 9 242 182 11
913 245 189 11 245 189 11 245 189 11 244 196 10 2 2 3
914 2 2 3 115 115 115 254 254 252 254 254 252 254 254 252
915 254 254 252 254 254 252 245 245 245 228 228 228 254 254 252
916 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
917 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
918 254 254 252 254 254 252 254 254 252 224 165 9 245 189 11
919 236 196 11 19 19 19 2 2 3 2 2 3 2 2 3
920 2 2 3 2 2 3 2 2 3 11 11 11 236 196 11
921 244 205 11 215 150 13 215 150 13 215 150 13 215 150 13
922 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
923 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
924 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
925 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
926 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
927 215 150 13 215 150 13 182 126 10 209 156 9 215 150 13
928 193 140 10 207 148 24 216 156 8 242 182 11 245 189 11
929 245 189 11 245 189 11 245 189 11 245 189 11 209 156 9
930 2 2 3 2 2 3 43 43 43 254 254 252 254 254 252
931 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
932 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
933 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
934 254 254 252 254 254 252 236 236 236 216 156 8 245 189 11
935 229 172 9 64 43 7 2 2 3 2 2 3 2 2 3
936 2 2 3 2 2 3 2 2 3 207 148 7 236 188 10
937 245 189 11 215 150 13 215 150 13 215 150 13 215 150 13
938 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
939 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
940 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
941 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
942 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
943 215 150 13 180 121 7 216 156 8 242 182 11 236 180 10
944 229 172 9 242 182 11 242 182 11 245 189 11 245 189 11
945 245 189 11 245 189 11 245 189 11 245 189 11 237 204 14
946 170 126 10 2 2 3 2 2 3 11 11 11 236 236 236
947 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
948 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
949 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
950 254 254 252 204 204 204 196 196 196 216 156 8 236 180 10
951 224 165 9 182 126 10 73 48 6 2 2 3 2 2 3
952 2 2 3 41 27 3 199 140 8 229 172 9 236 180 10
953 245 189 11 215 150 13 215 150 13 215 150 13 215 150 13
954 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
955 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
956 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
957 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
958 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
959 215 150 13 185 132 9 229 172 9 245 189 11 245 189 11
960 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
961 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
962 226 188 11 2 2 3 2 2 3 2 2 3 11 11 11
963 245 245 245 254 254 252 254 254 252 254 254 252 254 254 252
964 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
965 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
966 254 254 252 196 196 196 196 196 196 215 150 13 236 180 10
967 229 172 9 201 142 7 185 132 9 180 121 7 173 120 10
968 180 121 7 192 133 7 229 172 9 242 182 11 245 189 11
969 245 189 11 215 150 13 215 150 13 215 150 13 215 150 13
970 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
971 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
972 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
973 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
974 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
975 215 150 13 180 126 47 224 165 9 245 189 11 245 189 11
976 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
977 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
978 236 188 10 193 140 10 2 2 3 2 2 3 2 2 3
979 2 2 3 212 212 212 254 254 252 245 245 245 245 245 245
980 254 254 252 254 254 252 254 254 252 245 245 245 254 254 252
981 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
982 254 254 252 204 204 204 196 196 196 199 140 8 229 172 9
983 236 180 10 218 164 9 215 150 13 207 148 7 207 148 7
984 216 156 8 229 172 9 245 189 11 245 189 11 245 189 11
985 245 189 11 242 182 11 215 150 13 215 150 13 215 150 13
986 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
987 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
988 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
989 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
990 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
991 215 150 13 185 132 9 216 156 8 242 182 11 245 189 11
992 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
993 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
994 245 189 11 236 196 11 19 19 19 2 2 3 2 2 3
995 2 2 3 11 11 11 254 254 252 254 254 252 254 254 252
996 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
997 254 254 252 254 254 252 245 245 245 254 254 252 254 254 252
998 245 245 245 221 221 220 196 196 196 185 132 9 229 172 9
999 242 182 11 229 172 9 224 165 9 218 164 9 224 165 9
1000 229 172 9 236 180 10 245 189 11 245 189 11 245 189 11
1001 245 189 11 236 180 22 242 182 11 215 150 13 215 150 13
1002 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1003 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1004 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1005 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1006 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1007 215 150 13 215 150 13 215 150 13 236 180 22 245 189 11
1008 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1009 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1010 245 189 11 236 188 10 225 180 10 2 2 3 2 2 3
1011 2 2 3 11 11 11 254 254 252 254 254 252 254 254 252
1012 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
1013 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
1014 254 254 252 221 221 220 19 19 19 185 132 9 224 165 9
1015 245 189 11 245 189 11 242 182 11 236 180 10 236 180 10
1016 242 182 11 242 182 11 245 189 11 245 189 11 245 189 11
1017 245 189 11 245 189 11 245 189 11 245 189 11 196 154 14
1018 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1019 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1020 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1021 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1022 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1023 215 150 13 215 150 13 207 148 7 236 180 22 245 189 11
1024 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1025 245 189 11 245 189 11 245 189 11 245 189 11 242 182 11
1026 245 189 11 245 189 11 237 204 14 135 88 5 2 2 3
1027 27 27 27 254 254 252 254 254 252 254 254 252 254 254 252
1028 254 254 252 245 245 245 254 254 252 254 254 252 245 245 245
1029 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
1030 254 254 252 67 67 67 19 13 3 185 132 9 229 172 9
1031 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
1032 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1033 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1034 236 180 22 215 150 13 215 150 13 215 150 13 215 150 13
1035 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1036 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1037 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1038 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1039 215 150 13 215 150 13 215 150 13 245 189 11 242 182 11
1040 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
1041 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1042 245 189 11 245 189 11 236 188 10 226 188 11 104 83 48
1043 254 254 252 254 254 252 254 254 252 254 254 252 245 245 245
1044 254 254 252 254 254 252 245 245 245 254 254 252 245 245 245
1045 254 254 252 245 245 245 254 254 252 254 254 252 254 254 252
1046 2 2 3 2 2 3 56 38 5 185 132 9 229 172 9
1047 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1048 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1049 245 189 11 245 189 11 245 189 11 245 189 11 242 182 11
1050 229 172 9 215 150 13 215 150 13 215 150 13 215 150 13
1051 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1052 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1053 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1054 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1055 215 150 13 182 126 10 215 150 13 242 182 11 245 189 11
1056 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1057 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1058 245 189 11 242 182 11 245 189 11 236 196 11 216 156 8
1059 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
1060 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
1061 254 254 252 254 254 252 254 254 252 245 245 245 2 2 3
1062 2 2 3 2 2 3 75 54 3 182 126 10 229 172 9
1063 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
1064 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1065 245 189 11 245 189 11 245 189 11 245 189 11 229 172 9
1066 207 148 24 215 150 13 215 150 13 215 150 13 215 150 13
1067 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1068 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1069 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1070 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1071 215 150 13 192 133 7 229 172 9 242 182 11 245 189 11
1072 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1073 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1074 245 189 11 245 189 11 242 182 11 225 180 10 224 165 9
1075 107 69 5 245 245 245 254 254 252 254 254 252 254 254 252
1076 254 254 252 254 254 252 254 254 252 254 254 252 254 254 252
1077 254 254 252 236 236 236 2 2 3 2 2 3 2 2 3
1078 2 2 3 2 2 3 91 67 9 182 126 10 229 172 9
1079 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1080 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1081 245 189 11 242 182 11 242 182 11 216 156 8 180 126 47
1082 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1083 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1084 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1085 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1086 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1087 215 150 13 206 142 8 224 165 9 245 189 11 242 182 11
1088 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1089 245 189 11 245 189 11 245 189 11 245 189 11 242 182 11
1090 245 189 11 245 189 11 242 182 11 242 182 11 216 156 8
1091 156 102 5 19 13 3 43 43 43 196 196 196 254 254 252
1092 245 245 245 254 254 252 254 254 252 204 204 204 51 51 51
1093 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
1094 2 2 3 2 2 3 95 62 5 185 132 9 229 172 9
1095 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
1096 245 189 11 245 189 11 242 182 11 245 189 11 245 189 11
1097 236 180 22 216 156 8 206 142 8 215 150 13 215 150 13
1098 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1099 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1100 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1101 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1102 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1103 215 150 13 192 133 7 215 150 13 229 172 9 229 172 9
1104 236 180 10 236 180 22 242 182 11 242 182 11 245 189 11
1105 245 189 11 245 189 11 245 189 11 245 189 11 245 189 11
1106 245 189 11 245 189 11 245 189 11 229 172 9 216 156 8
1107 156 102 5 83 54 6 2 2 3 2 2 3 2 2 3
1108 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
1109 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
1110 2 2 3 2 2 3 115 73 3 185 132 9 229 172 9
1111 242 182 11 245 189 11 245 189 11 245 189 11 245 189 11
1112 245 189 11 242 182 11 229 172 9 229 172 9 216 156 8
1113 180 121 7 215 150 13 215 150 13 215 150 13 215 150 13
1114 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1115 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1116 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1117 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1118 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1119 215 150 13 180 121 7 182 126 10 192 133 7 199 140 8
1120 207 148 7 215 150 13 216 156 8 224 165 9 229 172 9
1121 236 180 22 245 189 11 242 182 11 245 189 11 242 182 11
1122 245 189 11 245 189 11 242 182 11 229 172 9 199 140 8
1123 151 97 5 101 67 7 2 2 3 2 2 3 2 2 3
1124 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
1125 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
1126 2 2 3 2 2 3 115 73 3 180 121 7 216 156 8
1127 236 180 22 242 182 11 245 189 11 245 189 11 242 182 11
1128 236 180 10 224 165 9 215 150 13 206 142 8 215 150 13
1129 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1130 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1131 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1132 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1133 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1134 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1135 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1136 156 102 5 164 109 5 172 114 5 180 121 7 180 121 7
1137 192 133 7 201 142 7 216 156 8 224 165 9 236 180 22
1138 245 189 11 242 182 11 229 172 9 201 142 7 172 114 5
1139 125 83 5 83 54 6 2 2 3 2 2 3 2 2 3
1140 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
1141 2 2 3 2 2 3 2 2 3 2 2 3 2 2 3
1142 2 2 3 2 2 3 91 58 5 156 102 5 192 133 7
1143 216 156 8 229 172 9 236 180 10 236 180 10 229 172 9
1144 215 150 13 199 140 8 164 109 5 215 150 13 215 150 13
1145 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1146 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1147 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1148 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1149 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1150 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1151 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1152 215 150 13 215 150 13 215 150 13 120 78 3 132 82 3
1153 151 97 5 157 106 7 180 121 7 185 132 9 193 140 10
1154 207 148 7 207 148 7 192 133 7 172 114 5 132 82 3
1155 101 67 7 41 27 3 215 150 13 215 150 13 215 150 13
1156 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1157 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1158 215 150 13 215 150 13 73 48 6 143 90 3 180 121 7
1159 192 133 7 207 148 7 207 148 7 201 142 7 185 132 9
1160 173 120 10 136 95 7 215 150 13 215 150 13 215 150 13
1161 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1162 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1163 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1164 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1165 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1166 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1167 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1168 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1169 215 150 13 215 150 13 91 58 5 125 83 5 135 88 5
1170 144 95 7 151 97 5 132 82 3 115 73 3 95 62 5
1171 64 43 7 215 150 13 215 150 13 215 150 13 215 150 13
1172 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1173 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1174 215 150 13 215 150 13 64 43 7 91 58 5 151 97 5
1175 157 106 7 172 114 5 172 114 5 164 109 5 151 97 5
1176 85 59 6 215 150 13 215 150 13 215 150 13 215 150 13
1177 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1178 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1179 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1180 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1181 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1182 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1183 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1184 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1185 215 150 13 215 150 13 215 150 13 215 150 13 73 48 6
1186 91 58 5 95 62 5 95 62 5 91 58 5 56 38 5
1187 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1188 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1189 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1190 215 150 13 215 150 13 215 150 13 215 150 13 83 54 6
1191 107 69 5 132 82 3 125 83 5 101 67 7 71 47 31
1192 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1193 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1194 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1195 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1196 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1197 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1198 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1199 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1200 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1201 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1202 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1203 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1204 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1205 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1206 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1207 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1208 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1209 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1210 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1211 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1212 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1213 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1214 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1215 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1216 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1217 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1218 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1219 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1220 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1221 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1222 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1223 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1224 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1225 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1226 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1227 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1228 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1229 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1230 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1231 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1232 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1233 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1234 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1235 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1236 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1237 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1238 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1239 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1240 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1241 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1242 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1243 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1244 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1245 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1246 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1247 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1248 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1249 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1250 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1251 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1252 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1253 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1254 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1255 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1256 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1257 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1258 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1259 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1260 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1261 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1262 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1263 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1264 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1265 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1266 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1267 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1268 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1269 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1270 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1271 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1272 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1273 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1274 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1275 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1276 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1277 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1278 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1279 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1280 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1281 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1282 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1283 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1284 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1285 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1286 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1287 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1288 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1289 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1290 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1291 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
1292 215 150 13 215 150 13 215 150 13 215 150 13 215 150 13
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index 789de13f461f..3848be2b9d2d 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -67,12 +67,18 @@ static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = {
67static inline u8 67static inline u8
68s1d13xxxfb_readreg(struct s1d13xxxfb_par *par, u16 regno) 68s1d13xxxfb_readreg(struct s1d13xxxfb_par *par, u16 regno)
69{ 69{
70#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
71 regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
72#endif
70 return readb(par->regs + regno); 73 return readb(par->regs + regno);
71} 74}
72 75
73static inline void 76static inline void
74s1d13xxxfb_writereg(struct s1d13xxxfb_par *par, u16 regno, u8 value) 77s1d13xxxfb_writereg(struct s1d13xxxfb_par *par, u16 regno, u8 value)
75{ 78{
79#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
80 regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
81#endif
76 writeb(value, par->regs + regno); 82 writeb(value, par->regs + regno);
77} 83}
78 84
@@ -259,7 +265,11 @@ s1d13xxxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
259 dbg("s1d13xxxfb_setcolreg: pseudo %d, val %08x\n", 265 dbg("s1d13xxxfb_setcolreg: pseudo %d, val %08x\n",
260 regno, pseudo_val); 266 regno, pseudo_val);
261 267
268#if defined(CONFIG_PLAT_MAPPI)
269 ((u32 *)info->pseudo_palette)[regno] = cpu_to_le16(pseudo_val);
270#else
262 ((u32 *)info->pseudo_palette)[regno] = pseudo_val; 271 ((u32 *)info->pseudo_palette)[regno] = pseudo_val;
272#endif
263 273
264 break; 274 break;
265 case FB_VISUAL_PSEUDOCOLOR: 275 case FB_VISUAL_PSEUDOCOLOR:
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 8fadcdae6f42..f4633d1891f1 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -2113,7 +2113,7 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state)
2113 printk(KERN_DEBUG "state: %u\n", state); 2113 printk(KERN_DEBUG "state: %u\n", state);
2114 2114
2115 acquire_console_sem(); 2115 acquire_console_sem();
2116 fb_set_suspend(info, state); 2116 fb_set_suspend(info, pci_choose_state(dev, state));
2117 savage_disable_mmio(par); 2117 savage_disable_mmio(par);
2118 release_console_sem(); 2118 release_console_sem();
2119 2119
diff --git a/fs/Kconfig b/fs/Kconfig
index 062177956239..aae0686a15fb 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -29,6 +29,7 @@ config EXT2_FS_XATTR
29config EXT2_FS_POSIX_ACL 29config EXT2_FS_POSIX_ACL
30 bool "Ext2 POSIX Access Control Lists" 30 bool "Ext2 POSIX Access Control Lists"
31 depends on EXT2_FS_XATTR 31 depends on EXT2_FS_XATTR
32 select FS_POSIX_ACL
32 help 33 help
33 Posix Access Control Lists (ACLs) support permissions for users and 34 Posix Access Control Lists (ACLs) support permissions for users and
34 groups beyond the owner/group/world scheme. 35 groups beyond the owner/group/world scheme.
@@ -114,6 +115,7 @@ config EXT3_FS_XATTR
114config EXT3_FS_POSIX_ACL 115config EXT3_FS_POSIX_ACL
115 bool "Ext3 POSIX Access Control Lists" 116 bool "Ext3 POSIX Access Control Lists"
116 depends on EXT3_FS_XATTR 117 depends on EXT3_FS_XATTR
118 select FS_POSIX_ACL
117 help 119 help
118 Posix Access Control Lists (ACLs) support permissions for users and 120 Posix Access Control Lists (ACLs) support permissions for users and
119 groups beyond the owner/group/world scheme. 121 groups beyond the owner/group/world scheme.
@@ -241,6 +243,7 @@ config REISERFS_FS_XATTR
241config REISERFS_FS_POSIX_ACL 243config REISERFS_FS_POSIX_ACL
242 bool "ReiserFS POSIX Access Control Lists" 244 bool "ReiserFS POSIX Access Control Lists"
243 depends on REISERFS_FS_XATTR 245 depends on REISERFS_FS_XATTR
246 select FS_POSIX_ACL
244 help 247 help
245 Posix Access Control Lists (ACLs) support permissions for users and 248 Posix Access Control Lists (ACLs) support permissions for users and
246 groups beyond the owner/group/world scheme. 249 groups beyond the owner/group/world scheme.
@@ -274,6 +277,7 @@ config JFS_FS
274config JFS_POSIX_ACL 277config JFS_POSIX_ACL
275 bool "JFS POSIX Access Control Lists" 278 bool "JFS POSIX Access Control Lists"
276 depends on JFS_FS 279 depends on JFS_FS
280 select FS_POSIX_ACL
277 help 281 help
278 Posix Access Control Lists (ACLs) support permissions for users and 282 Posix Access Control Lists (ACLs) support permissions for users and
279 groups beyond the owner/group/world scheme. 283 groups beyond the owner/group/world scheme.
@@ -318,8 +322,7 @@ config FS_POSIX_ACL
318# Never use this symbol for ifdefs. 322# Never use this symbol for ifdefs.
319# 323#
320 bool 324 bool
321 depends on EXT2_FS_POSIX_ACL || EXT3_FS_POSIX_ACL || JFS_POSIX_ACL || REISERFS_FS_POSIX_ACL || NFSD_V4 325 default n
322 default y
323 326
324source "fs/xfs/Kconfig" 327source "fs/xfs/Kconfig"
325 328
@@ -1438,6 +1441,7 @@ config NFSD_V4
1438 select NFSD_TCP 1441 select NFSD_TCP
1439 select CRYPTO_MD5 1442 select CRYPTO_MD5
1440 select CRYPTO 1443 select CRYPTO
1444 select FS_POSIX_ACL
1441 help 1445 help
1442 If you would like to include the NFSv4 server as well as the NFSv2 1446 If you would like to include the NFSv4 server as well as the NFSv2
1443 and NFSv3 servers, say Y here. This feature is experimental, and 1447 and NFSv3 servers, say Y here. This feature is experimental, and
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index fa2348dcd671..3df86285a1c7 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -231,8 +231,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
231 int type = (notify == NFY_MOUNT ? 231 int type = (notify == NFY_MOUNT ?
232 autofs_ptype_missing : autofs_ptype_expire_multi); 232 autofs_ptype_missing : autofs_ptype_expire_multi);
233 233
234 DPRINTK(("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", 234 DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
235 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify)); 235 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
236 236
237 /* autofs4_notify_daemon() may block */ 237 /* autofs4_notify_daemon() may block */
238 autofs4_notify_daemon(sbi, wq, type); 238 autofs4_notify_daemon(sbi, wq, type);
diff --git a/fs/bio.c b/fs/bio.c
index 3a1472acc361..ca8f7a850fe3 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -52,7 +52,7 @@ struct biovec_slab {
52 */ 52 */
53 53
54#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) } 54#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
55static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] = { 55static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
56 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), 56 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
57}; 57};
58#undef BV 58#undef BV
diff --git a/fs/buffer.c b/fs/buffer.c
index 561e63a14966..6a25d7df89b1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -513,8 +513,8 @@ static void free_more_memory(void)
513 */ 513 */
514static void end_buffer_async_read(struct buffer_head *bh, int uptodate) 514static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
515{ 515{
516 static DEFINE_SPINLOCK(page_uptodate_lock);
517 unsigned long flags; 516 unsigned long flags;
517 struct buffer_head *first;
518 struct buffer_head *tmp; 518 struct buffer_head *tmp;
519 struct page *page; 519 struct page *page;
520 int page_uptodate = 1; 520 int page_uptodate = 1;
@@ -536,7 +536,9 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
536 * two buffer heads end IO at almost the same time and both 536 * two buffer heads end IO at almost the same time and both
537 * decide that the page is now completely done. 537 * decide that the page is now completely done.
538 */ 538 */
539 spin_lock_irqsave(&page_uptodate_lock, flags); 539 first = page_buffers(page);
540 local_irq_save(flags);
541 bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
540 clear_buffer_async_read(bh); 542 clear_buffer_async_read(bh);
541 unlock_buffer(bh); 543 unlock_buffer(bh);
542 tmp = bh; 544 tmp = bh;
@@ -549,7 +551,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
549 } 551 }
550 tmp = tmp->b_this_page; 552 tmp = tmp->b_this_page;
551 } while (tmp != bh); 553 } while (tmp != bh);
552 spin_unlock_irqrestore(&page_uptodate_lock, flags); 554 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
555 local_irq_restore(flags);
553 556
554 /* 557 /*
555 * If none of the buffers had errors and they are all 558 * If none of the buffers had errors and they are all
@@ -561,7 +564,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
561 return; 564 return;
562 565
563still_busy: 566still_busy:
564 spin_unlock_irqrestore(&page_uptodate_lock, flags); 567 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
568 local_irq_restore(flags);
565 return; 569 return;
566} 570}
567 571
@@ -572,8 +576,8 @@ still_busy:
572void end_buffer_async_write(struct buffer_head *bh, int uptodate) 576void end_buffer_async_write(struct buffer_head *bh, int uptodate)
573{ 577{
574 char b[BDEVNAME_SIZE]; 578 char b[BDEVNAME_SIZE];
575 static DEFINE_SPINLOCK(page_uptodate_lock);
576 unsigned long flags; 579 unsigned long flags;
580 struct buffer_head *first;
577 struct buffer_head *tmp; 581 struct buffer_head *tmp;
578 struct page *page; 582 struct page *page;
579 583
@@ -594,7 +598,10 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
594 SetPageError(page); 598 SetPageError(page);
595 } 599 }
596 600
597 spin_lock_irqsave(&page_uptodate_lock, flags); 601 first = page_buffers(page);
602 local_irq_save(flags);
603 bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
604
598 clear_buffer_async_write(bh); 605 clear_buffer_async_write(bh);
599 unlock_buffer(bh); 606 unlock_buffer(bh);
600 tmp = bh->b_this_page; 607 tmp = bh->b_this_page;
@@ -605,12 +612,14 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
605 } 612 }
606 tmp = tmp->b_this_page; 613 tmp = tmp->b_this_page;
607 } 614 }
608 spin_unlock_irqrestore(&page_uptodate_lock, flags); 615 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
616 local_irq_restore(flags);
609 end_page_writeback(page); 617 end_page_writeback(page);
610 return; 618 return;
611 619
612still_busy: 620still_busy:
613 spin_unlock_irqrestore(&page_uptodate_lock, flags); 621 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
622 local_irq_restore(flags);
614 return; 623 return;
615} 624}
616 625
diff --git a/fs/dcookies.c b/fs/dcookies.c
index 581aac959cd3..02aa0ddc582a 100644
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -94,12 +94,10 @@ static struct dcookie_struct * alloc_dcookie(struct dentry * dentry,
94 if (!dcs) 94 if (!dcs)
95 return NULL; 95 return NULL;
96 96
97 atomic_inc(&dentry->d_count);
98 atomic_inc(&vfsmnt->mnt_count);
99 dentry->d_cookie = dcs; 97 dentry->d_cookie = dcs;
100 98
101 dcs->dentry = dentry; 99 dcs->dentry = dget(dentry);
102 dcs->vfsmnt = vfsmnt; 100 dcs->vfsmnt = mntget(vfsmnt);
103 hash_dcookie(dcs); 101 hash_dcookie(dcs);
104 102
105 return dcs; 103 return dcs;
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 0b2db4f618cb..9989fdcf4d5a 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2663,7 +2663,7 @@ static int ext3_do_update_inode(handle_t *handle,
2663 } else for (block = 0; block < EXT3_N_BLOCKS; block++) 2663 } else for (block = 0; block < EXT3_N_BLOCKS; block++)
2664 raw_inode->i_block[block] = ei->i_data[block]; 2664 raw_inode->i_block[block] = ei->i_data[block];
2665 2665
2666 if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) 2666 if (ei->i_extra_isize)
2667 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 2667 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
2668 2668
2669 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); 2669 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index f8e0cbd0cb60..6f553e17c375 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <linux/fs.h> 6#include <linux/fs.h>
7#include <linux/file.h>
7#include <linux/module.h> 8#include <linux/module.h>
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/slab.h> 10#include <linux/slab.h>
@@ -491,7 +492,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
491 fd = open_host_sock(host_file, &filter); 492 fd = open_host_sock(host_file, &filter);
492 if(fd > 0){ 493 if(fd > 0){
493 data->contents = hppfs_get_data(fd, filter, 494 data->contents = hppfs_get_data(fd, filter,
494 &data->proc_file, 495 data->proc_file,
495 file, &data->len); 496 file, &data->len);
496 if(!IS_ERR(data->contents)) 497 if(!IS_ERR(data->contents))
497 data->host_fd = fd; 498 data->host_fd = fd;
@@ -543,7 +544,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file)
543static loff_t hppfs_llseek(struct file *file, loff_t off, int where) 544static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
544{ 545{
545 struct hppfs_private *data = file->private_data; 546 struct hppfs_private *data = file->private_data;
546 struct file *proc_file = &data->proc_file; 547 struct file *proc_file = data->proc_file;
547 loff_t (*llseek)(struct file *, loff_t, int); 548 loff_t (*llseek)(struct file *, loff_t, int);
548 loff_t ret; 549 loff_t ret;
549 550
@@ -586,7 +587,7 @@ static int hppfs_filldir(void *d, const char *name, int size,
586static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) 587static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
587{ 588{
588 struct hppfs_private *data = file->private_data; 589 struct hppfs_private *data = file->private_data;
589 struct file *proc_file = &data->proc_file; 590 struct file *proc_file = data->proc_file;
590 int (*readdir)(struct file *, void *, filldir_t); 591 int (*readdir)(struct file *, void *, filldir_t);
591 struct hppfs_dirent dirent = ((struct hppfs_dirent) 592 struct hppfs_dirent dirent = ((struct hppfs_dirent)
592 { .vfs_dirent = ent, 593 { .vfs_dirent = ent,
diff --git a/fs/inode.c b/fs/inode.c
index 1f9a3a2b89bc..6d695037a0a3 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1052,7 +1052,7 @@ static void generic_forget_inode(struct inode *inode)
1052 * inode when the usage count drops to zero, and 1052 * inode when the usage count drops to zero, and
1053 * i_nlink is zero. 1053 * i_nlink is zero.
1054 */ 1054 */
1055static void generic_drop_inode(struct inode *inode) 1055void generic_drop_inode(struct inode *inode)
1056{ 1056{
1057 if (!inode->i_nlink) 1057 if (!inode->i_nlink)
1058 generic_delete_inode(inode); 1058 generic_delete_inode(inode);
@@ -1060,6 +1060,8 @@ static void generic_drop_inode(struct inode *inode)
1060 generic_forget_inode(inode); 1060 generic_forget_inode(inode);
1061} 1061}
1062 1062
1063EXPORT_SYMBOL_GPL(generic_drop_inode);
1064
1063/* 1065/*
1064 * Called when we're dropping the last reference 1066 * Called when we're dropping the last reference
1065 * to an inode. 1067 * to an inode.
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 663e420636d6..97e1f088ba00 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -43,7 +43,7 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
43 return 0; 43 return 0;
44} 44}
45 45
46asmlinkage int sys_ioprio_set(int which, int who, int ioprio) 46asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
47{ 47{
48 int class = IOPRIO_PRIO_CLASS(ioprio); 48 int class = IOPRIO_PRIO_CLASS(ioprio);
49 int data = IOPRIO_PRIO_DATA(ioprio); 49 int data = IOPRIO_PRIO_DATA(ioprio);
@@ -115,7 +115,7 @@ asmlinkage int sys_ioprio_set(int which, int who, int ioprio)
115 return ret; 115 return ret;
116} 116}
117 117
118asmlinkage int sys_ioprio_get(int which, int who) 118asmlinkage long sys_ioprio_get(int which, int who)
119{ 119{
120 struct task_struct *g, *p; 120 struct task_struct *g, *p;
121 struct user_struct *user; 121 struct user_struct *user;
diff --git a/fs/locks.c b/fs/locks.c
index a0bc03495bd4..29fa5da6c117 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1276,7 +1276,7 @@ int fcntl_getlease(struct file *filp)
1276 */ 1276 */
1277static int __setlease(struct file *filp, long arg, struct file_lock **flp) 1277static int __setlease(struct file *filp, long arg, struct file_lock **flp)
1278{ 1278{
1279 struct file_lock *fl, **before, **my_before = NULL, *lease = *flp; 1279 struct file_lock *fl, **before, **my_before = NULL, *lease;
1280 struct dentry *dentry = filp->f_dentry; 1280 struct dentry *dentry = filp->f_dentry;
1281 struct inode *inode = dentry->d_inode; 1281 struct inode *inode = dentry->d_inode;
1282 int error, rdlease_count = 0, wrlease_count = 0; 1282 int error, rdlease_count = 0, wrlease_count = 0;
@@ -1287,6 +1287,8 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp)
1287 if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break) 1287 if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break)
1288 goto out; 1288 goto out;
1289 1289
1290 lease = *flp;
1291
1290 error = -EAGAIN; 1292 error = -EAGAIN;
1291 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) 1293 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
1292 goto out; 1294 goto out;
diff --git a/fs/namei.c b/fs/namei.c
index fa8df81ce8ca..1d93cb4f7c5f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -314,7 +314,7 @@ void path_release(struct nameidata *nd)
314void path_release_on_umount(struct nameidata *nd) 314void path_release_on_umount(struct nameidata *nd)
315{ 315{
316 dput(nd->dentry); 316 dput(nd->dentry);
317 _mntput(nd->mnt); 317 mntput_no_expire(nd->mnt);
318} 318}
319 319
320/* 320/*
diff --git a/fs/namespace.c b/fs/namespace.c
index 208c079e9fdb..587eb0d707ee 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -61,7 +61,7 @@ struct vfsmount *alloc_vfsmnt(const char *name)
61 INIT_LIST_HEAD(&mnt->mnt_child); 61 INIT_LIST_HEAD(&mnt->mnt_child);
62 INIT_LIST_HEAD(&mnt->mnt_mounts); 62 INIT_LIST_HEAD(&mnt->mnt_mounts);
63 INIT_LIST_HEAD(&mnt->mnt_list); 63 INIT_LIST_HEAD(&mnt->mnt_list);
64 INIT_LIST_HEAD(&mnt->mnt_fslink); 64 INIT_LIST_HEAD(&mnt->mnt_expire);
65 if (name) { 65 if (name) {
66 int size = strlen(name)+1; 66 int size = strlen(name)+1;
67 char *newname = kmalloc(size, GFP_KERNEL); 67 char *newname = kmalloc(size, GFP_KERNEL);
@@ -165,8 +165,8 @@ clone_mnt(struct vfsmount *old, struct dentry *root)
165 /* stick the duplicate mount on the same expiry list 165 /* stick the duplicate mount on the same expiry list
166 * as the original if that was on one */ 166 * as the original if that was on one */
167 spin_lock(&vfsmount_lock); 167 spin_lock(&vfsmount_lock);
168 if (!list_empty(&old->mnt_fslink)) 168 if (!list_empty(&old->mnt_expire))
169 list_add(&mnt->mnt_fslink, &old->mnt_fslink); 169 list_add(&mnt->mnt_expire, &old->mnt_expire);
170 spin_unlock(&vfsmount_lock); 170 spin_unlock(&vfsmount_lock);
171 } 171 }
172 return mnt; 172 return mnt;
@@ -345,12 +345,13 @@ static void umount_tree(struct vfsmount *mnt)
345 for (p = mnt; p; p = next_mnt(p, mnt)) { 345 for (p = mnt; p; p = next_mnt(p, mnt)) {
346 list_del(&p->mnt_list); 346 list_del(&p->mnt_list);
347 list_add(&p->mnt_list, &kill); 347 list_add(&p->mnt_list, &kill);
348 p->mnt_namespace = NULL;
348 } 349 }
349 350
350 while (!list_empty(&kill)) { 351 while (!list_empty(&kill)) {
351 mnt = list_entry(kill.next, struct vfsmount, mnt_list); 352 mnt = list_entry(kill.next, struct vfsmount, mnt_list);
352 list_del_init(&mnt->mnt_list); 353 list_del_init(&mnt->mnt_list);
353 list_del_init(&mnt->mnt_fslink); 354 list_del_init(&mnt->mnt_expire);
354 if (mnt->mnt_parent == mnt) { 355 if (mnt->mnt_parent == mnt) {
355 spin_unlock(&vfsmount_lock); 356 spin_unlock(&vfsmount_lock);
356 } else { 357 } else {
@@ -644,7 +645,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
644 if (mnt) { 645 if (mnt) {
645 /* stop bind mounts from expiring */ 646 /* stop bind mounts from expiring */
646 spin_lock(&vfsmount_lock); 647 spin_lock(&vfsmount_lock);
647 list_del_init(&mnt->mnt_fslink); 648 list_del_init(&mnt->mnt_expire);
648 spin_unlock(&vfsmount_lock); 649 spin_unlock(&vfsmount_lock);
649 650
650 err = graft_tree(mnt, nd); 651 err = graft_tree(mnt, nd);
@@ -743,7 +744,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
743 744
744 /* if the mount is moved, it should no longer be expire 745 /* if the mount is moved, it should no longer be expire
745 * automatically */ 746 * automatically */
746 list_del_init(&old_nd.mnt->mnt_fslink); 747 list_del_init(&old_nd.mnt->mnt_expire);
747out2: 748out2:
748 spin_unlock(&vfsmount_lock); 749 spin_unlock(&vfsmount_lock);
749out1: 750out1:
@@ -807,12 +808,13 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
807 goto unlock; 808 goto unlock;
808 809
809 newmnt->mnt_flags = mnt_flags; 810 newmnt->mnt_flags = mnt_flags;
811 newmnt->mnt_namespace = current->namespace;
810 err = graft_tree(newmnt, nd); 812 err = graft_tree(newmnt, nd);
811 813
812 if (err == 0 && fslist) { 814 if (err == 0 && fslist) {
813 /* add to the specified expiration list */ 815 /* add to the specified expiration list */
814 spin_lock(&vfsmount_lock); 816 spin_lock(&vfsmount_lock);
815 list_add_tail(&newmnt->mnt_fslink, fslist); 817 list_add_tail(&newmnt->mnt_expire, fslist);
816 spin_unlock(&vfsmount_lock); 818 spin_unlock(&vfsmount_lock);
817 } 819 }
818 820
@@ -824,6 +826,54 @@ unlock:
824 826
825EXPORT_SYMBOL_GPL(do_add_mount); 827EXPORT_SYMBOL_GPL(do_add_mount);
826 828
829static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
830{
831 spin_lock(&vfsmount_lock);
832
833 /*
834 * Check if mount is still attached, if not, let whoever holds it deal
835 * with the sucker
836 */
837 if (mnt->mnt_parent == mnt) {
838 spin_unlock(&vfsmount_lock);
839 return;
840 }
841
842 /*
843 * Check that it is still dead: the count should now be 2 - as
844 * contributed by the vfsmount parent and the mntget above
845 */
846 if (atomic_read(&mnt->mnt_count) == 2) {
847 struct nameidata old_nd;
848
849 /* delete from the namespace */
850 list_del_init(&mnt->mnt_list);
851 mnt->mnt_namespace = NULL;
852 detach_mnt(mnt, &old_nd);
853 spin_unlock(&vfsmount_lock);
854 path_release(&old_nd);
855
856 /*
857 * Now lay it to rest if this was the last ref on the superblock
858 */
859 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
860 /* last instance - try to be smart */
861 lock_kernel();
862 DQUOT_OFF(mnt->mnt_sb);
863 acct_auto_close(mnt->mnt_sb);
864 unlock_kernel();
865 }
866 mntput(mnt);
867 } else {
868 /*
869 * Someone brought it back to life whilst we didn't have any
870 * locks held so return it to the expiration list
871 */
872 list_add_tail(&mnt->mnt_expire, mounts);
873 spin_unlock(&vfsmount_lock);
874 }
875}
876
827/* 877/*
828 * process a list of expirable mountpoints with the intent of discarding any 878 * process a list of expirable mountpoints with the intent of discarding any
829 * mountpoints that aren't in use and haven't been touched since last we came 879 * mountpoints that aren't in use and haven't been touched since last we came
@@ -846,13 +896,13 @@ void mark_mounts_for_expiry(struct list_head *mounts)
846 * - still marked for expiry (marked on the last call here; marks are 896 * - still marked for expiry (marked on the last call here; marks are
847 * cleared by mntput()) 897 * cleared by mntput())
848 */ 898 */
849 list_for_each_entry_safe(mnt, next, mounts, mnt_fslink) { 899 list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
850 if (!xchg(&mnt->mnt_expiry_mark, 1) || 900 if (!xchg(&mnt->mnt_expiry_mark, 1) ||
851 atomic_read(&mnt->mnt_count) != 1) 901 atomic_read(&mnt->mnt_count) != 1)
852 continue; 902 continue;
853 903
854 mntget(mnt); 904 mntget(mnt);
855 list_move(&mnt->mnt_fslink, &graveyard); 905 list_move(&mnt->mnt_expire, &graveyard);
856 } 906 }
857 907
858 /* 908 /*
@@ -862,61 +912,19 @@ void mark_mounts_for_expiry(struct list_head *mounts)
862 * - dispose of the corpse 912 * - dispose of the corpse
863 */ 913 */
864 while (!list_empty(&graveyard)) { 914 while (!list_empty(&graveyard)) {
865 mnt = list_entry(graveyard.next, struct vfsmount, mnt_fslink); 915 mnt = list_entry(graveyard.next, struct vfsmount, mnt_expire);
866 list_del_init(&mnt->mnt_fslink); 916 list_del_init(&mnt->mnt_expire);
867 917
868 /* don't do anything if the namespace is dead - all the 918 /* don't do anything if the namespace is dead - all the
869 * vfsmounts from it are going away anyway */ 919 * vfsmounts from it are going away anyway */
870 namespace = mnt->mnt_namespace; 920 namespace = mnt->mnt_namespace;
871 if (!namespace || atomic_read(&namespace->count) <= 0) 921 if (!namespace || !namespace->root)
872 continue; 922 continue;
873 get_namespace(namespace); 923 get_namespace(namespace);
874 924
875 spin_unlock(&vfsmount_lock); 925 spin_unlock(&vfsmount_lock);
876 down_write(&namespace->sem); 926 down_write(&namespace->sem);
877 spin_lock(&vfsmount_lock); 927 expire_mount(mnt, mounts);
878
879 /* check that it is still dead: the count should now be 2 - as
880 * contributed by the vfsmount parent and the mntget above */
881 if (atomic_read(&mnt->mnt_count) == 2) {
882 struct vfsmount *xdmnt;
883 struct dentry *xdentry;
884
885 /* delete from the namespace */
886 list_del_init(&mnt->mnt_list);
887 list_del_init(&mnt->mnt_child);
888 list_del_init(&mnt->mnt_hash);
889 mnt->mnt_mountpoint->d_mounted--;
890
891 xdentry = mnt->mnt_mountpoint;
892 mnt->mnt_mountpoint = mnt->mnt_root;
893 xdmnt = mnt->mnt_parent;
894 mnt->mnt_parent = mnt;
895
896 spin_unlock(&vfsmount_lock);
897
898 mntput(xdmnt);
899 dput(xdentry);
900
901 /* now lay it to rest if this was the last ref on the
902 * superblock */
903 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
904 /* last instance - try to be smart */
905 lock_kernel();
906 DQUOT_OFF(mnt->mnt_sb);
907 acct_auto_close(mnt->mnt_sb);
908 unlock_kernel();
909 }
910
911 mntput(mnt);
912 } else {
913 /* someone brought it back to life whilst we didn't
914 * have any locks held so return it to the expiration
915 * list */
916 list_add_tail(&mnt->mnt_fslink, mounts);
917 spin_unlock(&vfsmount_lock);
918 }
919
920 up_write(&namespace->sem); 928 up_write(&namespace->sem);
921 929
922 mntput(mnt); 930 mntput(mnt);
@@ -1449,16 +1457,12 @@ void __init mnt_init(unsigned long mempages)
1449 1457
1450void __put_namespace(struct namespace *namespace) 1458void __put_namespace(struct namespace *namespace)
1451{ 1459{
1452 struct vfsmount *mnt; 1460 struct vfsmount *root = namespace->root;
1453 1461 namespace->root = NULL;
1462 spin_unlock(&vfsmount_lock);
1454 down_write(&namespace->sem); 1463 down_write(&namespace->sem);
1455 spin_lock(&vfsmount_lock); 1464 spin_lock(&vfsmount_lock);
1456 1465 umount_tree(root);
1457 list_for_each_entry(mnt, &namespace->list, mnt_list) {
1458 mnt->mnt_namespace = NULL;
1459 }
1460
1461 umount_tree(namespace->root);
1462 spin_unlock(&vfsmount_lock); 1466 spin_unlock(&vfsmount_lock);
1463 up_write(&namespace->sem); 1467 up_write(&namespace->sem);
1464 kfree(namespace); 1468 kfree(namespace);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index d71f14517b9c..e08edc17c6a0 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -169,12 +169,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
169 (int)open->op_fname.len, open->op_fname.data, 169 (int)open->op_fname.len, open->op_fname.data,
170 open->op_stateowner); 170 open->op_stateowner);
171 171
172 if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
173 return nfserr_grace;
174
175 if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
176 return nfserr_no_grace;
177
178 /* This check required by spec. */ 172 /* This check required by spec. */
179 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 173 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
180 return nfserr_inval; 174 return nfserr_inval;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 095f1740f3ae..57ed50fe7f85 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -119,25 +119,12 @@ out:
119 return status; 119 return status;
120} 120}
121 121
122static int 122static void
123nfsd4_rec_fsync(struct dentry *dentry) 123nfsd4_sync_rec_dir(void)
124{ 124{
125 struct file *filp; 125 down(&rec_dir.dentry->d_inode->i_sem);
126 int status = nfs_ok; 126 nfsd_sync_dir(rec_dir.dentry);
127 127 up(&rec_dir.dentry->d_inode->i_sem);
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} 128}
142 129
143int 130int
@@ -176,7 +163,7 @@ out_unlock:
176 up(&rec_dir.dentry->d_inode->i_sem); 163 up(&rec_dir.dentry->d_inode->i_sem);
177 if (status == 0) { 164 if (status == 0) {
178 clp->cl_firststate = 1; 165 clp->cl_firststate = 1;
179 status = nfsd4_rec_fsync(rec_dir.dentry); 166 nfsd4_sync_rec_dir();
180 } 167 }
181 nfs4_reset_user(uid, gid); 168 nfs4_reset_user(uid, gid);
182 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); 169 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
@@ -302,7 +289,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
302 289
303 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); 290 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
304 291
292 down(&rec_dir.dentry->d_inode->i_sem);
305 dentry = lookup_one_len(name, rec_dir.dentry, namlen); 293 dentry = lookup_one_len(name, rec_dir.dentry, namlen);
294 up(&rec_dir.dentry->d_inode->i_sem);
306 if (IS_ERR(dentry)) { 295 if (IS_ERR(dentry)) {
307 status = PTR_ERR(dentry); 296 status = PTR_ERR(dentry);
308 return status; 297 return status;
@@ -327,11 +316,12 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
327 if (!rec_dir_init || !clp->cl_firststate) 316 if (!rec_dir_init || !clp->cl_firststate)
328 return; 317 return;
329 318
319 clp->cl_firststate = 0;
330 nfs4_save_user(&uid, &gid); 320 nfs4_save_user(&uid, &gid);
331 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); 321 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
332 nfs4_reset_user(uid, gid); 322 nfs4_reset_user(uid, gid);
333 if (status == 0) 323 if (status == 0)
334 status = nfsd4_rec_fsync(rec_dir.dentry); 324 nfsd4_sync_rec_dir();
335 if (status) 325 if (status)
336 printk("NFSD: Failed to remove expired client state directory" 326 printk("NFSD: Failed to remove expired client state directory"
337 " %.*s\n", HEXDIR_LEN, clp->cl_recdir); 327 " %.*s\n", HEXDIR_LEN, clp->cl_recdir);
@@ -362,7 +352,7 @@ nfsd4_recdir_purge_old(void) {
362 return; 352 return;
363 status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old); 353 status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
364 if (status == 0) 354 if (status == 0)
365 status = nfsd4_rec_fsync(rec_dir.dentry); 355 nfsd4_sync_rec_dir();
366 if (status) 356 if (status)
367 printk("nfsd4: failed to purge old clients from recovery" 357 printk("nfsd4: failed to purge old clients from recovery"
368 " directory %s\n", rec_dir.dentry->d_name.name); 358 " directory %s\n", rec_dir.dentry->d_name.name);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 89e36526d7f2..b83f8fb441e1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -874,6 +874,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
874 * change request correctly. */ 874 * change request correctly. */
875 atomic_set(&conf->cl_callback.cb_set, 0); 875 atomic_set(&conf->cl_callback.cb_set, 0);
876 gen_confirm(conf); 876 gen_confirm(conf);
877 nfsd4_remove_clid_dir(unconf);
877 expire_client(unconf); 878 expire_client(unconf);
878 status = nfs_ok; 879 status = nfs_ok;
879 880
@@ -1159,6 +1160,7 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
1159 stp->st_deny_bmap = 0; 1160 stp->st_deny_bmap = 0;
1160 __set_bit(open->op_share_access, &stp->st_access_bmap); 1161 __set_bit(open->op_share_access, &stp->st_access_bmap);
1161 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 1162 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
1163 stp->st_openstp = NULL;
1162} 1164}
1163 1165
1164static void 1166static void
@@ -1294,7 +1296,7 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1294 fp = find_file(ino); 1296 fp = find_file(ino);
1295 if (!fp) 1297 if (!fp)
1296 return nfs_ok; 1298 return nfs_ok;
1297 ret = nfserr_share_denied; 1299 ret = nfserr_locked;
1298 /* Search for conflicting share reservations */ 1300 /* Search for conflicting share reservations */
1299 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) { 1301 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
1300 if (test_bit(deny_type, &stp->st_deny_bmap) || 1302 if (test_bit(deny_type, &stp->st_deny_bmap) ||
@@ -1482,7 +1484,7 @@ nfsd4_process_open1(struct nfsd4_open *open)
1482 if (sop) { 1484 if (sop) {
1483 open->op_stateowner = sop; 1485 open->op_stateowner = sop;
1484 /* check for replay */ 1486 /* check for replay */
1485 if (open->op_seqid == sop->so_seqid){ 1487 if (open->op_seqid == sop->so_seqid - 1){
1486 if (sop->so_replay.rp_buflen) 1488 if (sop->so_replay.rp_buflen)
1487 return NFSERR_REPLAY_ME; 1489 return NFSERR_REPLAY_ME;
1488 else { 1490 else {
@@ -1497,7 +1499,7 @@ nfsd4_process_open1(struct nfsd4_open *open)
1497 goto renew; 1499 goto renew;
1498 } 1500 }
1499 } else if (sop->so_confirmed) { 1501 } else if (sop->so_confirmed) {
1500 if (open->op_seqid == sop->so_seqid + 1) 1502 if (open->op_seqid == sop->so_seqid)
1501 goto renew; 1503 goto renew;
1502 status = nfserr_bad_seqid; 1504 status = nfserr_bad_seqid;
1503 goto out; 1505 goto out;
@@ -1530,8 +1532,6 @@ renew:
1530 status = nfs_ok; 1532 status = nfs_ok;
1531 renew_client(sop->so_client); 1533 renew_client(sop->so_client);
1532out: 1534out:
1533 if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1534 status = nfserr_reclaim_bad;
1535 return status; 1535 return status;
1536} 1536}
1537 1537
@@ -1685,19 +1685,11 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta
1685} 1685}
1686 1686
1687 1687
1688/* decrement seqid on successful reclaim, it will be bumped in encode_open */
1689static void 1688static void
1690nfs4_set_claim_prev(struct nfsd4_open *open, int *status) 1689nfs4_set_claim_prev(struct nfsd4_open *open)
1691{ 1690{
1692 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) { 1691 open->op_stateowner->so_confirmed = 1;
1693 if (*status) 1692 open->op_stateowner->so_client->cl_firststate = 1;
1694 *status = nfserr_reclaim_bad;
1695 else {
1696 open->op_stateowner->so_confirmed = 1;
1697 open->op_stateowner->so_client->cl_firststate = 1;
1698 open->op_stateowner->so_seqid--;
1699 }
1700 }
1701} 1693}
1702 1694
1703/* 1695/*
@@ -1789,6 +1781,12 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1789 struct nfs4_delegation *dp = NULL; 1781 struct nfs4_delegation *dp = NULL;
1790 int status; 1782 int status;
1791 1783
1784 if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
1785 return nfserr_grace;
1786
1787 if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1788 return nfserr_no_grace;
1789
1792 status = nfserr_inval; 1790 status = nfserr_inval;
1793 if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny)) 1791 if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
1794 goto out; 1792 goto out;
@@ -1823,6 +1821,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1823 status = nfs4_upgrade_open(rqstp, current_fh, stp, open); 1821 status = nfs4_upgrade_open(rqstp, current_fh, stp, open);
1824 if (status) 1822 if (status)
1825 goto out; 1823 goto out;
1824 update_stateid(&stp->st_stateid);
1826 } else { 1825 } else {
1827 /* Stateid was not found, this is a new OPEN */ 1826 /* Stateid was not found, this is a new OPEN */
1828 int flags = 0; 1827 int flags = 0;
@@ -1856,8 +1855,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1856out: 1855out:
1857 if (fp) 1856 if (fp)
1858 put_nfs4_file(fp); 1857 put_nfs4_file(fp);
1859 /* CLAIM_PREVIOUS has different error returns */ 1858 if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1860 nfs4_set_claim_prev(open, &status); 1859 nfs4_set_claim_prev(open);
1861 /* 1860 /*
1862 * To finish the open response, we just need to set the rflags. 1861 * To finish the open response, we just need to set the rflags.
1863 */ 1862 */
@@ -1990,14 +1989,11 @@ laundromat_main(void *not_used)
1990 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); 1989 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
1991} 1990}
1992 1991
1993/* search ownerid_hashtbl[] and close_lru for stateid owner
1994 * (stateid->si_stateownerid)
1995 */
1996static struct nfs4_stateowner * 1992static struct nfs4_stateowner *
1997find_openstateowner_id(u32 st_id, int flags) { 1993search_close_lru(u32 st_id, int flags)
1994{
1998 struct nfs4_stateowner *local = NULL; 1995 struct nfs4_stateowner *local = NULL;
1999 1996
2000 dprintk("NFSD: find_openstateowner_id %d\n", st_id);
2001 if (flags & CLOSE_STATE) { 1997 if (flags & CLOSE_STATE) {
2002 list_for_each_entry(local, &close_lru, so_close_lru) { 1998 list_for_each_entry(local, &close_lru, so_close_lru) {
2003 if (local->so_id == st_id) 1999 if (local->so_id == st_id)
@@ -2163,14 +2159,19 @@ out:
2163 return status; 2159 return status;
2164} 2160}
2165 2161
2162static inline int
2163setlkflg (int type)
2164{
2165 return (type == NFS4_READW_LT || type == NFS4_READ_LT) ?
2166 RD_STATE : WR_STATE;
2167}
2166 2168
2167/* 2169/*
2168 * Checks for sequence id mutating operations. 2170 * Checks for sequence id mutating operations.
2169 */ 2171 */
2170static int 2172static int
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) 2173nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
2172{ 2174{
2173 int status;
2174 struct nfs4_stateid *stp; 2175 struct nfs4_stateid *stp;
2175 struct nfs4_stateowner *sop; 2176 struct nfs4_stateowner *sop;
2176 2177
@@ -2178,53 +2179,65 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2178 "stateid = (%08x/%08x/%08x/%08x)\n", seqid, 2179 "stateid = (%08x/%08x/%08x/%08x)\n", seqid,
2179 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, 2180 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
2180 stateid->si_generation); 2181 stateid->si_generation);
2181 2182
2182 *stpp = NULL; 2183 *stpp = NULL;
2183 *sopp = NULL; 2184 *sopp = NULL;
2184 2185
2185 status = nfserr_bad_stateid;
2186 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { 2186 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
2187 printk("NFSD: preprocess_seqid_op: magic stateid!\n"); 2187 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
2188 goto out; 2188 return nfserr_bad_stateid;
2189 } 2189 }
2190 2190
2191 status = nfserr_stale_stateid;
2192 if (STALE_STATEID(stateid)) 2191 if (STALE_STATEID(stateid))
2193 goto out; 2192 return nfserr_stale_stateid;
2194 /* 2193 /*
2195 * We return BAD_STATEID if filehandle doesn't match stateid, 2194 * We return BAD_STATEID if filehandle doesn't match stateid,
2196 * the confirmed flag is incorrecly set, or the generation 2195 * the confirmed flag is incorrecly set, or the generation
2197 * number is incorrect. 2196 * number is incorrect.
2198 * If there is no entry in the openfile table for this id,
2199 * we can't always return BAD_STATEID;
2200 * this might be a retransmitted CLOSE which has arrived after
2201 * the openfile has been released.
2202 */ 2197 */
2203 if (!(stp = find_stateid(stateid, flags))) 2198 stp = find_stateid(stateid, flags);
2204 goto no_nfs4_stateid; 2199 if (stp == NULL) {
2205 2200 /*
2206 status = nfserr_bad_stateid; 2201 * Also, we should make sure this isn't just the result of
2202 * a replayed close:
2203 */
2204 sop = search_close_lru(stateid->si_stateownerid, flags);
2205 if (sop == NULL)
2206 return nfserr_bad_stateid;
2207 *sopp = sop;
2208 goto check_replay;
2209 }
2207 2210
2208 /* for new lock stateowners: 2211 if (lock) {
2209 * check that the lock->v.new.open_stateid
2210 * refers to an open stateowner
2211 *
2212 * check that the lockclid (nfs4_lock->v.new.clientid) is the same
2213 * as the open_stateid->st_stateowner->so_client->clientid
2214 */
2215 if (lockclid) {
2216 struct nfs4_stateowner *sop = stp->st_stateowner; 2212 struct nfs4_stateowner *sop = stp->st_stateowner;
2213 clientid_t *lockclid = &lock->v.new.clientid;
2217 struct nfs4_client *clp = sop->so_client; 2214 struct nfs4_client *clp = sop->so_client;
2215 int lkflg = 0;
2216 int status;
2217
2218 lkflg = setlkflg(lock->lk_type);
2219
2220 if (lock->lk_is_new) {
2221 if (!sop->so_is_open_owner)
2222 return nfserr_bad_stateid;
2223 if (!cmp_clid(&clp->cl_clientid, lockclid))
2224 return nfserr_bad_stateid;
2225 /* stp is the open stateid */
2226 status = nfs4_check_openmode(stp, lkflg);
2227 if (status)
2228 return status;
2229 } else {
2230 /* stp is the lock stateid */
2231 status = nfs4_check_openmode(stp->st_openstp, lkflg);
2232 if (status)
2233 return status;
2234 }
2218 2235
2219 if (!sop->so_is_open_owner)
2220 goto out;
2221 if (!cmp_clid(&clp->cl_clientid, lockclid))
2222 goto out;
2223 } 2236 }
2224 2237
2225 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) { 2238 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
2226 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n"); 2239 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
2227 goto out; 2240 return nfserr_bad_stateid;
2228 } 2241 }
2229 2242
2230 *stpp = stp; 2243 *stpp = stp;
@@ -2235,63 +2248,41 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2235 * For the moment, we ignore the possibility of 2248 * For the moment, we ignore the possibility of
2236 * generation number wraparound. 2249 * generation number wraparound.
2237 */ 2250 */
2238 if (seqid != sop->so_seqid + 1) 2251 if (seqid != sop->so_seqid)
2239 goto check_replay; 2252 goto check_replay;
2240 2253
2241 if (sop->so_confirmed) { 2254 if (sop->so_confirmed && flags & CONFIRM) {
2242 if (flags & CONFIRM) { 2255 printk("NFSD: preprocess_seqid_op: expected"
2243 printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n"); 2256 " unconfirmed stateowner!\n");
2244 goto out; 2257 return nfserr_bad_stateid;
2245 }
2246 } 2258 }
2247 else { 2259 if (!sop->so_confirmed && !(flags & CONFIRM)) {
2248 if (!(flags & CONFIRM)) { 2260 printk("NFSD: preprocess_seqid_op: stateowner not"
2249 printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n"); 2261 " confirmed yet!\n");
2250 goto out; 2262 return nfserr_bad_stateid;
2251 }
2252 } 2263 }
2253 if (stateid->si_generation > stp->st_stateid.si_generation) { 2264 if (stateid->si_generation > stp->st_stateid.si_generation) {
2254 printk("NFSD: preprocess_seqid_op: future stateid?!\n"); 2265 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
2255 goto out; 2266 return nfserr_bad_stateid;
2256 } 2267 }
2257 2268
2258 status = nfserr_old_stateid;
2259 if (stateid->si_generation < stp->st_stateid.si_generation) { 2269 if (stateid->si_generation < stp->st_stateid.si_generation) {
2260 printk("NFSD: preprocess_seqid_op: old stateid!\n"); 2270 printk("NFSD: preprocess_seqid_op: old stateid!\n");
2261 goto out; 2271 return nfserr_old_stateid;
2262 } 2272 }
2263 /* XXX renew the client lease here */ 2273 renew_client(sop->so_client);
2264 status = nfs_ok; 2274 return nfs_ok;
2265
2266out:
2267 return status;
2268
2269no_nfs4_stateid:
2270
2271 /*
2272 * We determine whether this is a bad stateid or a replay,
2273 * starting by trying to look up the stateowner.
2274 * If stateowner is not found - stateid is bad.
2275 */
2276 if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
2277 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
2278 status = nfserr_bad_stateid;
2279 goto out;
2280 }
2281 *sopp = sop;
2282 2275
2283check_replay: 2276check_replay:
2284 if (seqid == sop->so_seqid) { 2277 if (seqid == sop->so_seqid - 1) {
2285 printk("NFSD: preprocess_seqid_op: retransmission?\n"); 2278 printk("NFSD: preprocess_seqid_op: retransmission?\n");
2286 /* indicate replay to calling function */ 2279 /* indicate replay to calling function */
2287 status = NFSERR_REPLAY_ME; 2280 return NFSERR_REPLAY_ME;
2288 } else {
2289 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
2290
2291 *sopp = NULL;
2292 status = nfserr_bad_seqid;
2293 } 2281 }
2294 goto out; 2282 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
2283 sop->so_seqid, seqid);
2284 *sopp = NULL;
2285 return nfserr_bad_seqid;
2295} 2286}
2296 2287
2297int 2288int
@@ -2609,7 +2600,6 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid,
2609 * occured. 2600 * occured.
2610 * 2601 *
2611 * strhashval = lock_ownerstr_hashval 2602 * strhashval = lock_ownerstr_hashval
2612 * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode
2613 */ 2603 */
2614 2604
2615static struct nfs4_stateowner * 2605static struct nfs4_stateowner *
@@ -2634,7 +2624,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
2634 sop->so_is_open_owner = 0; 2624 sop->so_is_open_owner = 0;
2635 sop->so_id = current_ownerid++; 2625 sop->so_id = current_ownerid++;
2636 sop->so_client = clp; 2626 sop->so_client = clp;
2637 sop->so_seqid = lock->lk_new_lock_seqid - 1; 2627 sop->so_seqid = lock->lk_new_lock_seqid;
2638 sop->so_confirmed = 1; 2628 sop->so_confirmed = 1;
2639 rp = &sop->so_replay; 2629 rp = &sop->so_replay;
2640 rp->rp_status = NFSERR_SERVERFAULT; 2630 rp->rp_status = NFSERR_SERVERFAULT;
@@ -2669,6 +2659,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
2669 stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */ 2659 stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
2670 stp->st_access_bmap = open_stp->st_access_bmap; 2660 stp->st_access_bmap = open_stp->st_access_bmap;
2671 stp->st_deny_bmap = open_stp->st_deny_bmap; 2661 stp->st_deny_bmap = open_stp->st_deny_bmap;
2662 stp->st_openstp = open_stp;
2672 2663
2673out: 2664out:
2674 return stp; 2665 return stp;
@@ -2699,22 +2690,17 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2699 (long long) lock->lk_offset, 2690 (long long) lock->lk_offset,
2700 (long long) lock->lk_length); 2691 (long long) lock->lk_length);
2701 2692
2702 if (nfs4_in_grace() && !lock->lk_reclaim)
2703 return nfserr_grace;
2704 if (!nfs4_in_grace() && lock->lk_reclaim)
2705 return nfserr_no_grace;
2706
2707 if (check_lock_length(lock->lk_offset, lock->lk_length)) 2693 if (check_lock_length(lock->lk_offset, lock->lk_length))
2708 return nfserr_inval; 2694 return nfserr_inval;
2709 2695
2710 nfs4_lock_state(); 2696 nfs4_lock_state();
2711 2697
2712 if (lock->lk_is_new) { 2698 if (lock->lk_is_new) {
2713 /* 2699 /*
2714 * Client indicates that this is a new lockowner. 2700 * Client indicates that this is a new lockowner.
2715 * Use open owner and open stateid to create lock owner and lock 2701 * Use open owner and open stateid to create lock owner and
2716 * stateid. 2702 * lock stateid.
2717 */ 2703 */
2718 struct nfs4_stateid *open_stp = NULL; 2704 struct nfs4_stateid *open_stp = NULL;
2719 struct nfs4_file *fp; 2705 struct nfs4_file *fp;
2720 2706
@@ -2724,23 +2710,14 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2724 goto out; 2710 goto out;
2725 } 2711 }
2726 2712
2727 /* is the new lock seqid presented by the client zero? */
2728 status = nfserr_bad_seqid;
2729 if (lock->v.new.lock_seqid != 0)
2730 goto out;
2731
2732 /* validate and update open stateid and open seqid */ 2713 /* validate and update open stateid and open seqid */
2733 status = nfs4_preprocess_seqid_op(current_fh, 2714 status = nfs4_preprocess_seqid_op(current_fh,
2734 lock->lk_new_open_seqid, 2715 lock->lk_new_open_seqid,
2735 &lock->lk_new_open_stateid, 2716 &lock->lk_new_open_stateid,
2736 CHECK_FH | OPEN_STATE, 2717 CHECK_FH | OPEN_STATE,
2737 &open_sop, &open_stp, 2718 &open_sop, &open_stp, lock);
2738 &lock->v.new.clientid); 2719 if (status)
2739 if (status) {
2740 if (lock->lk_reclaim)
2741 status = nfserr_reclaim_bad;
2742 goto out; 2720 goto out;
2743 }
2744 /* create lockowner and lock stateid */ 2721 /* create lockowner and lock stateid */
2745 fp = open_stp->st_file; 2722 fp = open_stp->st_file;
2746 strhashval = lock_ownerstr_hashval(fp->fi_inode, 2723 strhashval = lock_ownerstr_hashval(fp->fi_inode,
@@ -2766,7 +2743,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2766 lock->lk_old_lock_seqid, 2743 lock->lk_old_lock_seqid,
2767 &lock->lk_old_lock_stateid, 2744 &lock->lk_old_lock_stateid,
2768 CHECK_FH | LOCK_STATE, 2745 CHECK_FH | LOCK_STATE,
2769 &lock->lk_stateowner, &lock_stp, NULL); 2746 &lock->lk_stateowner, &lock_stp, lock);
2770 if (status) 2747 if (status)
2771 goto out; 2748 goto out;
2772 } 2749 }
@@ -2778,6 +2755,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2778 goto out; 2755 goto out;
2779 } 2756 }
2780 2757
2758 status = nfserr_grace;
2759 if (nfs4_in_grace() && !lock->lk_reclaim)
2760 goto out;
2761 status = nfserr_no_grace;
2762 if (!nfs4_in_grace() && lock->lk_reclaim)
2763 goto out;
2764
2781 locks_init_lock(&file_lock); 2765 locks_init_lock(&file_lock);
2782 switch (lock->lk_type) { 2766 switch (lock->lk_type) {
2783 case NFS4_READ_LT: 2767 case NFS4_READ_LT:
@@ -2844,10 +2828,10 @@ conflicting_lock:
2844out_destroy_new_stateid: 2828out_destroy_new_stateid:
2845 if (lock->lk_is_new) { 2829 if (lock->lk_is_new) {
2846 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n"); 2830 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2847 /* 2831 /*
2848 * An error encountered after instantiation of the new 2832 * An error encountered after instantiation of the new
2849 * stateid has forced us to destroy it. 2833 * stateid has forced us to destroy it.
2850 */ 2834 */
2851 if (!seqid_mutating_err(status)) 2835 if (!seqid_mutating_err(status))
2852 open_sop->so_seqid--; 2836 open_sop->so_seqid--;
2853 2837
@@ -3083,7 +3067,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
3083 * of the lockowner state released; so don't release any until all 3067 * of the lockowner state released; so don't release any until all
3084 * have been checked. */ 3068 * have been checked. */
3085 status = nfs_ok; 3069 status = nfs_ok;
3086 list_for_each_entry(sop, &matches, so_perclient) { 3070 while (!list_empty(&matches)) {
3071 sop = list_entry(matches.next, struct nfs4_stateowner,
3072 so_perclient);
3073 /* unhash_stateowner deletes so_perclient only
3074 * for openowners. */
3075 list_del(&sop->so_perclient);
3087 release_stateowner(sop); 3076 release_stateowner(sop);
3088 } 3077 }
3089out: 3078out:
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 91fb171d2ace..4c4146350236 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1210,16 +1210,15 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1210 save = resp->p; 1210 save = resp->p;
1211 1211
1212/* 1212/*
1213 * Routine for encoding the result of a 1213 * Routine for encoding the result of a "seqid-mutating" NFSv4 operation. This
1214 * "seqid-mutating" NFSv4 operation. This is 1214 * is where sequence id's are incremented, and the replay cache is filled.
1215 * where seqids are incremented, and the 1215 * Note that we increment sequence id's here, at the last moment, so we're sure
1216 * replay cache is filled. 1216 * we know whether the error to be returned is a sequence id mutating error.
1217 */ 1217 */
1218 1218
1219#define ENCODE_SEQID_OP_TAIL(stateowner) do { \ 1219#define ENCODE_SEQID_OP_TAIL(stateowner) do { \
1220 if (seqid_mutating_err(nfserr) && stateowner) { \ 1220 if (seqid_mutating_err(nfserr) && stateowner) { \
1221 if (stateowner->so_confirmed) \ 1221 stateowner->so_seqid++; \
1222 stateowner->so_seqid++; \
1223 stateowner->so_replay.rp_status = nfserr; \ 1222 stateowner->so_replay.rp_status = nfserr; \
1224 stateowner->so_replay.rp_buflen = \ 1223 stateowner->so_replay.rp_buflen = \
1225 (((char *)(resp)->p - (char *)save)); \ 1224 (((char *)(resp)->p - (char *)save)); \
@@ -1367,9 +1366,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1367 if ((buflen -= 4) < 0) 1366 if ((buflen -= 4) < 0)
1368 goto out_resource; 1367 goto out_resource;
1369 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) 1368 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
1370 WRITE32(NFS4_FH_VOLATILE_ANY); 1369 WRITE32(NFS4_FH_PERSISTENT);
1371 else 1370 else
1372 WRITE32(NFS4_FH_VOLATILE_ANY|NFS4_FH_VOL_RENAME); 1371 WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
1373 } 1372 }
1374 if (bmval0 & FATTR4_WORD0_CHANGE) { 1373 if (bmval0 & FATTR4_WORD0_CHANGE) {
1375 /* 1374 /*
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index be24ead89d94..5e0bf3917607 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -733,7 +733,7 @@ nfsd_sync(struct file *filp)
733 up(&inode->i_sem); 733 up(&inode->i_sem);
734} 734}
735 735
736static void 736void
737nfsd_sync_dir(struct dentry *dp) 737nfsd_sync_dir(struct dentry *dp)
738{ 738{
739 nfsd_dosync(NULL, dp, dp->d_inode->i_fop); 739 nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
diff --git a/fs/super.c b/fs/super.c
index 25bc1ec6bc5d..6e57ee252e14 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -840,7 +840,6 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
840 mnt->mnt_root = dget(sb->s_root); 840 mnt->mnt_root = dget(sb->s_root);
841 mnt->mnt_mountpoint = sb->s_root; 841 mnt->mnt_mountpoint = sb->s_root;
842 mnt->mnt_parent = mnt; 842 mnt->mnt_parent = mnt;
843 mnt->mnt_namespace = current->namespace;
844 up_write(&sb->s_umount); 843 up_write(&sb->s_umount);
845 free_secdata(secdata); 844 free_secdata(secdata);
846 put_filesystem(type); 845 put_filesystem(type);
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 408aea55e0cc..e139463d9a0e 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -132,6 +132,8 @@
132#define __S110 _PAGE_S(0) 132#define __S110 _PAGE_S(0)
133#define __S111 _PAGE_S(0) 133#define __S111 _PAGE_S(0)
134 134
135#define pgprot_noncached(prot) (prot)
136
135/* 137/*
136 * BAD_PAGETABLE is used when we need a bogus page-table, while 138 * BAD_PAGETABLE is used when we need a bogus page-table, while
137 * BAD_PAGE is used for a bogus page. 139 * BAD_PAGE is used for a bogus page.
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 33ce5d37e894..516421300ea2 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -8,20 +8,15 @@
8 8
9#include <asm/smp.h> 9#include <asm/smp.h>
10 10
11#if CONFIG_NUMA 11#ifdef CONFIG_NUMA
12extern struct pglist_data *node_data[]; 12extern struct pglist_data *node_data[];
13#define NODE_DATA(nid) (node_data[nid]) 13#define NODE_DATA(nid) (node_data[nid])
14 14
15#ifdef CONFIG_NUMA 15#ifdef CONFIG_X86_NUMAQ
16 #ifdef CONFIG_X86_NUMAQ 16 #include <asm/numaq.h>
17 #include <asm/numaq.h> 17#else /* summit or generic arch */
18 #else /* summit or generic arch */ 18 #include <asm/srat.h>
19 #include <asm/srat.h> 19#endif
20 #endif
21#else /* !CONFIG_NUMA */
22 #define get_memcfg_numa get_memcfg_numa_flat
23 #define get_zholes_size(n) (0)
24#endif /* CONFIG_NUMA */
25 20
26extern int get_memcfg_numa_flat(void ); 21extern int get_memcfg_numa_flat(void );
27/* 22/*
@@ -42,6 +37,11 @@ static inline void get_memcfg_numa(void)
42 get_memcfg_numa_flat(); 37 get_memcfg_numa_flat();
43} 38}
44 39
40extern int early_pfn_to_nid(unsigned long pfn);
41
42#else /* !CONFIG_NUMA */
43#define get_memcfg_numa get_memcfg_numa_flat
44#define get_zholes_size(n) (0)
45#endif /* CONFIG_NUMA */ 45#endif /* CONFIG_NUMA */
46 46
47#ifdef CONFIG_DISCONTIGMEM 47#ifdef CONFIG_DISCONTIGMEM
@@ -151,6 +151,4 @@ static inline int pfn_valid(int pfn)
151 151
152#endif /* CONFIG_NEED_MULTIPLE_NODES */ 152#endif /* CONFIG_NEED_MULTIPLE_NODES */
153 153
154extern int early_pfn_to_nid(unsigned long pfn);
155
156#endif /* _ASM_MMZONE_H_ */ 154#endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 6f0f93d0d417..5d06e6bd6ba0 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -694,4 +694,12 @@ extern unsigned long boot_option_idle_override;
694extern void enable_sep_cpu(void); 694extern void enable_sep_cpu(void);
695extern int sysenter_setup(void); 695extern int sysenter_setup(void);
696 696
697#ifdef CONFIG_MTRR
698extern void mtrr_ap_init(void);
699extern void mtrr_bp_init(void);
700#else
701#define mtrr_ap_init() do {} while (0)
702#define mtrr_bp_init() do {} while (0)
703#endif
704
697#endif /* __ASM_I386_PROCESSOR_H */ 705#endif /* __ASM_I386_PROCESSOR_H */
diff --git a/include/asm-m32r/s1d13806.h b/include/asm-m32r/s1d13806.h
new file mode 100644
index 000000000000..248d36a82d79
--- /dev/null
+++ b/include/asm-m32r/s1d13806.h
@@ -0,0 +1,199 @@
1//----------------------------------------------------------------------------
2//
3// File generated by S1D13806CFG.EXE
4//
5// Copyright (c) 2000,2001 Epson Research and Development, Inc.
6// All rights reserved.
7//
8//----------------------------------------------------------------------------
9
10// Panel: (active) 640x480 77Hz STN Single 8-bit (PCLK=CLKI=25.175MHz)
11// Memory: Embedded SDRAM (MCLK=CLKI3=50.000MHz) (BUSCLK=33.333MHz)
12
13#define SWIVEL_VIEW 0 /* 0:none, 1:90 not completed */
14
15static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
16
17 {0x0001,0x00}, // Miscellaneous Register
18 {0x01FC,0x00}, // Display Mode Register
19#if defined(CONFIG_PLAT_MAPPI)
20 {0x0004,0x00}, // General IO Pins Configuration Register 0
21 {0x0005,0x00}, // General IO Pins Configuration Register 1
22 {0x0008,0x00}, // General IO Pins Control Register 0
23 {0x0009,0x00}, // General IO Pins Control Register 1
24 {0x0010,0x00}, // Memory Clock Configuration Register
25 {0x0014,0x00}, // LCD Pixel Clock Configuration Register
26 {0x0018,0x00}, // CRT/TV Pixel Clock Configuration Register
27 {0x001C,0x00}, // MediaPlug Clock Configuration Register
28/*
29 * .. 10MHz: 0x00
30 * .. 30MHz: 0x01
31 * 30MHz ..: 0x02
32 */
33 {0x001E,0x02}, // CPU To Memory Wait State Select Register
34 {0x0021,0x02}, // DRAM Refresh Rate Register
35 {0x002A,0x11}, // DRAM Timings Control Register 0
36 {0x002B,0x13}, // DRAM Timings Control Register 1
37 {0x0020,0x80}, // Memory Configuration Register
38 {0x0030,0x25}, // Panel Type Register
39 {0x0031,0x00}, // MOD Rate Register
40 {0x0032,0x4F}, // LCD Horizontal Display Width Register
41 {0x0034,0x12}, // LCD Horizontal Non-Display Period Register
42 {0x0035,0x01}, // TFT FPLINE Start Position Register
43 {0x0036,0x0B}, // TFT FPLINE Pulse Width Register
44 {0x0038,0xDF}, // LCD Vertical Display Height Register 0
45 {0x0039,0x01}, // LCD Vertical Display Height Register 1
46 {0x003A,0x2C}, // LCD Vertical Non-Display Period Register
47 {0x003B,0x0A}, // TFT FPFRAME Start Position Register
48 {0x003C,0x01}, // TFT FPFRAME Pulse Width Register
49
50 {0x0041,0x00}, // LCD Miscellaneous Register
51 {0x0042,0x00}, // LCD Display Start Address Register 0
52 {0x0043,0x00}, // LCD Display Start Address Register 1
53 {0x0044,0x00}, // LCD Display Start Address Register 2
54
55#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
56 {0x0004,0x07}, // GPIO[0:7] direction
57 {0x0005,0x00}, // GPIO[8:12] direction
58 {0x0008,0x00}, // GPIO[0:7] data
59 {0x0009,0x00}, // GPIO[8:12] data
60 {0x0008,0x04}, // LCD panel Vcc on
61 {0x0008,0x05}, // LCD panel reset
62 {0x0010,0x01}, // Memory Clock Configuration Register
63 {0x0014,0x30}, // LCD Pixel Clock Configuration Register (CLKI 22MHz/4)
64 {0x0018,0x00}, // CRT/TV Pixel Clock Configuration Register
65 {0x001C,0x00}, // MediaPlug Clock Configuration Register(10MHz)
66 {0x001E,0x00}, // CPU To Memory Wait State Select Register
67 {0x0020,0x80}, // Memory Configuration Register
68 {0x0021,0x03}, // DRAM Refresh Rate Register
69 {0x002A,0x00}, // DRAM Timings Control Register 0
70 {0x002B,0x01}, // DRAM Timings Control Register 1
71 {0x0030,0x25}, // Panel Type Register
72 {0x0031,0x00}, // MOD Rate Register
73 {0x0032,0x1d}, // LCD Horizontal Display Width Register
74 {0x0034,0x05}, // LCD Horizontal Non-Display Period Register
75 {0x0035,0x01}, // TFT FPLINE Start Position Register
76 {0x0036,0x01}, // TFT FPLINE Pulse Width Register
77 {0x0038,0x3F}, // LCD Vertical Display Height Register 0
78 {0x0039,0x01}, // LCD Vertical Display Height Register 1
79 {0x003A,0x0b}, // LCD Vertical Non-Display Period Register
80 {0x003B,0x07}, // TFT FPFRAME Start Position Register
81 {0x003C,0x02}, // TFT FPFRAME Pulse Width Register
82
83 {0x0041,0x00}, // LCD Miscellaneous Register
84#if (SWIVEL_VIEW == 0)
85 {0x0042,0x00}, // LCD Display Start Address Register 0
86 {0x0043,0x00}, // LCD Display Start Address Register 1
87 {0x0044,0x00}, // LCD Display Start Address Register 2
88
89#elif (SWIVEL_VIEW == 1)
90 // 1024 - W(320) = 0x2C0
91 {0x0042,0xC0}, // LCD Display Start Address Register 0
92 {0x0043,0x02}, // LCD Display Start Address Register 1
93 {0x0044,0x00}, // LCD Display Start Address Register 2
94 // 1024
95 {0x0046,0x00}, // LCD Memory Address Offset Register 0
96 {0x0047,0x02}, // LCD Memory Address Offset Register 1
97#else
98#error unsupported SWIVEL_VIEW mode
99#endif
100#else
101#error no platform configuration
102#endif /* CONFIG_PLAT_XXX */
103
104 {0x0048,0x00}, // LCD Pixel Panning Register
105 {0x004A,0x00}, // LCD Display FIFO High Threshold Control Register
106 {0x004B,0x00}, // LCD Display FIFO Low Threshold Control Register
107 {0x0050,0x4F}, // CRT/TV Horizontal Display Width Register
108 {0x0052,0x13}, // CRT/TV Horizontal Non-Display Period Register
109 {0x0053,0x01}, // CRT/TV HRTC Start Position Register
110 {0x0054,0x0B}, // CRT/TV HRTC Pulse Width Register
111 {0x0056,0xDF}, // CRT/TV Vertical Display Height Register 0
112 {0x0057,0x01}, // CRT/TV Vertical Display Height Register 1
113 {0x0058,0x2B}, // CRT/TV Vertical Non-Display Period Register
114 {0x0059,0x09}, // CRT/TV VRTC Start Position Register
115 {0x005A,0x01}, // CRT/TV VRTC Pulse Width Register
116 {0x005B,0x10}, // TV Output Control Register
117
118 {0x0062,0x00}, // CRT/TV Display Start Address Register 0
119 {0x0063,0x00}, // CRT/TV Display Start Address Register 1
120 {0x0064,0x00}, // CRT/TV Display Start Address Register 2
121
122 {0x0068,0x00}, // CRT/TV Pixel Panning Register
123 {0x006A,0x00}, // CRT/TV Display FIFO High Threshold Control Register
124 {0x006B,0x00}, // CRT/TV Display FIFO Low Threshold Control Register
125 {0x0070,0x00}, // LCD Ink/Cursor Control Register
126 {0x0071,0x01}, // LCD Ink/Cursor Start Address Register
127 {0x0072,0x00}, // LCD Cursor X Position Register 0
128 {0x0073,0x00}, // LCD Cursor X Position Register 1
129 {0x0074,0x00}, // LCD Cursor Y Position Register 0
130 {0x0075,0x00}, // LCD Cursor Y Position Register 1
131 {0x0076,0x00}, // LCD Ink/Cursor Blue Color 0 Register
132 {0x0077,0x00}, // LCD Ink/Cursor Green Color 0 Register
133 {0x0078,0x00}, // LCD Ink/Cursor Red Color 0 Register
134 {0x007A,0x1F}, // LCD Ink/Cursor Blue Color 1 Register
135 {0x007B,0x3F}, // LCD Ink/Cursor Green Color 1 Register
136 {0x007C,0x1F}, // LCD Ink/Cursor Red Color 1 Register
137 {0x007E,0x00}, // LCD Ink/Cursor FIFO Threshold Register
138 {0x0080,0x00}, // CRT/TV Ink/Cursor Control Register
139 {0x0081,0x01}, // CRT/TV Ink/Cursor Start Address Register
140 {0x0082,0x00}, // CRT/TV Cursor X Position Register 0
141 {0x0083,0x00}, // CRT/TV Cursor X Position Register 1
142 {0x0084,0x00}, // CRT/TV Cursor Y Position Register 0
143 {0x0085,0x00}, // CRT/TV Cursor Y Position Register 1
144 {0x0086,0x00}, // CRT/TV Ink/Cursor Blue Color 0 Register
145 {0x0087,0x00}, // CRT/TV Ink/Cursor Green Color 0 Register
146 {0x0088,0x00}, // CRT/TV Ink/Cursor Red Color 0 Register
147 {0x008A,0x1F}, // CRT/TV Ink/Cursor Blue Color 1 Register
148 {0x008B,0x3F}, // CRT/TV Ink/Cursor Green Color 1 Register
149 {0x008C,0x1F}, // CRT/TV Ink/Cursor Red Color 1 Register
150 {0x008E,0x00}, // CRT/TV Ink/Cursor FIFO Threshold Register
151 {0x0100,0x00}, // BitBlt Control Register 0
152 {0x0101,0x00}, // BitBlt Control Register 1
153 {0x0102,0x00}, // BitBlt ROP Code/Color Expansion Register
154 {0x0103,0x00}, // BitBlt Operation Register
155 {0x0104,0x00}, // BitBlt Source Start Address Register 0
156 {0x0105,0x00}, // BitBlt Source Start Address Register 1
157 {0x0106,0x00}, // BitBlt Source Start Address Register 2
158 {0x0108,0x00}, // BitBlt Destination Start Address Register 0
159 {0x0109,0x00}, // BitBlt Destination Start Address Register 1
160 {0x010A,0x00}, // BitBlt Destination Start Address Register 2
161 {0x010C,0x00}, // BitBlt Memory Address Offset Register 0
162 {0x010D,0x00}, // BitBlt Memory Address Offset Register 1
163 {0x0110,0x00}, // BitBlt Width Register 0
164 {0x0111,0x00}, // BitBlt Width Register 1
165 {0x0112,0x00}, // BitBlt Height Register 0
166 {0x0113,0x00}, // BitBlt Height Register 1
167 {0x0114,0x00}, // BitBlt Background Color Register 0
168 {0x0115,0x00}, // BitBlt Background Color Register 1
169 {0x0118,0x00}, // BitBlt Foreground Color Register 0
170 {0x0119,0x00}, // BitBlt Foreground Color Register 1
171 {0x01E0,0x00}, // Look-Up Table Mode Register
172 {0x01E2,0x00}, // Look-Up Table Address Register
173 {0x01F0,0x10}, // Power Save Configuration Register
174 {0x01F1,0x00}, // Power Save Status Register
175 {0x01F4,0x00}, // CPU-to-Memory Access Watchdog Timer Register
176#if (SWIVEL_VIEW == 0)
177 {0x01FC,0x01}, // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
178#elif (SWIVEL_VIEW == 1)
179 {0x01FC,0x41}, // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
180#else
181#error unsupported SWIVEL_VIEW mode
182#endif /* SWIVEL_VIEW */
183
184#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
185 {0x0008,0x07}, // LCD panel Vdd & Vg on
186#endif
187
188 {0x0040,0x05}, // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
189#if defined(CONFIG_PLAT_MAPPI)
190 {0x0046,0x80}, // LCD Memory Address Offset Register 0
191 {0x0047,0x02}, // LCD Memory Address Offset Register 1
192#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
193 {0x0046,0xf0}, // LCD Memory Address Offset Register 0
194 {0x0047,0x00}, // LCD Memory Address Offset Register 1
195#endif
196 {0x0060,0x05}, // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
197 {0x0066,0x80}, // CRT/TV Memory Address Offset Register 0 // takeo
198 {0x0067,0x02}, // CRT/TV Memory Address Offset Register 1
199};
diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
index e8b79220b29c..a7894e0fbbb1 100644
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-ppc/unistd.h
@@ -262,7 +262,7 @@
262#define __NR_rtas 255 262#define __NR_rtas 255
263#define __NR_sys_debug_setcontext 256 263#define __NR_sys_debug_setcontext 256
264/* Number 257 is reserved for vserver */ 264/* Number 257 is reserved for vserver */
265/* Number 258 is reserved for new sys_remap_file_pages */ 265/* 258 currently unused */
266/* Number 259 is reserved for new sys_mbind */ 266/* Number 259 is reserved for new sys_mbind */
267/* Number 260 is reserved for new sys_get_mempolicy */ 267/* Number 260 is reserved for new sys_get_mempolicy */
268/* Number 261 is reserved for new sys_set_mempolicy */ 268/* Number 261 is reserved for new sys_set_mempolicy */
diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h
index cbbfbec78b6b..d67fa9e26079 100644
--- a/include/asm-ppc64/cputable.h
+++ b/include/asm-ppc64/cputable.h
@@ -138,6 +138,7 @@ extern firmware_feature_t firmware_features_table[];
138#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000) 138#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000)
139#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000) 139#define CPU_FTR_LOCKLESS_TLBIE ASM_CONST(0x0000040000000000)
140#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000) 140#define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000)
141#define CPU_FTR_CTRL ASM_CONST(0x0000100000000000)
141 142
142/* Platform firmware features */ 143/* Platform firmware features */
143#define FW_FTR_ ASM_CONST(0x0000000000000001) 144#define FW_FTR_ ASM_CONST(0x0000000000000001)
@@ -148,7 +149,7 @@ extern firmware_feature_t firmware_features_table[];
148 149
149#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ 150#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
150 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \ 151 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
151 CPU_FTR_NODSISRALIGN) 152 CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
152 153
153/* iSeries doesn't support large pages */ 154/* iSeries doesn't support large pages */
154#ifdef CONFIG_PPC_ISERIES 155#ifdef CONFIG_PPC_ISERIES
diff --git a/include/asm-ppc64/hvconsole.h b/include/asm-ppc64/hvconsole.h
index d89d94c91815..6da93ce74dc0 100644
--- a/include/asm-ppc64/hvconsole.h
+++ b/include/asm-ppc64/hvconsole.h
@@ -29,12 +29,21 @@
29 */ 29 */
30#define MAX_NR_HVC_CONSOLES 16 30#define MAX_NR_HVC_CONSOLES 16
31 31
32/* implemented by a low level driver */
33struct hv_ops {
34 int (*get_chars)(uint32_t vtermno, char *buf, int count);
35 int (*put_chars)(uint32_t vtermno, const char *buf, int count);
36};
32extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); 37extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
33extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); 38extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
34 39
35/* Early discovery of console adapters. */ 40struct hvc_struct;
36extern int hvc_find_vtys(void);
37 41
38/* Implemented by a console driver */ 42/* Register a vterm and a slot index for use as a console (console_init) */
39extern int hvc_instantiate(uint32_t vtermno, int index); 43extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
44/* register a vterm for hvc tty operation (module_init or hotplug add) */
45extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
46 struct hv_ops *ops);
47/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
48extern int __devexit hvc_remove(struct hvc_struct *hp);
40#endif /* _PPC64_HVCONSOLE_H */ 49#endif /* _PPC64_HVCONSOLE_H */
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
index 9cdad3ed1526..1e6ad4824132 100644
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-ppc64/machdep.h
@@ -140,8 +140,13 @@ struct machdep_calls {
140 unsigned long size, 140 unsigned long size,
141 pgprot_t vma_prot); 141 pgprot_t vma_prot);
142 142
143 /* Idle loop for this platform, leave empty for default idle loop */
144 int (*idle_loop)(void);
143}; 145};
144 146
147extern int default_idle(void);
148extern int native_idle(void);
149
145extern struct machdep_calls ppc_md; 150extern struct machdep_calls ppc_md;
146extern char cmd_line[COMMAND_LINE_SIZE]; 151extern char cmd_line[COMMAND_LINE_SIZE];
147 152
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index af28aa55d8c1..352306cfb579 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -20,6 +20,7 @@
20#include <asm/ptrace.h> 20#include <asm/ptrace.h>
21#include <asm/types.h> 21#include <asm/types.h>
22#include <asm/systemcfg.h> 22#include <asm/systemcfg.h>
23#include <asm/cputable.h>
23 24
24/* Machine State Register (MSR) Fields */ 25/* Machine State Register (MSR) Fields */
25#define MSR_SF_LG 63 /* Enable 64 bit mode */ 26#define MSR_SF_LG 63 /* Enable 64 bit mode */
@@ -501,24 +502,37 @@ static inline void ppc64_runlatch_on(void)
501{ 502{
502 unsigned long ctrl; 503 unsigned long ctrl;
503 504
504 ctrl = mfspr(SPRN_CTRLF); 505 if (cpu_has_feature(CPU_FTR_CTRL)) {
505 ctrl |= CTRL_RUNLATCH; 506 ctrl = mfspr(SPRN_CTRLF);
506 mtspr(SPRN_CTRLT, ctrl); 507 ctrl |= CTRL_RUNLATCH;
508 mtspr(SPRN_CTRLT, ctrl);
509 }
507} 510}
508 511
509static inline void ppc64_runlatch_off(void) 512static inline void ppc64_runlatch_off(void)
510{ 513{
511 unsigned long ctrl; 514 unsigned long ctrl;
512 515
513 ctrl = mfspr(SPRN_CTRLF); 516 if (cpu_has_feature(CPU_FTR_CTRL)) {
514 ctrl &= ~CTRL_RUNLATCH; 517 ctrl = mfspr(SPRN_CTRLF);
515 mtspr(SPRN_CTRLT, ctrl); 518 ctrl &= ~CTRL_RUNLATCH;
519 mtspr(SPRN_CTRLT, ctrl);
520 }
516} 521}
517 522
518#endif /* __KERNEL__ */ 523#endif /* __KERNEL__ */
519 524
520#endif /* __ASSEMBLY__ */ 525#endif /* __ASSEMBLY__ */
521 526
527#ifdef __KERNEL__
528#define RUNLATCH_ON(REG) \
529BEGIN_FTR_SECTION \
530 mfspr (REG),SPRN_CTRLF; \
531 ori (REG),(REG),CTRL_RUNLATCH; \
532 mtspr SPRN_CTRLT,(REG); \
533END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
534#endif
535
522/* 536/*
523 * Number of entries in the SLB. If this ever changes we should handle 537 * Number of entries in the SLB. If this ever changes we should handle
524 * it with a use a cpu feature fixup. 538 * it with a use a cpu feature fixup.
diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
index 605d91e011ec..4a94acf6bfed 100644
--- a/include/asm-ppc64/unistd.h
+++ b/include/asm-ppc64/unistd.h
@@ -268,7 +268,7 @@
268#define __NR_rtas 255 268#define __NR_rtas 255
269/* Number 256 is reserved for sys_debug_setcontext */ 269/* Number 256 is reserved for sys_debug_setcontext */
270/* Number 257 is reserved for vserver */ 270/* Number 257 is reserved for vserver */
271/* Number 258 is reserved for new sys_remap_file_pages */ 271/* 258 currently unused */
272#define __NR_mbind 259 272#define __NR_mbind 259
273#define __NR_get_mempolicy 260 273#define __NR_get_mempolicy 260
274#define __NR_set_mempolicy 261 274#define __NR_set_mempolicy 261
@@ -283,8 +283,10 @@
283#define __NR_request_key 270 283#define __NR_request_key 270
284#define __NR_keyctl 271 284#define __NR_keyctl 271
285#define __NR_waitid 272 285#define __NR_waitid 272
286#define __NR_ioprio_set 273
287#define __NR_ioprio_get 274
286 288
287#define __NR_syscalls 273 289#define __NR_syscalls 275
288#ifdef __KERNEL__ 290#ifdef __KERNEL__
289#define NR_syscalls __NR_syscalls 291#define NR_syscalls __NR_syscalls
290#endif 292#endif
diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h
index 89bff310b7a9..7529c9c853dd 100644
--- a/include/asm-um/mmu_context.h
+++ b/include/asm-um/mmu_context.h
@@ -7,7 +7,9 @@
7#define __UM_MMU_CONTEXT_H 7#define __UM_MMU_CONTEXT_H
8 8
9#include "linux/sched.h" 9#include "linux/sched.h"
10#include "linux/config.h"
10#include "choose-mode.h" 11#include "choose-mode.h"
12#include "um_mmu.h"
11 13
12#define get_mmu_context(task) do ; while(0) 14#define get_mmu_context(task) do ; while(0)
13#define activate_context(tsk) do ; while(0) 15#define activate_context(tsk) do ; while(0)
@@ -18,8 +20,6 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
18{ 20{
19} 21}
20 22
21extern void switch_mm_skas(int mm_fd);
22
23static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 23static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
24 struct task_struct *tsk) 24 struct task_struct *tsk)
25{ 25{
@@ -30,7 +30,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
30 cpu_set(cpu, next->cpu_vm_mask); 30 cpu_set(cpu, next->cpu_vm_mask);
31 if(next != &init_mm) 31 if(next != &init_mm)
32 CHOOSE_MODE((void) 0, 32 CHOOSE_MODE((void) 0,
33 switch_mm_skas(next->context.skas.mm_fd)); 33 switch_mm_skas(&next->context.skas.id));
34 } 34 }
35} 35}
36 36
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index f2f073642d62..6c813eb521f3 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -15,6 +15,13 @@ extern void pda_init(int);
15extern void early_idt_handler(void); 15extern void early_idt_handler(void);
16 16
17extern void mcheck_init(struct cpuinfo_x86 *c); 17extern void mcheck_init(struct cpuinfo_x86 *c);
18#ifdef CONFIG_MTRR
19extern void mtrr_ap_init(void);
20extern void mtrr_bp_init(void);
21#else
22#define mtrr_ap_init() do {} while (0)
23#define mtrr_bp_init() do {} while (0)
24#endif
18extern void init_memory_mapping(unsigned long start, unsigned long end); 25extern void init_memory_mapping(unsigned long start, unsigned long end);
19 26
20extern void system_call(void); 27extern void system_call(void);
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h
index 64c64dd83ba4..6b39d6609d9c 100644
--- a/include/asm-xtensa/unistd.h
+++ b/include/asm-xtensa/unistd.h
@@ -13,42 +13,31 @@
13 13
14#include <linux/linkage.h> 14#include <linux/linkage.h>
15 15
16//#define __NR_setup 0 /* used only by init, to get system going */
17#define __NR_spill 0 16#define __NR_spill 0
18#define __NR_exit 1 17#define __NR_exit 1
19#define __NR_fork 2
20#define __NR_read 3 18#define __NR_read 3
21#define __NR_write 4 19#define __NR_write 4
22#define __NR_open 5 20#define __NR_open 5
23#define __NR_close 6 21#define __NR_close 6
24#define __NR_waitpid 7
25#define __NR_creat 8 22#define __NR_creat 8
26#define __NR_link 9 23#define __NR_link 9
27#define __NR_unlink 10 24#define __NR_unlink 10
28#define __NR_execve 11 25#define __NR_execve 11
29#define __NR_chdir 12 26#define __NR_chdir 12
30#define __NR_time 13
31#define __NR_mknod 14 27#define __NR_mknod 14
32#define __NR_chmod 15 28#define __NR_chmod 15
33#define __NR_lchown 16 29#define __NR_lchown 16
34#define __NR_break 17 30#define __NR_break 17
35#define __NR_oldstat 18
36#define __NR_lseek 19 31#define __NR_lseek 19
37#define __NR_getpid 20 32#define __NR_getpid 20
38#define __NR_mount 21 33#define __NR_mount 21
39#define __NR_oldumount 22
40#define __NR_setuid 23 34#define __NR_setuid 23
41#define __NR_getuid 24 35#define __NR_getuid 24
42#define __NR_stime 25
43#define __NR_ptrace 26 36#define __NR_ptrace 26
44#define __NR_alarm 27
45#define __NR_oldfstat 28
46#define __NR_pause 29
47#define __NR_utime 30 37#define __NR_utime 30
48#define __NR_stty 31 38#define __NR_stty 31
49#define __NR_gtty 32 39#define __NR_gtty 32
50#define __NR_access 33 40#define __NR_access 33
51#define __NR_nice 34
52#define __NR_ftime 35 41#define __NR_ftime 35
53#define __NR_sync 36 42#define __NR_sync 36
54#define __NR_kill 37 43#define __NR_kill 37
@@ -66,24 +55,18 @@
66#define __NR_geteuid 49 55#define __NR_geteuid 49
67#define __NR_getegid 50 56#define __NR_getegid 50
68#define __NR_acct 51 57#define __NR_acct 51
69#define __NR_umount 52
70#define __NR_lock 53 58#define __NR_lock 53
71#define __NR_ioctl 54 59#define __NR_ioctl 54
72#define __NR_fcntl 55 60#define __NR_fcntl 55
73#define __NR_mpx 56
74#define __NR_setpgid 57 61#define __NR_setpgid 57
75#define __NR_ulimit 58 62#define __NR_ulimit 58
76#define __NR_oldolduname 59
77#define __NR_umask 60 63#define __NR_umask 60
78#define __NR_chroot 61 64#define __NR_chroot 61
79#define __NR_ustat 62 65#define __NR_ustat 62
80#define __NR_dup2 63 66#define __NR_dup2 63
81#define __NR_getppid 64 67#define __NR_getppid 64
82#define __NR_getpgrp 65
83#define __NR_setsid 66 68#define __NR_setsid 66
84#define __NR_sigaction 67 69#define __NR_sigaction 67
85#define __NR_sgetmask 68
86#define __NR_ssetmask 69
87#define __NR_setreuid 70 70#define __NR_setreuid 70
88#define __NR_setregid 71 71#define __NR_setregid 71
89#define __NR_sigsuspend 72 72#define __NR_sigsuspend 72
@@ -98,13 +81,10 @@
98#define __NR_setgroups 81 81#define __NR_setgroups 81
99#define __NR_select 82 82#define __NR_select 82
100#define __NR_symlink 83 83#define __NR_symlink 83
101#define __NR_oldlstat 84
102#define __NR_readlink 85 84#define __NR_readlink 85
103#define __NR_uselib 86 85#define __NR_uselib 86
104#define __NR_swapon 87 86#define __NR_swapon 87
105#define __NR_reboot 88 87#define __NR_reboot 88
106#define __NR_readdir 89
107#define __NR_mmap 90
108#define __NR_munmap 91 88#define __NR_munmap 91
109#define __NR_truncate 92 89#define __NR_truncate 92
110#define __NR_ftruncate 93 90#define __NR_ftruncate 93
@@ -116,22 +96,18 @@
116#define __NR_statfs 99 96#define __NR_statfs 99
117#define __NR_fstatfs 100 97#define __NR_fstatfs 100
118#define __NR_ioperm 101 98#define __NR_ioperm 101
119#define __NR_socketcall 102
120#define __NR_syslog 103 99#define __NR_syslog 103
121#define __NR_setitimer 104 100#define __NR_setitimer 104
122#define __NR_getitimer 105 101#define __NR_getitimer 105
123#define __NR_stat 106 102#define __NR_stat 106
124#define __NR_lstat 107 103#define __NR_lstat 107
125#define __NR_fstat 108 104#define __NR_fstat 108
126#define __NR_olduname 109
127#define __NR_iopl 110 105#define __NR_iopl 110
128#define __NR_vhangup 111 106#define __NR_vhangup 111
129#define __NR_idle 112 107#define __NR_idle 112
130#define __NR_vm86 113
131#define __NR_wait4 114 108#define __NR_wait4 114
132#define __NR_swapoff 115 109#define __NR_swapoff 115
133#define __NR_sysinfo 116 110#define __NR_sysinfo 116
134#define __NR_ipc 117
135#define __NR_fsync 118 111#define __NR_fsync 118
136#define __NR_sigreturn 119 112#define __NR_sigreturn 119
137#define __NR_clone 120 113#define __NR_clone 120
@@ -140,18 +116,15 @@
140#define __NR_modify_ldt 123 116#define __NR_modify_ldt 123
141#define __NR_adjtimex 124 117#define __NR_adjtimex 124
142#define __NR_mprotect 125 118#define __NR_mprotect 125
143#define __NR_sigprocmask 126
144#define __NR_create_module 127 119#define __NR_create_module 127
145#define __NR_init_module 128 120#define __NR_init_module 128
146#define __NR_delete_module 129 121#define __NR_delete_module 129
147#define __NR_get_kernel_syms 130
148#define __NR_quotactl 131 122#define __NR_quotactl 131
149#define __NR_getpgid 132 123#define __NR_getpgid 132
150#define __NR_fchdir 133 124#define __NR_fchdir 133
151#define __NR_bdflush 134 125#define __NR_bdflush 134
152#define __NR_sysfs 135 126#define __NR_sysfs 135
153#define __NR_personality 136 127#define __NR_personality 136
154#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
155#define __NR_setfsuid 138 128#define __NR_setfsuid 138
156#define __NR_setfsgid 139 129#define __NR_setfsgid 139
157#define __NR__llseek 140 130#define __NR__llseek 140
@@ -222,8 +195,6 @@
222#define __NR_capset 205 195#define __NR_capset 205
223#define __NR_sigaltstack 206 196#define __NR_sigaltstack 206
224#define __NR_sendfile 207 197#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 198#define __NR_mmap2 210
228#define __NR_truncate64 211 199#define __NR_truncate64 211
229#define __NR_ftruncate64 212 200#define __NR_ftruncate64 212
@@ -234,7 +205,6 @@
234#define __NR_mincore 217 205#define __NR_mincore 217
235#define __NR_madvise 218 206#define __NR_madvise 218
236#define __NR_getdents64 219 207#define __NR_getdents64 219
237#define __NR_vfork 220
238 208
239/* Keep this last; should always equal the last valid call number. */ 209/* Keep this last; should always equal the last valid call number. */
240#define __NR_Linux_syscalls 220 210#define __NR_Linux_syscalls 220
@@ -448,55 +418,7 @@ __syscall_return(type,__res); \
448 418
449 419
450#ifdef __KERNEL_SYSCALLS__ 420#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) 421static __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 422#endif
501 423
502/* 424/*
@@ -508,30 +430,10 @@ static __inline__ pid_t wait(int * wait_stat)
508#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); 430#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
509 431
510#ifdef __KERNEL__ 432#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 433#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 434#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 435#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 436#define __ARCH_WANT_SYS_RT_SIGACTION
533#endif 437#endif
534 438
535
536
537#endif /* _XTENSA_UNISTD_H */ 439#endif /* _XTENSA_UNISTD_H */
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 802c91e9b3da..90828493791f 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -19,6 +19,9 @@ enum bh_state_bits {
19 BH_Dirty, /* Is dirty */ 19 BH_Dirty, /* Is dirty */
20 BH_Lock, /* Is locked */ 20 BH_Lock, /* Is locked */
21 BH_Req, /* Has been submitted for I/O */ 21 BH_Req, /* Has been submitted for I/O */
22 BH_Uptodate_Lock,/* Used by the first bh in a page, to serialise
23 * IO completion of other buffers in the page
24 */
22 25
23 BH_Mapped, /* Has a disk mapping */ 26 BH_Mapped, /* Has a disk mapping */
24 BH_New, /* Disk mapping was newly created by get_block */ 27 BH_New, /* Disk mapping was newly created by get_block */
diff --git a/include/linux/cache.h b/include/linux/cache.h
index 4d767b93738a..2b66a36d85f0 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -13,6 +13,12 @@
13#define SMP_CACHE_BYTES L1_CACHE_BYTES 13#define SMP_CACHE_BYTES L1_CACHE_BYTES
14#endif 14#endif
15 15
16#ifdef CONFIG_X86
17#define __read_mostly __attribute__((__section__(".data.read_mostly")))
18#else
19#define __read_mostly
20#endif
21
16#ifndef ____cacheline_aligned 22#ifndef ____cacheline_aligned
17#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES))) 23#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
18#endif 24#endif
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 927daa86c9b3..ff7f80f48df1 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -201,7 +201,7 @@ struct cpufreq_driver {
201 201
202 /* optional */ 202 /* optional */
203 int (*exit) (struct cpufreq_policy *policy); 203 int (*exit) (struct cpufreq_policy *policy);
204 int (*suspend) (struct cpufreq_policy *policy, u32 state); 204 int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg);
205 int (*resume) (struct cpufreq_policy *policy); 205 int (*resume) (struct cpufreq_policy *policy);
206 struct freq_attr **attr; 206 struct freq_attr **attr;
207}; 207};
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 047bde30836a..302ec20838ca 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1435,6 +1435,7 @@ extern struct inode * igrab(struct inode *);
1435extern ino_t iunique(struct super_block *, ino_t); 1435extern ino_t iunique(struct super_block *, ino_t);
1436extern int inode_needs_sync(struct inode *inode); 1436extern int inode_needs_sync(struct inode *inode);
1437extern void generic_delete_inode(struct inode *inode); 1437extern void generic_delete_inode(struct inode *inode);
1438extern void generic_drop_inode(struct inode *inode);
1438 1439
1439extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval, 1440extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
1440 int (*test)(struct inode *, void *), void *data); 1441 int (*test)(struct inode *, void *), void *data);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 8d6bf608b199..7c7400137e97 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -12,8 +12,8 @@ struct vm_area_struct;
12 * GFP bitmasks.. 12 * GFP bitmasks..
13 */ 13 */
14/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */ 14/* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */
15#define __GFP_DMA 0x01 15#define __GFP_DMA 0x01u
16#define __GFP_HIGHMEM 0x02 16#define __GFP_HIGHMEM 0x02u
17 17
18/* 18/*
19 * Action modifiers - doesn't change the zoning 19 * Action modifiers - doesn't change the zoning
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
index 8a453a0b5e4b..88d5961f7a3f 100644
--- a/include/linux/ioprio.h
+++ b/include/linux/ioprio.h
@@ -34,9 +34,6 @@ enum {
34 */ 34 */
35#define IOPRIO_BE_NR (8) 35#define IOPRIO_BE_NR (8)
36 36
37asmlinkage int sys_ioprio_set(int, int, int);
38asmlinkage int sys_ioprio_get(int, int);
39
40enum { 37enum {
41 IOPRIO_WHO_PROCESS = 1, 38 IOPRIO_WHO_PROCESS = 1,
42 IOPRIO_WHO_PGRP, 39 IOPRIO_WHO_PGRP,
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 8b8d3b9beefd..74b4727a4e30 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -34,7 +34,7 @@ struct vfsmount
34 int mnt_expiry_mark; /* true if marked for expiry */ 34 int mnt_expiry_mark; /* true if marked for expiry */
35 char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ 35 char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
36 struct list_head mnt_list; 36 struct list_head mnt_list;
37 struct list_head mnt_fslink; /* link in fs-specific expiry list */ 37 struct list_head mnt_expire; /* link in fs-specific expiry list */
38 struct namespace *mnt_namespace; /* containing namespace */ 38 struct namespace *mnt_namespace; /* containing namespace */
39}; 39};
40 40
@@ -47,7 +47,7 @@ static inline struct vfsmount *mntget(struct vfsmount *mnt)
47 47
48extern void __mntput(struct vfsmount *mnt); 48extern void __mntput(struct vfsmount *mnt);
49 49
50static inline void _mntput(struct vfsmount *mnt) 50static inline void mntput_no_expire(struct vfsmount *mnt)
51{ 51{
52 if (mnt) { 52 if (mnt) {
53 if (atomic_dec_and_test(&mnt->mnt_count)) 53 if (atomic_dec_and_test(&mnt->mnt_count))
@@ -59,7 +59,7 @@ static inline void mntput(struct vfsmount *mnt)
59{ 59{
60 if (mnt) { 60 if (mnt) {
61 mnt->mnt_expiry_mark = 0; 61 mnt->mnt_expiry_mark = 0;
62 _mntput(mnt); 62 mntput_no_expire(mnt);
63 } 63 }
64} 64}
65 65
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 697991b69f9b..0e5a86f13b2f 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -17,7 +17,8 @@ extern void __put_namespace(struct namespace *namespace);
17 17
18static inline void put_namespace(struct namespace *namespace) 18static inline void put_namespace(struct namespace *namespace)
19{ 19{
20 if (atomic_dec_and_test(&namespace->count)) 20 if (atomic_dec_and_lock(&namespace->count, &vfsmount_lock))
21 /* releases vfsmount_lock */
21 __put_namespace(namespace); 22 __put_namespace(namespace);
22} 23}
23 24
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 5791dfd30dd0..6d5a24f3fc6d 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -124,6 +124,7 @@ int nfsd_statfs(struct svc_rqst *, struct svc_fh *,
124 124
125int nfsd_notify_change(struct inode *, struct iattr *); 125int nfsd_notify_change(struct inode *, struct iattr *);
126int nfsd_permission(struct svc_export *, struct dentry *, int); 126int nfsd_permission(struct svc_export *, struct dentry *, int);
127void nfsd_sync_dir(struct dentry *dp);
127 128
128#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 129#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
129#ifdef CONFIG_NFSD_V2_ACL 130#ifdef CONFIG_NFSD_V2_ACL
@@ -230,6 +231,7 @@ void nfsd_lockd_shutdown(void);
230#define nfserr_reclaim_bad __constant_htonl(NFSERR_RECLAIM_BAD) 231#define nfserr_reclaim_bad __constant_htonl(NFSERR_RECLAIM_BAD)
231#define nfserr_badname __constant_htonl(NFSERR_BADNAME) 232#define nfserr_badname __constant_htonl(NFSERR_BADNAME)
232#define nfserr_cb_path_down __constant_htonl(NFSERR_CB_PATH_DOWN) 233#define nfserr_cb_path_down __constant_htonl(NFSERR_CB_PATH_DOWN)
234#define nfserr_locked __constant_htonl(NFSERR_LOCKED)
233 235
234/* error codes for internal use */ 236/* error codes for internal use */
235/* if a request fails due to kmalloc failure, it gets dropped. 237/* if a request fails due to kmalloc failure, it gets dropped.
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index a84a3fa99be1..8bf23cf8b603 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -203,7 +203,9 @@ struct nfs4_stateowner {
203 int so_is_open_owner; /* 1=openowner,0=lockowner */ 203 int so_is_open_owner; /* 1=openowner,0=lockowner */
204 u32 so_id; 204 u32 so_id;
205 struct nfs4_client * so_client; 205 struct nfs4_client * so_client;
206 u32 so_seqid; 206 /* after increment in ENCODE_SEQID_OP_TAIL, represents the next
207 * sequence id expected from the client: */
208 u32 so_seqid;
207 struct xdr_netobj so_owner; /* open owner name */ 209 struct xdr_netobj so_owner; /* open owner name */
208 int so_confirmed; /* successful OPEN_CONFIRM? */ 210 int so_confirmed; /* successful OPEN_CONFIRM? */
209 struct nfs4_replay so_replay; 211 struct nfs4_replay so_replay;
@@ -235,6 +237,10 @@ struct nfs4_file {
235* st_perlockowner: (open stateid) list of lock nfs4_stateowners 237* st_perlockowner: (open stateid) list of lock nfs4_stateowners
236* st_access_bmap: used only for open stateid 238* st_access_bmap: used only for open stateid
237* st_deny_bmap: used only for open stateid 239* st_deny_bmap: used only for open stateid
240* st_openstp: open stateid lock stateid was derived from
241*
242* XXX: open stateids and lock stateids have diverged sufficiently that
243* we should consider defining separate structs for the two cases.
238*/ 244*/
239 245
240struct nfs4_stateid { 246struct nfs4_stateid {
@@ -248,6 +254,7 @@ struct nfs4_stateid {
248 struct file * st_vfs_file; 254 struct file * st_vfs_file;
249 unsigned long st_access_bmap; 255 unsigned long st_access_bmap;
250 unsigned long st_deny_bmap; 256 unsigned long st_deny_bmap;
257 struct nfs4_stateid * st_openstp;
251}; 258};
252 259
253/* flags for preprocess_seqid_op() */ 260/* flags for preprocess_seqid_op() */
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 76cf7e60216c..4c8e552471b0 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -65,7 +65,7 @@ extern void *kmem_cache_alloc(kmem_cache_t *, unsigned int __nocast);
65extern void kmem_cache_free(kmem_cache_t *, void *); 65extern void kmem_cache_free(kmem_cache_t *, void *);
66extern unsigned int kmem_cache_size(kmem_cache_t *); 66extern unsigned int kmem_cache_size(kmem_cache_t *);
67extern const char *kmem_cache_name(kmem_cache_t *); 67extern const char *kmem_cache_name(kmem_cache_t *);
68extern kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags); 68extern kmem_cache_t *kmem_find_general_cachep(size_t size, unsigned int __nocast gfpflags);
69 69
70/* Size description struct for general caches. */ 70/* Size description struct for general caches. */
71struct cache_sizes { 71struct cache_sizes {
@@ -105,7 +105,7 @@ extern unsigned int ksize(const void *);
105 105
106#ifdef CONFIG_NUMA 106#ifdef CONFIG_NUMA
107extern void *kmem_cache_alloc_node(kmem_cache_t *, int flags, int node); 107extern void *kmem_cache_alloc_node(kmem_cache_t *, int flags, int node);
108extern void *kmalloc_node(size_t size, int flags, int node); 108extern void *kmalloc_node(size_t size, unsigned int __nocast flags, int node);
109#else 109#else
110static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node) 110static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node)
111{ 111{
diff --git a/include/linux/string.h b/include/linux/string.h
index 93994c613095..dab2652acbd8 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -88,7 +88,7 @@ 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); 91extern char *kstrdup(const char *s, unsigned int __nocast gfp);
92 92
93#ifdef __cplusplus 93#ifdef __cplusplus
94} 94}
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 2343f999e6e1..c75954f2d868 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -148,7 +148,7 @@ struct swap_list_t {
148#define vm_swap_full() (nr_swap_pages*2 < total_swap_pages) 148#define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
149 149
150/* linux/mm/oom_kill.c */ 150/* linux/mm/oom_kill.c */
151extern void out_of_memory(unsigned int __nocast gfp_mask); 151extern void out_of_memory(unsigned int __nocast gfp_mask, int order);
152 152
153/* linux/mm/memory.c */ 153/* linux/mm/memory.c */
154extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct *); 154extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct *);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 52830b6d94e5..425f58c8ea4a 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -506,4 +506,7 @@ asmlinkage long sys_request_key(const char __user *_type,
506asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3, 506asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
507 unsigned long arg4, unsigned long arg5); 507 unsigned long arg4, unsigned long arg5);
508 508
509asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
510asmlinkage long sys_ioprio_get(int which, int who);
511
509#endif 512#endif
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index b42ddc0c1143..2cab39f49eb2 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -68,21 +68,9 @@ typedef struct adjust_t {
68#define RES_ALLOCATED 0x20 68#define RES_ALLOCATED 0x20
69#define RES_REMOVED 0x40 69#define RES_REMOVED 0x40
70 70
71typedef struct servinfo_t {
72 char Signature[2];
73 u_int Count;
74 u_int Revision;
75 u_int CSLevel;
76 char *VendorString;
77} servinfo_t;
78
79typedef struct event_callback_args_t { 71typedef struct event_callback_args_t {
80 client_handle_t client_handle; 72 struct pcmcia_device *client_handle;
81 void *info; 73 void *client_data;
82 void *mtdrequest;
83 void *buffer;
84 void *misc;
85 void *client_data;
86} event_callback_args_t; 74} event_callback_args_t;
87 75
88/* for GetConfigurationInfo */ 76/* for GetConfigurationInfo */
@@ -393,25 +381,25 @@ enum service {
393 381
394struct pcmcia_socket; 382struct pcmcia_socket;
395 383
396int pcmcia_access_configuration_register(client_handle_t handle, conf_reg_t *reg); 384int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg);
397int pcmcia_deregister_client(client_handle_t handle); 385int pcmcia_deregister_client(struct pcmcia_device *p_dev);
398int pcmcia_get_configuration_info(client_handle_t handle, config_info_t *config); 386int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);
399int pcmcia_get_first_window(window_handle_t *win, win_req_t *req); 387int pcmcia_get_first_window(window_handle_t *win, win_req_t *req);
400int pcmcia_get_next_window(window_handle_t *win, win_req_t *req); 388int pcmcia_get_next_window(window_handle_t *win, win_req_t *req);
401int pcmcia_get_status(client_handle_t handle, cs_status_t *status); 389int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status);
402int pcmcia_get_mem_page(window_handle_t win, memreq_t *req); 390int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
403int pcmcia_map_mem_page(window_handle_t win, memreq_t *req); 391int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
404int pcmcia_modify_configuration(client_handle_t handle, modconf_t *mod); 392int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
405int pcmcia_register_client(client_handle_t *handle, client_reg_t *req); 393int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
406int pcmcia_release_configuration(client_handle_t handle); 394int pcmcia_release_configuration(struct pcmcia_device *p_dev);
407int pcmcia_release_io(client_handle_t handle, io_req_t *req); 395int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req);
408int pcmcia_release_irq(client_handle_t handle, irq_req_t *req); 396int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req);
409int pcmcia_release_window(window_handle_t win); 397int pcmcia_release_window(window_handle_t win);
410int pcmcia_request_configuration(client_handle_t handle, config_req_t *req); 398int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req);
411int pcmcia_request_io(client_handle_t handle, io_req_t *req); 399int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
412int pcmcia_request_irq(client_handle_t handle, irq_req_t *req); 400int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
413int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh); 401int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh);
414int pcmcia_reset_card(client_handle_t handle, client_req_t *req); 402int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req);
415int pcmcia_suspend_card(struct pcmcia_socket *skt); 403int pcmcia_suspend_card(struct pcmcia_socket *skt);
416int pcmcia_resume_card(struct pcmcia_socket *skt); 404int pcmcia_resume_card(struct pcmcia_socket *skt);
417int pcmcia_eject_card(struct pcmcia_socket *skt); 405int pcmcia_eject_card(struct pcmcia_socket *skt);
diff --git a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h
index 7881d40aac8d..c1d1629fcd27 100644
--- a/include/pcmcia/cs_types.h
+++ b/include/pcmcia/cs_types.h
@@ -34,8 +34,8 @@ typedef u_int event_t;
34typedef u_char cisdata_t; 34typedef u_char cisdata_t;
35typedef u_short page_t; 35typedef u_short page_t;
36 36
37struct client_t; 37struct pcmcia_device;
38typedef struct client_t *client_handle_t; 38typedef struct pcmcia_device *client_handle_t;
39 39
40struct window_t; 40struct window_t;
41typedef struct window_t *window_handle_t; 41typedef struct window_t *window_handle_t;
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index 2b52553f2d94..0190e766e1a7 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -49,7 +49,6 @@ typedef struct mtd_info_t {
49} mtd_info_t; 49} mtd_info_t;
50 50
51typedef union ds_ioctl_arg_t { 51typedef union ds_ioctl_arg_t {
52 servinfo_t servinfo;
53 adjust_t adjust; 52 adjust_t adjust;
54 config_info_t config; 53 config_info_t config;
55 tuple_t tuple; 54 tuple_t tuple;
@@ -65,7 +64,6 @@ typedef union ds_ioctl_arg_t {
65 cisdump_t cisdump; 64 cisdump_t cisdump;
66} ds_ioctl_arg_t; 65} ds_ioctl_arg_t;
67 66
68#define DS_GET_CARD_SERVICES_INFO _IOR ('d', 1, servinfo_t)
69#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t) 67#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t)
70#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t) 68#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t)
71#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t) 69#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t)
@@ -133,6 +131,8 @@ struct pcmcia_socket;
133 131
134struct pcmcia_driver { 132struct pcmcia_driver {
135 dev_link_t *(*attach)(void); 133 dev_link_t *(*attach)(void);
134 int (*event) (event_t event, int priority,
135 event_callback_args_t *);
136 void (*detach)(dev_link_t *); 136 void (*detach)(dev_link_t *);
137 struct module *owner; 137 struct module *owner;
138 struct pcmcia_device_id *id_table; 138 struct pcmcia_device_id *id_table;
@@ -159,16 +159,8 @@ struct pcmcia_device {
159 /* deprecated, a cleaned up version will be moved into this 159 /* deprecated, a cleaned up version will be moved into this
160 struct soon */ 160 struct soon */
161 dev_link_t *instance; 161 dev_link_t *instance;
162 struct client_t { 162 event_callback_args_t event_callback_args;
163 u_short client_magic; 163 u_int state;
164 struct pcmcia_socket *Socket;
165 u_char Function;
166 u_int state;
167 event_t EventMask;
168 int (*event_handler) (event_t event, int priority,
169 event_callback_args_t *);
170 event_callback_args_t event_callback_args;
171 } client;
172 164
173 /* information about this device */ 165 /* information about this device */
174 u8 has_manf_id:1; 166 u8 has_manf_id:1;
@@ -193,8 +185,8 @@ struct pcmcia_device {
193#define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev) 185#define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
194#define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv) 186#define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
195 187
196#define handle_to_pdev(handle) container_of(handle, struct pcmcia_device, client); 188#define handle_to_pdev(handle) (handle)
197#define handle_to_dev(handle) ((container_of(handle, struct pcmcia_device, client))->dev) 189#define handle_to_dev(handle) (handle->dev)
198 190
199/* error reporting */ 191/* error reporting */
200void cs_error(client_handle_t handle, int func, int ret); 192void cs_error(client_handle_t handle, int func, int ret);
diff --git a/include/pcmcia/version.h b/include/pcmcia/version.h
index eb88263fc8d5..5ad9c5e198b6 100644
--- a/include/pcmcia/version.h
+++ b/include/pcmcia/version.h
@@ -1,4 +1,3 @@
1/* version.h 1.94 2000/10/03 17:55:48 (David Hinds) */ 1/* version.h 1.94 2000/10/03 17:55:48 (David Hinds) */
2 2
3#define CS_RELEASE "3.1.22" 3/* This file will be removed, please don't include it */
4#define CS_RELEASE_CODE 0x3116
diff --git a/ipc/compat.c b/ipc/compat.c
index 70e4e4e10fd1..3881d564c668 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -572,6 +572,7 @@ static inline int put_compat_shminfo(struct shminfo64 *smi,
572 err |= __put_user(smi->shmmni, &up->shmmni); 572 err |= __put_user(smi->shmmni, &up->shmmni);
573 err |= __put_user(smi->shmseg, &up->shmseg); 573 err |= __put_user(smi->shmseg, &up->shmseg);
574 err |= __put_user(smi->shmall, &up->shmall); 574 err |= __put_user(smi->shmall, &up->shmall);
575 return err;
575} 576}
576 577
577static inline int put_compat_shm_info(struct shm_info __user *ip, 578static inline int put_compat_shm_info(struct shm_info __user *ip,
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index fb8de63c2919..c51a4d96d4eb 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -234,6 +234,16 @@ static int software_resume(void)
234{ 234{
235 int error; 235 int error;
236 236
237 if (!swsusp_resume_device) {
238 if (!strlen(resume_file))
239 return -ENOENT;
240 swsusp_resume_device = name_to_dev_t(resume_file);
241 pr_debug("swsusp: Resume From Partition %s\n", resume_file);
242 } else {
243 pr_debug("swsusp: Resume From Partition %d:%d\n",
244 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
245 }
246
237 if (noresume) { 247 if (noresume) {
238 /** 248 /**
239 * FIXME: If noresume is specified, we need to find the partition 249 * FIXME: If noresume is specified, we need to find the partition
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 0a086640bcfc..3bd0d261818f 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -59,6 +59,7 @@ int freeze_processes(void)
59 int todo; 59 int todo;
60 unsigned long start_time; 60 unsigned long start_time;
61 struct task_struct *g, *p; 61 struct task_struct *g, *p;
62 unsigned long flags;
62 63
63 printk( "Stopping tasks: " ); 64 printk( "Stopping tasks: " );
64 start_time = jiffies; 65 start_time = jiffies;
@@ -66,12 +67,9 @@ int freeze_processes(void)
66 todo = 0; 67 todo = 0;
67 read_lock(&tasklist_lock); 68 read_lock(&tasklist_lock);
68 do_each_thread(g, p) { 69 do_each_thread(g, p) {
69 unsigned long flags;
70 if (!freezeable(p)) 70 if (!freezeable(p))
71 continue; 71 continue;
72 if ((frozen(p)) || 72 if (frozen(p))
73 (p->state == TASK_TRACED) ||
74 (p->state == TASK_STOPPED))
75 continue; 73 continue;
76 74
77 freeze(p); 75 freeze(p);
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index c285fc5a2320..7d7801cd01f0 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -869,13 +869,6 @@ extern asmlinkage int swsusp_arch_resume(void);
869 869
870asmlinkage int swsusp_save(void) 870asmlinkage int swsusp_save(void)
871{ 871{
872 int error = 0;
873
874 if ((error = swsusp_swap_check())) {
875 printk(KERN_ERR "swsusp: FATAL: cannot find swap device, try "
876 "swapon -a!\n");
877 return error;
878 }
879 return suspend_prepare_image(); 872 return suspend_prepare_image();
880} 873}
881 874
@@ -892,14 +885,20 @@ int swsusp_suspend(void)
892 * at resume time, and evil weirdness ensues. 885 * at resume time, and evil weirdness ensues.
893 */ 886 */
894 if ((error = device_power_down(PMSG_FREEZE))) { 887 if ((error = device_power_down(PMSG_FREEZE))) {
895 printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
896 local_irq_enable(); 888 local_irq_enable();
897 swsusp_free();
898 return error; 889 return error;
899 } 890 }
891
892 if ((error = swsusp_swap_check())) {
893 printk(KERN_ERR "swsusp: FATAL: cannot find swap device, try "
894 "swapon -a!\n");
895 local_irq_enable();
896 return error;
897 }
898
900 save_processor_state(); 899 save_processor_state();
901 if ((error = swsusp_arch_suspend())) 900 if ((error = swsusp_arch_suspend()))
902 swsusp_free(); 901 printk("Error %d suspending\n", error);
903 /* Restore control flow magically appears here */ 902 /* Restore control flow magically appears here */
904 restore_processor_state(); 903 restore_processor_state();
905 BUG_ON (nr_copy_pages_check != nr_copy_pages); 904 BUG_ON (nr_copy_pages_check != nr_copy_pages);
@@ -1166,9 +1165,9 @@ static int bio_write_page(pgoff_t page_off, void * page)
1166static const char * sanity_check(void) 1165static const char * sanity_check(void)
1167{ 1166{
1168 dump_info(); 1167 dump_info();
1169 if(swsusp_info.version_code != LINUX_VERSION_CODE) 1168 if (swsusp_info.version_code != LINUX_VERSION_CODE)
1170 return "kernel version"; 1169 return "kernel version";
1171 if(swsusp_info.num_physpages != num_physpages) 1170 if (swsusp_info.num_physpages != num_physpages)
1172 return "memory size"; 1171 return "memory size";
1173 if (strcmp(swsusp_info.uts.sysname,system_utsname.sysname)) 1172 if (strcmp(swsusp_info.uts.sysname,system_utsname.sysname))
1174 return "system type"; 1173 return "system type";
@@ -1356,16 +1355,6 @@ int swsusp_check(void)
1356{ 1355{
1357 int error; 1356 int error;
1358 1357
1359 if (!swsusp_resume_device) {
1360 if (!strlen(resume_file))
1361 return -ENOENT;
1362 swsusp_resume_device = name_to_dev_t(resume_file);
1363 pr_debug("swsusp: Resume From Partition %s\n", resume_file);
1364 } else {
1365 pr_debug("swsusp: Resume From Partition %d:%d\n",
1366 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
1367 }
1368
1369 resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); 1358 resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
1370 if (!IS_ERR(resume_bdev)) { 1359 if (!IS_ERR(resume_bdev)) {
1371 set_blocksize(resume_bdev, PAGE_SIZE); 1360 set_blocksize(resume_bdev, PAGE_SIZE);
diff --git a/kernel/profile.c b/kernel/profile.c
index ad8cbb75ffa2..f89248e6d704 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -35,11 +35,11 @@ struct profile_hit {
35#define NR_PROFILE_GRP (NR_PROFILE_HIT/PROFILE_GRPSZ) 35#define NR_PROFILE_GRP (NR_PROFILE_HIT/PROFILE_GRPSZ)
36 36
37/* Oprofile timer tick hook */ 37/* Oprofile timer tick hook */
38int (*timer_hook)(struct pt_regs *); 38int (*timer_hook)(struct pt_regs *) __read_mostly;
39 39
40static atomic_t *prof_buffer; 40static atomic_t *prof_buffer;
41static unsigned long prof_len, prof_shift; 41static unsigned long prof_len, prof_shift;
42static int prof_on; 42static int prof_on __read_mostly;
43static cpumask_t prof_cpu_mask = CPU_MASK_ALL; 43static cpumask_t prof_cpu_mask = CPU_MASK_ALL;
44#ifdef CONFIG_SMP 44#ifdef CONFIG_SMP
45static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits); 45static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits);
diff --git a/kernel/sched.c b/kernel/sched.c
index 5f2182d42241..4107db0dc091 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -3877,6 +3877,13 @@ asmlinkage long sys_sched_yield(void)
3877 3877
3878static inline void __cond_resched(void) 3878static inline void __cond_resched(void)
3879{ 3879{
3880 /*
3881 * The BKS might be reacquired before we have dropped
3882 * PREEMPT_ACTIVE, which could trigger a second
3883 * cond_resched() call.
3884 */
3885 if (unlikely(preempt_count()))
3886 return;
3880 do { 3887 do {
3881 add_preempt_count(PREEMPT_ACTIVE); 3888 add_preempt_count(PREEMPT_ACTIVE);
3882 schedule(); 3889 schedule();
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 04d664377f2c..10bed1c8c3c3 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -58,7 +58,7 @@ struct radix_tree_path {
58#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) 58#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
59#define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2) 59#define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2)
60 60
61static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH]; 61static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH] __read_mostly;
62 62
63/* 63/*
64 * Radix tree node cache. 64 * Radix tree node cache.
diff --git a/mm/mempool.c b/mm/mempool.c
index 9a72f7d918fa..65f2957b8d51 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -205,7 +205,7 @@ void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask)
205 void *element; 205 void *element;
206 unsigned long flags; 206 unsigned long flags;
207 wait_queue_t wait; 207 wait_queue_t wait;
208 int gfp_temp; 208 unsigned int gfp_temp;
209 209
210 might_sleep_if(gfp_mask & __GFP_WAIT); 210 might_sleep_if(gfp_mask & __GFP_WAIT);
211 211
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 59666d905f19..1e56076672f5 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -253,14 +253,16 @@ static struct mm_struct *oom_kill_process(struct task_struct *p)
253 * OR try to be smart about which process to kill. Note that we 253 * OR try to be smart about which process to kill. Note that we
254 * don't have to be perfect here, we just have to be good. 254 * don't have to be perfect here, we just have to be good.
255 */ 255 */
256void out_of_memory(unsigned int __nocast gfp_mask) 256void out_of_memory(unsigned int __nocast gfp_mask, int order)
257{ 257{
258 struct mm_struct *mm = NULL; 258 struct mm_struct *mm = NULL;
259 task_t * p; 259 task_t * p;
260 260
261 printk("oom-killer: gfp_mask=0x%x\n", gfp_mask); 261 if (printk_ratelimit()) {
262 /* print memory stats */ 262 printk("oom-killer: gfp_mask=0x%x, order=%d\n",
263 show_mem(); 263 gfp_mask, order);
264 show_mem();
265 }
264 266
265 read_lock(&tasklist_lock); 267 read_lock(&tasklist_lock);
266retry: 268retry:
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3c9f7f881125..1d6ba6a4b594 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -897,12 +897,6 @@ rebalance:
897 cond_resched(); 897 cond_resched();
898 898
899 if (likely(did_some_progress)) { 899 if (likely(did_some_progress)) {
900 /*
901 * Go through the zonelist yet one more time, keep
902 * very high watermark here, this is only to catch
903 * a parallel oom killing, we must fail if we're still
904 * under heavy pressure.
905 */
906 for (i = 0; (z = zones[i]) != NULL; i++) { 900 for (i = 0; (z = zones[i]) != NULL; i++) {
907 if (!zone_watermark_ok(z, order, z->pages_min, 901 if (!zone_watermark_ok(z, order, z->pages_min,
908 classzone_idx, can_try_harder, 902 classzone_idx, can_try_harder,
@@ -936,7 +930,7 @@ rebalance:
936 goto got_pg; 930 goto got_pg;
937 } 931 }
938 932
939 out_of_memory(gfp_mask); 933 out_of_memory(gfp_mask, order);
940 goto restart; 934 goto restart;
941 } 935 }
942 936
diff --git a/mm/slab.c b/mm/slab.c
index e57abd45eede..c9e706db4634 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -584,7 +584,8 @@ static inline struct array_cache *ac_data(kmem_cache_t *cachep)
584 return cachep->array[smp_processor_id()]; 584 return cachep->array[smp_processor_id()];
585} 585}
586 586
587static inline kmem_cache_t *__find_general_cachep(size_t size, int gfpflags) 587static inline kmem_cache_t *__find_general_cachep(size_t size,
588 unsigned int __nocast gfpflags)
588{ 589{
589 struct cache_sizes *csizep = malloc_sizes; 590 struct cache_sizes *csizep = malloc_sizes;
590 591
@@ -608,7 +609,8 @@ static inline kmem_cache_t *__find_general_cachep(size_t size, int gfpflags)
608 return csizep->cs_cachep; 609 return csizep->cs_cachep;
609} 610}
610 611
611kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags) 612kmem_cache_t *kmem_find_general_cachep(size_t size,
613 unsigned int __nocast gfpflags)
612{ 614{
613 return __find_general_cachep(size, gfpflags); 615 return __find_general_cachep(size, gfpflags);
614} 616}
@@ -2100,7 +2102,7 @@ cache_alloc_debugcheck_before(kmem_cache_t *cachep, unsigned int __nocast flags)
2100#if DEBUG 2102#if DEBUG
2101static void * 2103static void *
2102cache_alloc_debugcheck_after(kmem_cache_t *cachep, 2104cache_alloc_debugcheck_after(kmem_cache_t *cachep,
2103 unsigned long flags, void *objp, void *caller) 2105 unsigned int __nocast flags, void *objp, void *caller)
2104{ 2106{
2105 if (!objp) 2107 if (!objp)
2106 return objp; 2108 return objp;
@@ -2442,7 +2444,7 @@ got_slabp:
2442} 2444}
2443EXPORT_SYMBOL(kmem_cache_alloc_node); 2445EXPORT_SYMBOL(kmem_cache_alloc_node);
2444 2446
2445void *kmalloc_node(size_t size, int flags, int node) 2447void *kmalloc_node(size_t size, unsigned int __nocast flags, int node)
2446{ 2448{
2447 kmem_cache_t *cachep; 2449 kmem_cache_t *cachep;
2448 2450
@@ -3094,7 +3096,7 @@ unsigned int ksize(const void *objp)
3094 * @s: the string to duplicate 3096 * @s: the string to duplicate
3095 * @gfp: the GFP mask used in the kmalloc() call when allocating memory 3097 * @gfp: the GFP mask used in the kmalloc() call when allocating memory
3096 */ 3098 */
3097char *kstrdup(const char *s, int gfp) 3099char *kstrdup(const char *s, unsigned int __nocast gfp)
3098{ 3100{
3099 size_t len; 3101 size_t len;
3100 char *buf; 3102 char *buf;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 269f217918a3..3c654e06b084 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -145,8 +145,6 @@ __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
145 if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) { 145 if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) {
146 if (task == xprt->snd_task) 146 if (task == xprt->snd_task)
147 return 1; 147 return 1;
148 if (task == NULL)
149 return 0;
150 goto out_sleep; 148 goto out_sleep;
151 } 149 }
152 if (xprt->nocong || __xprt_get_cong(xprt, task)) { 150 if (xprt->nocong || __xprt_get_cong(xprt, task)) {
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 90a551e4da66..a1f6bac647a1 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -129,7 +129,7 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
129 int loop, ret; 129 int loop, ret;
130 130
131 const unsigned limit = 131 const unsigned limit =
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 135
@@ -150,7 +150,7 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
150 max = limit; 150 max = limit;
151 151
152 ret = -ENOMEM; 152 ret = -ENOMEM;
153 size = sizeof(*klist) + sizeof(struct key) * max; 153 size = sizeof(*klist) + sizeof(struct key *) * max;
154 klist = kmalloc(size, GFP_KERNEL); 154 klist = kmalloc(size, GFP_KERNEL);
155 if (!klist) 155 if (!klist)
156 goto error; 156 goto error;
@@ -163,7 +163,7 @@ static int keyring_duplicate(struct key *keyring, const struct key *source)
163 klist->nkeys = sklist->nkeys; 163 klist->nkeys = sklist->nkeys;
164 memcpy(klist->keys, 164 memcpy(klist->keys,
165 sklist->keys, 165 sklist->keys,
166 sklist->nkeys * sizeof(struct key)); 166 sklist->nkeys * sizeof(struct key *));
167 167
168 for (loop = klist->nkeys - 1; loop >= 0; loop--) 168 for (loop = klist->nkeys - 1; loop >= 0; loop--)
169 atomic_inc(&klist->keys[loop]->usage); 169 atomic_inc(&klist->keys[loop]->usage);
@@ -783,7 +783,7 @@ int __key_link(struct key *keyring, struct key *key)
783 ret = -ENFILE; 783 ret = -ENFILE;
784 if (max > 65535) 784 if (max > 65535)
785 goto error3; 785 goto error3;
786 size = sizeof(*klist) + sizeof(*key) * max; 786 size = sizeof(*klist) + sizeof(struct key *) * max;
787 if (size > PAGE_SIZE) 787 if (size > PAGE_SIZE)
788 goto error3; 788 goto error3;
789 789
@@ -895,7 +895,8 @@ int key_unlink(struct key *keyring, struct key *key)
895 895
896key_is_present: 896key_is_present:
897 /* we need to copy the key list for RCU purposes */ 897 /* we need to copy the key list for RCU purposes */
898 nklist = kmalloc(sizeof(*klist) + sizeof(*key) * klist->maxkeys, 898 nklist = kmalloc(sizeof(*klist) +
899 sizeof(struct key *) * klist->maxkeys,
899 GFP_KERNEL); 900 GFP_KERNEL);
900 if (!nklist) 901 if (!nklist)
901 goto nomem; 902 goto nomem;
@@ -905,12 +906,12 @@ key_is_present:
905 if (loop > 0) 906 if (loop > 0)
906 memcpy(&nklist->keys[0], 907 memcpy(&nklist->keys[0],
907 &klist->keys[0], 908 &klist->keys[0],
908 loop * sizeof(klist->keys[0])); 909 loop * sizeof(struct key *));
909 910
910 if (loop < nklist->nkeys) 911 if (loop < nklist->nkeys)
911 memcpy(&nklist->keys[loop], 912 memcpy(&nklist->keys[loop],
912 &klist->keys[loop + 1], 913 &klist->keys[loop + 1],
913 (nklist->nkeys - loop) * sizeof(klist->keys[0])); 914 (nklist->nkeys - loop) * sizeof(struct key *));
914 915
915 /* adjust the user's quota */ 916 /* adjust the user's quota */
916 key_payload_reserve(keyring, 917 key_payload_reserve(keyring,
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index 9e42a1a67ca4..cb998e8c0fdd 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -4174,7 +4174,7 @@ static int cs_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int
4174 list_for_each(entry, &cs46xx_devs) 4174 list_for_each(entry, &cs46xx_devs)
4175 { 4175 {
4176 card = list_entry(entry, struct cs_card, list); 4176 card = list_entry(entry, struct cs_card, list);
4177 cs46xx_suspend(card, 0); 4177 cs46xx_suspend(card, PMSG_ON);
4178 } 4178 }
4179 4179
4180 } 4180 }
@@ -5749,7 +5749,7 @@ static int cs46xx_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
5749 case PM_SUSPEND: 5749 case PM_SUSPEND:
5750 CS_DBGOUT(CS_PM, 2, printk(KERN_INFO 5750 CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
5751 "cs46xx: PM suspend request\n")); 5751 "cs46xx: PM suspend request\n"));
5752 if(cs46xx_suspend(card, 0)) 5752 if(cs46xx_suspend(card, PMSG_SUSPEND))
5753 { 5753 {
5754 CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO 5754 CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
5755 "cs46xx: PM suspend request refused\n")); 5755 "cs46xx: PM suspend request refused\n"));
@@ -5779,7 +5779,7 @@ static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state)
5779 struct cs_card *s = PCI_GET_DRIVER_DATA(pcidev); 5779 struct cs_card *s = PCI_GET_DRIVER_DATA(pcidev);
5780 CS_DBGOUT(CS_PM | CS_FUNCTION, 2, 5780 CS_DBGOUT(CS_PM | CS_FUNCTION, 2,
5781 printk(KERN_INFO "cs46xx: cs46xx_suspend_tbl request\n")); 5781 printk(KERN_INFO "cs46xx: cs46xx_suspend_tbl request\n"));
5782 cs46xx_suspend(s, 0); 5782 cs46xx_suspend(s, state);
5783 return 0; 5783 return 0;
5784} 5784}
5785 5785
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 2d4f8e28478b..d6918b453f28 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -22,7 +22,6 @@
22#include <sound/core.h> 22#include <sound/core.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <pcmcia/version.h>
26#include <pcmcia/ciscode.h> 25#include <pcmcia/ciscode.h>
27#include <pcmcia/cisreg.h> 26#include <pcmcia/cisreg.h>
28#include "pdaudiocf.h" 27#include "pdaudiocf.h"
@@ -171,14 +170,6 @@ static dev_link_t *snd_pdacf_attach(void)
171 170
172 /* Register with Card Services */ 171 /* Register with Card Services */
173 client_reg.dev_info = &dev_info; 172 client_reg.dev_info = &dev_info;
174 client_reg.EventMask =
175 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
176#ifdef CONFIG_PM
177 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
178 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
179#endif
180 ;
181 client_reg.event_handler = &pdacf_event;
182 client_reg.Version = 0x0210; 173 client_reg.Version = 0x0210;
183 client_reg.event_callback_args.client_data = link; 174 client_reg.event_callback_args.client_data = link;
184 175
@@ -387,12 +378,13 @@ static struct pcmcia_device_id snd_pdacf_ids[] = {
387MODULE_DEVICE_TABLE(pcmcia, snd_pdacf_ids); 378MODULE_DEVICE_TABLE(pcmcia, snd_pdacf_ids);
388 379
389static struct pcmcia_driver pdacf_cs_driver = { 380static struct pcmcia_driver pdacf_cs_driver = {
390 .owner = THIS_MODULE, 381 .owner = THIS_MODULE,
391 .drv = { 382 .drv = {
392 .name = "snd-pdaudiocf", 383 .name = "snd-pdaudiocf",
393 }, 384 },
394 .attach = snd_pdacf_attach, 385 .attach = snd_pdacf_attach,
395 .detach = snd_pdacf_detach, 386 .event = pdacf_event,
387 .detach = snd_pdacf_detach,
396 .id_table = snd_pdacf_ids, 388 .id_table = snd_pdacf_ids,
397}; 389};
398 390
diff --git a/sound/pcmcia/vx/vx_entry.c b/sound/pcmcia/vx/vx_entry.c
index 332bbca3dfc4..df7a39ba9680 100644
--- a/sound/pcmcia/vx/vx_entry.c
+++ b/sound/pcmcia/vx/vx_entry.c
@@ -35,7 +35,6 @@ MODULE_LICENSE("GPL");
35 * prototypes 35 * prototypes
36 */ 36 */
37static void vxpocket_config(dev_link_t *link); 37static void vxpocket_config(dev_link_t *link);
38static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);
39 38
40 39
41static void vxpocket_release(dev_link_t *link) 40static void vxpocket_release(dev_link_t *link)
@@ -169,14 +168,6 @@ dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw)
169 /* Register with Card Services */ 168 /* Register with Card Services */
170 memset(&client_reg, 0, sizeof(client_reg)); 169 memset(&client_reg, 0, sizeof(client_reg));
171 client_reg.dev_info = hw->dev_info; 170 client_reg.dev_info = hw->dev_info;
172 client_reg.EventMask =
173 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
174#ifdef CONFIG_PM
175 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
176 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
177#endif
178 ;
179 client_reg.event_handler = &vxpocket_event;
180 client_reg.Version = 0x0210; 171 client_reg.Version = 0x0210;
181 client_reg.event_callback_args.client_data = link; 172 client_reg.event_callback_args.client_data = link;
182 173
@@ -321,7 +312,7 @@ failed:
321/* 312/*
322 * event callback 313 * event callback
323 */ 314 */
324static int vxpocket_event(event_t event, int priority, event_callback_args_t *args) 315int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
325{ 316{
326 dev_link_t *link = args->client_data; 317 dev_link_t *link = args->client_data;
327 vx_core_t *chip = link->priv; 318 vx_core_t *chip = link->priv;
@@ -380,4 +371,5 @@ static int vxpocket_event(event_t event, int priority, event_callback_args_t *ar
380 */ 371 */
381EXPORT_SYMBOL(snd_vxpocket_ops); 372EXPORT_SYMBOL(snd_vxpocket_ops);
382EXPORT_SYMBOL(snd_vxpocket_attach); 373EXPORT_SYMBOL(snd_vxpocket_attach);
374EXPORT_SYMBOL(vxpocket_event);
383EXPORT_SYMBOL(snd_vxpocket_detach); 375EXPORT_SYMBOL(snd_vxpocket_detach);
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 5f4c13264159..62d6fa128148 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -23,7 +23,6 @@
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <sound/core.h> 25#include <sound/core.h>
26#include <pcmcia/version.h>
27#include "vxpocket.h" 26#include "vxpocket.h"
28#include <sound/initval.h> 27#include <sound/initval.h>
29 28